From 4c1f8acd2ac14ffce1e1d9f414c700f293a7bdc6 Mon Sep 17 00:00:00 2001 From: nagachika Date: Wed, 8 May 2013 14:38:43 +0000 Subject: merge revision(s) 40583,40584,40585,40590: [Backport #8367] * insns.def (defined): get method entry from the method top level frame, not block frame. [ruby-core:54769] [Bug #8367] * insns.def (defined): use vm_search_superclass() like as normal super call. based on a patch by wanabe. * vm_insnhelper.c (vm_search_superclass): return error but not raise exceptions. * vm_insnhelper.c (vm_search_super_method): check the result of vm_search_superclass and raise execptions on error. vm_search_superclass and raise exceptions on error. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40613 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- vm_insnhelper.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'vm_insnhelper.c') diff --git a/vm_insnhelper.c b/vm_insnhelper.c index ec26f677ff..0c52774ca8 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1927,7 +1927,7 @@ vm_super_outside(void) rb_raise(rb_eNoMethodError, "super called outside of method"); } -static void +static int vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, rb_call_info_t *ci) { while (iseq && !iseq->klass) { @@ -1935,7 +1935,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, } if (iseq == 0) { - vm_super_outside(); + return -1; } ci->mid = iseq->defined_method_id; @@ -1946,7 +1946,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, if (!sigval) { /* zsuper */ - rb_raise(rb_eRuntimeError, "implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly."); + return -2; } while (lcfp->iseq != iseq) { @@ -1955,7 +1955,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, while (1) { lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp); if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, lcfp)) { - vm_super_outside(); + return -1; } if (lcfp->ep == tep) { break; @@ -1965,7 +1965,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, /* temporary measure for [Bug #2420] [Bug #3136] */ if (!lcfp->me) { - vm_super_outside(); + return -1; } ci->mid = lcfp->me->def->original_id; @@ -1974,6 +1974,8 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, else { ci->klass = vm_search_normal_superclass(reg_cfp->klass); } + + return 0; } static void @@ -2003,7 +2005,15 @@ vm_search_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_inf rb_obj_classname(ci->recv), rb_class2name(m)); } - vm_search_superclass(GET_CFP(), iseq, sigval, ci); + switch (vm_search_superclass(GET_CFP(), iseq, sigval, ci)) { + case -1: + vm_super_outside(); + case -2: + rb_raise(rb_eRuntimeError, + "implicit argument passing of super from method defined" + " by define_method() is not supported." + " Specify all arguments explicitly."); + } /* TODO: use inline cache */ ci->me = rb_method_entry(ci->klass, ci->mid, &ci->defined_class); -- cgit v1.2.3