mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* vm_insnhelper.c (vm_throw): check a class frame.
Fixes Bug #4648. The patch is contributed by Kazuki Tsujimoto. * bootstraptest/test_proc.rb: add tests for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									b9a13f4962
								
							
						
					
					
						commit
						9cf9d5eaf7
					
				
					 3 changed files with 43 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
Sun Jul 10 16:57:08 2011  Koichi Sasada  <ko1@atdot.net>
 | 
			
		||||
 | 
			
		||||
	* vm_insnhelper.c (vm_throw): check a class frame.
 | 
			
		||||
	  Fixes Bug #4648.
 | 
			
		||||
	  The patch is contributed by Kazuki Tsujimoto.
 | 
			
		||||
 | 
			
		||||
	* bootstraptest/test_proc.rb: add tests for above.
 | 
			
		||||
 | 
			
		||||
Sun Jul 10 17:28:01 2011  KOSAKI Motohiro  <kosaki.motohiro@gmail.com>
 | 
			
		||||
 | 
			
		||||
	* thread_pthread.c (mutex_debug): use exit(EXIT_FAILURE) instad of
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -429,3 +429,30 @@ assert_equal 'ok', %q{
 | 
			
		|||
  raise "ok"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
assert_equal 'ok', %q{
 | 
			
		||||
  lambda do
 | 
			
		||||
    class A
 | 
			
		||||
      class B
 | 
			
		||||
        proc{return :ng}.call
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end.call
 | 
			
		||||
  :ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
assert_equal 'ok', %q{
 | 
			
		||||
  $proc = proc{return}
 | 
			
		||||
  begin
 | 
			
		||||
    lambda do
 | 
			
		||||
      class A
 | 
			
		||||
        class B
 | 
			
		||||
          $proc.call
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end.call
 | 
			
		||||
    :ng
 | 
			
		||||
  rescue LocalJumpError
 | 
			
		||||
    :ok
 | 
			
		||||
  end
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1541,6 +1541,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
 | 
			
		|||
		rb_control_frame_t *cfp = GET_CFP();
 | 
			
		||||
		VALUE *dfp = GET_DFP();
 | 
			
		||||
		VALUE *lfp = GET_LFP();
 | 
			
		||||
		int in_class_frame = 0;
 | 
			
		||||
 | 
			
		||||
		/* check orphan and get dfp */
 | 
			
		||||
		while ((VALUE *) cfp < th->stack + th->stack_size) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1548,6 +1549,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
 | 
			
		|||
			lfp = cfp->lfp;
 | 
			
		||||
		    }
 | 
			
		||||
		    if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_CLASS) {
 | 
			
		||||
			in_class_frame = 1;
 | 
			
		||||
			lfp = 0;
 | 
			
		||||
		    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1555,6 +1557,12 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
 | 
			
		|||
			if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
 | 
			
		||||
			    VALUE *tdfp = dfp;
 | 
			
		||||
 | 
			
		||||
			    if (in_class_frame) {
 | 
			
		||||
				/* lambda {class A; ... return ...; end} */
 | 
			
		||||
				dfp = cfp->dfp;
 | 
			
		||||
				goto valid_return;
 | 
			
		||||
			    }
 | 
			
		||||
 | 
			
		||||
			    while (lfp != tdfp) {
 | 
			
		||||
				if (cfp->dfp == tdfp) {
 | 
			
		||||
				    /* in lambda */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue