8000 vm_insnhelper.c: iclass as klass in cfp · ruby/ruby@7de8c95 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7de8c95

Browse files
committed
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]
1 parent de83cb9 commit 7de8c95

File tree

8 files changed

+87
-23
lines changed

8 files changed

+87
-23
lines changed

cont.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1161,7 +1161,7 @@ rb_fiber_start(void)
11611161
th->root_svar = Qnil;
11621162

11631163
fib->status = RUNNING;
1164-
cont->value = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, 0);
1164+
cont->value = rb_vm_invoke_proc(th, proc, argc, argv, 0);
11651165
}
11661166
TH_POP_TAG();
11671167

proc.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,7 @@ proc_call(int argc, VALUE *argv, VALUE procval)
558558
}
559559
}
560560

561-
vret = rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
562-
argc, argv, blockptr);
561+
vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, blockptr);
563562
RB_GC_GUARD(procval);
564563
return vret;
565564
}
@@ -584,7 +583,7 @@ rb_proc_call(VALUE self, VALUE args)
584583
VALUE vret;
585584
rb_proc_t *proc;
586585
GetProcPtr(self, proc);
587-
vret = rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
586+
vret = rb_vm_invoke_proc(GET_THREAD(), proc,
588587
check_argc(RARRAY_LEN(args)), RARRAY_PTR(args), 0);
589588
RB_GC_GUARD(self);
590589
RB_GC_GUARD(args);
@@ -605,8 +604,7 @@ rb_proc_call_with_block(VALUE self, int argc, VALUE *argv, VALUE pass_procval)
605604
block = &pass_proc->block;
606605
}
607606

608-
vret = rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
609-
argc, argv, block);
607+
vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, block);
610608
RB_GC_GUARD(self);
611609
RB_GC_GUARD(pass_procval);
612610
return vret;

test/ruby/test_module.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,4 +1398,58 @@ def test_class_variables
13981398
assert_equal([:@@bar, :@@foo], m2.class_variables(true))
13991399
assert_equal([:@@bar], m2.class_variables(false))
14001400
end
1401+
1402+
Bug6891 = '[ruby-core:47241]'
1403+
1404+
def test_extend_module_with_protected_method
1405+
list = []
1406+
1407+
x = Class.new {
1408+
@list = list
1409+
1410+
extend Module.new {
1411+
protected
1412+
1413+
def inherited(klass)
1414+
@list << "protected"
1415+
super(klass)
1416+
end
1417+
}
1418+
1419+
extend Module.new {
1420+
def inherited(klass)
1421+
@list << "public"
1422+
super(klass)
1423+
end
1424+
}
1425+
}
1426+
1427+
assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
1428+
assert_equal(['public', 'protected'], list)
1429+
end
1430+
1431+
def test_extend_module_with_protected_bmethod
1432+
list = []
1433+
1434+
x = Class.new {
1435+
extend Module.new {
1436+
protected
1437+
1438+
define_method(:inherited) do |klass|
1439+
list << "protected"
1440+
super(klass)
1441+
end
1442+
}
1443+
1444+
extend Module.new {
1445+
define_method(:inherited) do |klass|
1446+
list << "public"
1447+
super(klass)
1448+
end
1449+
}
1450+
}
1451+
1452+
assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
1453+
assert_equal(['public', 'protected'], list)
1454+
end
14011455
end

thread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
455455
th->errinfo = Qnil;
456456
th->root_lep = rb_vm_ep_local_ep(proc->block.ep);
457457
th->root_svar = Qnil;
458-
th->value = rb_vm_invoke_proc(th, proc, proc->block.self,
458+
th->value = rb_vm_invoke_proc(th, proc,
459459
(int)RARRAY_LEN(args), RARRAY_PTR(args), 0);
460460
}
461461
else {

vm.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp)
6161
return VM_CF_BLOCK_PTR(cfp);
6262
}
6363

64+
static VALUE
65+
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
66+
int argc, const VALUE *argv, const rb_block_t *blockptr);
67+
6468
#include "vm_insnhelper.h"
6569
#include "vm_insnhelper.c"
6670
#include "vm_exec.h"
@@ -577,7 +581,8 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
577581
static inline VALUE
578582
invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
579583
VALUE self, int argc, const VALUE *argv,
580-
const rb_block_t *blockptr, const NODE *cref)
584+
const rb_block_t *blockptr, const NODE *cref,
585+
VALUE defined_class)
581586
{
582587
if (SPECIAL_CONST_P(block->iseq))
583588
return Qnil;
@@ -599,7 +604,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
599604
type == VM_FRAME_MAGIC_LAMBDA);
600605

601606
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH,
602-
self, block->klass, /* th->passed_defined_class, */
607+
self, defined_class,
603608
VM_ENVVAL_PREV_EP_PTR(block->ep),
604609
iseq->iseq_encoded + opt_pc,
605610
cfp->sp + arg_size, iseq->local_size - arg_size,
@@ -633,19 +638,21 @@ static inline VALUE
633638
vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const NODE *cref)
634639
{
635640
const rb_block_t *blockptr = check_block(th);
636-
return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref);
641+
return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, cref,
642+
blockptr->klass);
637643
}
638644

639645
static inline VALUE
640646
vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
641647
{
642648
const rb_block_t *blockptr = check_block(th);
643-
return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0);
649+
return invoke_block_from_c(th, blockptr, blockptr->self, argc, argv, 0, 0,
650+
blockptr->klass);
644651
}
645652

646-
VALUE
647-
rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
648-
int argc, const VALUE *argv, const rb_block_t * blockptr)
653+
static VALUE
654+
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
655+
int argc, const VALUE *argv, const rb_block_t *blockptr)
649656
{
650657
VALUE val = Qundef;
651658
int state;
@@ -656,7 +663,8 @@ rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
656663
if (!proc->is_from_method) {
657664
th->safe_level = proc->safe_level;
658665
}
659-
val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0);
666+
val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, 0,
667+
defined_class);
660668
}
661669
TH_POP_TAG();
662670

@@ -670,6 +678,14 @@ rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
670678
return val;
671679
}
672680

681+
VALUE
682+
rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
683+
int argc, const VALUE *argv, const rb_block_t *blockptr)
684+
{
685+
return vm_invoke_proc(th, proc, proc->block.self, proc->block.klass,
686+
argc, argv, blockptr);
687+
}
688+
673689
/* special variable */
674690

675691
static rb_control_frame_t *

vm_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ VALUE rb_iseq_eval_main(VALUE iseqval);
731731
#endif
732732
int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
733733

734-
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
734+
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
735735
int argc, const VALUE *argv, const rb_block_t *blockptr);
736736
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
737737
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);

vm_eval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
126126
case OPTIMIZED_METHOD_TYPE_CALL: {
127127
rb_proc_t *proc;
128128
GetProcPtr(recv, proc);
129-
val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr);
129+
val = rb_vm_invoke_proc(th, proc, argc, argv, blockptr);
130130
break;
131131
}
132132
default:

vm_insnhelper.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ vm_call_bmethod(rb_thread_t *th, VALUE recv, int argc, const VALUE *argv,
466466
/* control block frame */
467467
th->passed_me = me;
468468
GetProcPtr(me->def->body.proc, proc);
469-
val = rb_vm_invoke_proc(th, proc, recv, argc, argv, blockptr);
469+
val = vm_invoke_proc(th, proc, recv, defined_class, argc, argv, blockptr);
470470

471471
EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, recv, me->called_id, me->klass);
472472

@@ -655,7 +655,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
655655
MEMCPY(argv, cfp->sp - num, VALUE, num);
656656
cfp->sp -= num + 1;
657657

658-
val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr);
658+
val = rb_vm_invoke_proc(th, proc, argc, argv, blockptr);
659659
break;
660660
}
661661
default:
@@ -683,10 +683,6 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
683683
val = vm_method_missing(th, id, recv, num, blockptr, stat);
684684
}
685685
else if (!(flag & VM_CALL_OPT_SEND_BIT) && (me->flag & NOEX_MASK) & NOEX_PROTECTED) {
686-
if (RB_TYPE_P(defined_class, T_ICLASS)) {
687-
defined_class = RBASIC(defined_class)->klass;
688-
}
689-
690686
if (!rb_obj_is_kind_of(cfp->self, defined_class)) {
691687
val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
692688
}

0 commit comments

Comments
 (0)
0