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…
Reference in a new issue