diff --git a/ChangeLog b/ChangeLog index 705695ed58..cc3fff3ac5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Wed Dec 24 20:33:45 2008 Koichi Sasada + + * vm_insnhelper.c (vm_call_method): use class of method defined + instead of receiver's class on bmethod. fixes [ruby-core:20786] + + * bootstraptest/test_method.rb: add a test for above. + + * vm_insnhelper.c (vm_setup_method): remove unused parameter klass. + + * vm_insnhelper.h (CALL_METHOD): ditto. + + * insns.def, vm_eval.c: ditto. + Wed Dec 24 20:15:50 2008 Koichi Sasada * tool/file2lastrev.rb (get_revisions): fix to ignore end of line. diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb index 33e7436e6e..fff484db73 100644 --- a/bootstraptest/test_method.rb +++ b/bootstraptest/test_method.rb @@ -1084,3 +1084,22 @@ assert_equal '[1, [:foo, 3, 4, :foo]]', %q{ a = b = [:foo] regular(1, *a, *[3, 4], *b) } + +assert_equal '["B", "A"]', %q{ + class A + def m + 'A' + end + end + + class B < A + define_method(:m) do + ['B', super()] + end + end + + class C < B + end + + C.new.m +} diff --git a/insns.def b/insns.def index c91147ed16..669c491ed7 100644 --- a/insns.def +++ b/insns.def @@ -996,7 +996,7 @@ send vm_send_optimize(GET_CFP(), &mn, &flag, &num, &id, klass); } - CALL_METHOD(num, blockptr, flag, id, mn, recv, klass); + CALL_METHOD(num, blockptr, flag, id, mn, recv); } /** @@ -1023,7 +1023,7 @@ invokesuper vm_search_superclass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass); mn = rb_method_node(klass, id); - CALL_METHOD(num, blockptr, flag, id, mn, recv, klass); + CALL_METHOD(num, blockptr, flag, id, mn, recv); } /** diff --git a/vm_eval.c b/vm_eval.c index 20d7c920d6..aea00e2f5c 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -52,7 +52,7 @@ vm_call0(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid, *reg_cfp->sp++ = argv[i]; } - vm_setup_method(th, reg_cfp, argc, blockptr, 0, iseqval, recv, klass); + vm_setup_method(th, reg_cfp, argc, blockptr, 0, iseqval, recv); val = vm_exec(th); break; } diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 5c3348f3b2..749832c297 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -423,7 +423,7 @@ vm_method_missing(rb_thread_t *th, ID id, VALUE recv, static inline void vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, const int argc, const rb_block_t *blockptr, const VALUE flag, - const VALUE iseqval, const VALUE recv, const VALUE klass) + const VALUE iseqval, const VALUE recv) { rb_iseq_t *iseq; int opt_pc, i; @@ -479,7 +479,7 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, static inline VALUE vm_call_method(rb_thread_t * const th, rb_control_frame_t * const cfp, const int num, rb_block_t * const blockptr, const VALUE flag, - const ID id, const NODE * mn, const VALUE recv, VALUE klass) + const ID id, const NODE * mn, const VALUE recv) { VALUE val; @@ -496,7 +496,7 @@ vm_call_method(rb_thread_t * const th, rb_control_frame_t * const cfp, switch (nd_type(node)) { case RUBY_VM_METHOD_NODE:{ - vm_setup_method(th, cfp, num, blockptr, flag, (VALUE)node->nd_body, recv, klass); + vm_setup_method(th, cfp, num, blockptr, flag, (VALUE)node->nd_body, recv); return Qundef; } case NODE_CFUNC:{ @@ -521,10 +521,11 @@ vm_call_method(rb_thread_t * const th, rb_control_frame_t * const cfp, VALUE *argv = ALLOCA_N(VALUE, num); MEMCPY(argv, cfp->sp - num, VALUE, num); cfp->sp += - num - 1; - val = vm_call_bmethod(th, id, node->nd_cval, recv, klass, num, argv, blockptr); + val = vm_call_bmethod(th, id, node->nd_cval, recv, mn->nd_clss, num, argv, blockptr); break; } case NODE_ZSUPER:{ + VALUE klass; klass = RCLASS_SUPER(mn->nd_clss); mn = rb_method_node(klass, id); diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 613d997a4c..6000f9478c 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -158,8 +158,8 @@ extern VALUE ruby_vm_global_state_version; c1->nd_next = __tmp_c2->nd_next; \ } while (0) -#define CALL_METHOD(num, blockptr, flag, id, mn, recv, klass) do { \ - VALUE v = vm_call_method(th, GET_CFP(), num, blockptr, flag, id, mn, recv, klass); \ +#define CALL_METHOD(num, blockptr, flag, id, mn, recv) do { \ + VALUE v = vm_call_method(th, GET_CFP(), num, blockptr, flag, id, mn, recv); \ if (v == Qundef) { \ RESTORE_REGS(); \ NEXT_INSN(); \ @@ -188,7 +188,7 @@ extern VALUE ruby_vm_global_state_version; #define CALL_SIMPLE_METHOD(num, id, recv) do { \ VALUE klass = CLASS_OF(recv); \ - CALL_METHOD(num, 0, 0, id, rb_method_node(klass, id), recv, CLASS_OF(recv)); \ + CALL_METHOD(num, 0, 0, id, rb_method_node(klass, id), recv); \ } while (0) #endif /* RUBY_INSNHELPER_H */