ruby-changes:24685
From: nobu <ko1@a...>
Date: Mon, 20 Aug 2012 20:36:51 +0900 (JST)
Subject: [ruby-changes:24685] nobu:r36736 (trunk): vm_insnhelper.c: iclass as klass in cfp
nobu 2012-08-20 20:36:34 +0900 (Mon, 20 Aug 2012) New Revision: 36736 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36736 Log: 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] Modified files: trunk/ChangeLog trunk/cont.c trunk/proc.c trunk/test/ruby/test_module.rb trunk/thread.c trunk/vm.c trunk/vm_core.h trunk/vm_eval.c trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 36735) +++ ChangeLog (revision 36736) @@ -1,3 +1,19 @@ +Mon Aug 20 20:36:30 2012 Nobuyoshi Nakada <nobu@r...> + + * 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@r...> + + * 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@m...> * common.mk: fix failed to make with -j2. Index: vm_core.h =================================================================== --- vm_core.h (revision 36735) +++ vm_core.h (revision 36736) @@ -731,7 +731,7 @@ #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); Index: vm_eval.c =================================================================== --- vm_eval.c (revision 36735) +++ vm_eval.c (revision 36736) @@ -126,7 +126,7 @@ 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: Index: proc.c =================================================================== --- proc.c (revision 36735) +++ proc.c (revision 36736) @@ -558,8 +558,7 @@ } } - 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 @@ 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 @@ 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; Index: thread.c =================================================================== --- thread.c (revision 36735) +++ thread.c (revision 36736) @@ -455,7 +455,7 @@ 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 { Index: cont.c =================================================================== --- cont.c (revision 36735) +++ cont.c (revision 36736) @@ -1161,7 +1161,7 @@ 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(); Index: vm.c =================================================================== --- vm.c (revision 36735) +++ vm.c (revision 36736) @@ -61,6 +61,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 * Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 36735) +++ vm_insnhelper.c (revision 36736) @@ -466,7 +466,7 @@ /* 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 @@ 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 @@ 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); } Index: test/ruby/test_module.rb =================================================================== --- test/ruby/test_module.rb (revision 36735) +++ test/ruby/test_module.rb (revision 36736) @@ -1398,4 +1398,58 @@ 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/