mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	vm_insnhelper.c: iclass as klass in cfp
* vm_insnhelper.c (vm_call_method): follow iclasses as klass in cfp but not included modules. [ruby-core:47241] [Bug #6891] * vm_insnhelper.c (vm_call_bmethod): pass defined_class to follow proper ancestors. [ruby-core:47241] [Bug #6891] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36736 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									de83cb9b20
								
							
						
					
					
						commit
						ceece4650a
					
				
					 9 changed files with 103 additions and 23 deletions
				
			
		
							
								
								
									
										16
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,19 @@
 | 
			
		|||
Mon Aug 20 20:36:30 2012  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* vm_insnhelper.c (vm_call_method): follow iclasses as klass in cfp
 | 
			
		||||
	  but not included modules.  [ruby-core:47241] [Bug #6891]
 | 
			
		||||
 | 
			
		||||
	* vm_insnhelper.c (vm_call_bmethod): pass defined_class to follow
 | 
			
		||||
	  proper ancestors.  [ruby-core:47241] [Bug #6891]
 | 
			
		||||
 | 
			
		||||
Mon Aug 20 20:36:13 2012  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* vm_insnhelper.c (vm_call_method): follow iclasses as klass in cfp
 | 
			
		||||
	  but not included modules.  [ruby-core:47241] [Bug #6891]
 | 
			
		||||
 | 
			
		||||
	* vm_insnhelper.c (vm_call_bmethod): pass defined_class to follow
 | 
			
		||||
	  proper ancestors.  [ruby-core:47241] [Bug #6891]
 | 
			
		||||
 | 
			
		||||
Mon Aug 20 11:40:27 2012  Kazuhiro NISHIYAMA  <zn@mbf.nifty.com>
 | 
			
		||||
 | 
			
		||||
	* common.mk: fix failed to make with -j2.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								cont.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								cont.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1161,7 +1161,7 @@ rb_fiber_start(void)
 | 
			
		|||
	th->root_svar = Qnil;
 | 
			
		||||
 | 
			
		||||
	fib->status = RUNNING;
 | 
			
		||||
	cont->value = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, 0);
 | 
			
		||||
	cont->value = rb_vm_invoke_proc(th, proc, argc, argv, 0);
 | 
			
		||||
    }
 | 
			
		||||
    TH_POP_TAG();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -558,8 +558,7 @@ proc_call(int argc, VALUE *argv, VALUE procval)
 | 
			
		|||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vret = rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
 | 
			
		||||
			     argc, argv, blockptr);
 | 
			
		||||
    vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, blockptr);
 | 
			
		||||
    RB_GC_GUARD(procval);
 | 
			
		||||
    return vret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -584,7 +583,7 @@ rb_proc_call(VALUE self, VALUE args)
 | 
			
		|||
    VALUE vret;
 | 
			
		||||
    rb_proc_t *proc;
 | 
			
		||||
    GetProcPtr(self, proc);
 | 
			
		||||
    vret = rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
 | 
			
		||||
    vret = rb_vm_invoke_proc(GET_THREAD(), proc,
 | 
			
		||||
			     check_argc(RARRAY_LEN(args)), RARRAY_PTR(args), 0);
 | 
			
		||||
    RB_GC_GUARD(self);
 | 
			
		||||
    RB_GC_GUARD(args);
 | 
			
		||||
| 
						 | 
				
			
			@ -605,8 +604,7 @@ rb_proc_call_with_block(VALUE self, int argc, VALUE *argv, VALUE pass_procval)
 | 
			
		|||
	block = &pass_proc->block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vret = rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
 | 
			
		||||
			     argc, argv, block);
 | 
			
		||||
    vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, block);
 | 
			
		||||
    RB_GC_GUARD(self);
 | 
			
		||||
    RB_GC_GUARD(pass_procval);
 | 
			
		||||
    return vret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1398,4 +1398,58 @@ class TestModule < Test::Unit::TestCase
 | 
			
		|||
    assert_equal([:@@bar, :@@foo], m2.class_variables(true))
 | 
			
		||||
    assert_equal([:@@bar], m2.class_variables(false))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  Bug6891 = '[ruby-core:47241]'
 | 
			
		||||
 | 
			
		||||
  def test_extend_module_with_protected_method
 | 
			
		||||
    list = []
 | 
			
		||||
 | 
			
		||||
    x = Class.new {
 | 
			
		||||
      @list = list
 | 
			
		||||
 | 
			
		||||
      extend Module.new {
 | 
			
		||||
        protected
 | 
			
		||||
 | 
			
		||||
        def inherited(klass)
 | 
			
		||||
          @list << "protected"
 | 
			
		||||
          super(klass)
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      extend Module.new {
 | 
			
		||||
        def inherited(klass)
 | 
			
		||||
          @list << "public"
 | 
			
		||||
          super(klass)
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
 | 
			
		||||
    assert_equal(['public', 'protected'], list)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_extend_module_with_protected_bmethod
 | 
			
		||||
    list = []
 | 
			
		||||
 | 
			
		||||
    x = Class.new {
 | 
			
		||||
      extend Module.new {
 | 
			
		||||
        protected
 | 
			
		||||
 | 
			
		||||
        define_method(:inherited) do |klass|
 | 
			
		||||
          list << "protected"
 | 
			
		||||
          super(klass)
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      extend Module.new {
 | 
			
		||||
        define_method(:inherited) do |klass|
 | 
			
		||||
          list << "public"
 | 
			
		||||
          super(klass)
 | 
			
		||||
        end
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
 | 
			
		||||
    assert_equal(['public', 'protected'], list)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								thread.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								thread.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -455,7 +455,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
 | 
			
		|||
		    th->errinfo = Qnil;
 | 
			
		||||
		    th->root_lep = rb_vm_ep_local_ep(proc->block.ep);
 | 
			
		||||
		    th->root_svar = Qnil;
 | 
			
		||||
		    th->value = rb_vm_invoke_proc(th, proc, proc->block.self,
 | 
			
		||||
		    th->value = rb_vm_invoke_proc(th, proc,
 | 
			
		||||
						  (int)RARRAY_LEN(args), RARRAY_PTR(args), 0);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								vm.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -61,6 +61,10 @@ rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp)
 | 
			
		|||
    return VM_CF_BLOCK_PTR(cfp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
 | 
			
		||||
	       int argc, const VALUE *argv, const rb_block_t *blockptr);
 | 
			
		||||
 | 
			
		||||
#include "vm_insnhelper.h"
 | 
			
		||||
#include "vm_insnhelper.c"
 | 
			
		||||
#include "vm_exec.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -577,7 +581,8 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
 | 
			
		|||
static inline VALUE
 | 
			
		||||
invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
 | 
			
		||||
		    VALUE self, int argc, const VALUE *argv,
 | 
			
		||||
		    const rb_block_t *blockptr, const NODE *cref)
 | 
			
		||||
		    const rb_block_t *blockptr, const NODE *cref,
 | 
			
		||||
		    VALUE defined_class)
 | 
			
		||||
{
 | 
			
		||||
    if (SPECIAL_CONST_P(block->iseq))
 | 
			
		||||
	return Qnil;
 | 
			
		||||
| 
						 | 
				
			
			@ -599,7 +604,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
 | 
			
		|||
				     type == VM_FRAME_MAGIC_LAMBDA);
 | 
			
		||||
 | 
			
		||||
	vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH,
 | 
			
		||||
		      self, block->klass, /* th->passed_defined_class, */
 | 
			
		||||
		      self, defined_class,
 | 
			
		||||
		      VM_ENVVAL_PREV_EP_PTR(block->ep),
 | 
			
		||||
		      iseq->iseq_encoded + opt_pc,
 | 
			
		||||
		      cfp->sp + arg_size, iseq->local_size - arg_size,
 | 
			
		||||
| 
						 | 
				
			
			@ -633,19 +638,21 @@ static inline VALUE
 | 
			
		|||
vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref)
 | 
			
		||||
{
 | 
			
		||||
    const rb_block_t *blockptr = check_block(th);
 | 
			
		||||
    return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref);
 | 
			
		||||
    return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref,
 | 
			
		||||
			       blockptr->klass);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline VALUE
 | 
			
		||||
vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
 | 
			
		||||
{
 | 
			
		||||
    const rb_block_t *blockptr = check_block(th);
 | 
			
		||||
    return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0);
 | 
			
		||||
    return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0,
 | 
			
		||||
			       blockptr->klass);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
 | 
			
		||||
		  int argc, const VALUE *argv, const rb_block_t * blockptr)
 | 
			
		||||
static VALUE
 | 
			
		||||
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
 | 
			
		||||
	       int argc, const VALUE *argv, const rb_block_t *blockptr)
 | 
			
		||||
{
 | 
			
		||||
    VALUE val = Qundef;
 | 
			
		||||
    int state;
 | 
			
		||||
| 
						 | 
				
			
			@ -656,7 +663,8 @@ rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
 | 
			
		|||
	if (!proc->is_from_method) {
 | 
			
		||||
	    th->safe_level = proc->safe_level;
 | 
			
		||||
	}
 | 
			
		||||
	val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0);
 | 
			
		||||
	val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0,
 | 
			
		||||
				  defined_class);
 | 
			
		||||
    }
 | 
			
		||||
    TH_POP_TAG();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -670,6 +678,14 @@ rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
 | 
			
		|||
    return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
 | 
			
		||||
		  int argc, const VALUE *argv, const rb_block_t *blockptr)
 | 
			
		||||
{
 | 
			
		||||
    return vm_invoke_proc(th, proc, proc->block.self, proc->block.klass,
 | 
			
		||||
			  argc, argv, blockptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* special variable */
 | 
			
		||||
 | 
			
		||||
static rb_control_frame_t *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -731,7 +731,7 @@ VALUE rb_iseq_eval_main(VALUE iseqval);
 | 
			
		|||
#endif
 | 
			
		||||
int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
 | 
			
		||||
 | 
			
		||||
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
 | 
			
		||||
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
 | 
			
		||||
			int argc, const VALUE *argv, const rb_block_t *blockptr);
 | 
			
		||||
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
 | 
			
		||||
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
 | 
			
		|||
	  case OPTIMIZED_METHOD_TYPE_CALL: {
 | 
			
		||||
	    rb_proc_t *proc;
 | 
			
		||||
	    GetProcPtr(recv, proc);
 | 
			
		||||
	    val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr);
 | 
			
		||||
	    val = rb_vm_invoke_proc(th, proc, argc, argv, blockptr);
 | 
			
		||||
	    break;
 | 
			
		||||
	  }
 | 
			
		||||
	  default:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -466,7 +466,7 @@ vm_call_bmethod(rb_thread_t *th, VALUE recv, int argc, const VALUE *argv,
 | 
			
		|||
    /* control block frame */
 | 
			
		||||
    th->passed_me = me;
 | 
			
		||||
    GetProcPtr(me->def->body.proc, proc);
 | 
			
		||||
    val = rb_vm_invoke_proc(th, proc, recv, argc, argv, blockptr);
 | 
			
		||||
    val = vm_invoke_proc(th, proc, recv, defined_class, argc, argv, blockptr);
 | 
			
		||||
 | 
			
		||||
    EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, recv, me->called_id, me->klass);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -655,7 +655,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
 | 
			
		|||
		    MEMCPY(argv, cfp->sp - num, VALUE, num);
 | 
			
		||||
		    cfp->sp -= num + 1;
 | 
			
		||||
 | 
			
		||||
		    val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr);
 | 
			
		||||
		    val = rb_vm_invoke_proc(th, proc, argc, argv, blockptr);
 | 
			
		||||
		    break;
 | 
			
		||||
		  }
 | 
			
		||||
		  default:
 | 
			
		||||
| 
						 | 
				
			
			@ -683,10 +683,6 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
 | 
			
		|||
		val = vm_method_missing(th, id, recv, num, blockptr, stat);
 | 
			
		||||
	    }
 | 
			
		||||
	    else if (!(flag & VM_CALL_OPT_SEND_BIT) && (me->flag & NOEX_MASK) & NOEX_PROTECTED) {
 | 
			
		||||
		if (RB_TYPE_P(defined_class, T_ICLASS)) {
 | 
			
		||||
		    defined_class = RBASIC(defined_class)->klass;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!rb_obj_is_kind_of(cfp->self, defined_class)) {
 | 
			
		||||
		    val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue