mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
insns.def: refactor by wanabe
* insns.def (defined): use vm_search_superclass() like as normal super call. based on a patch <https://gist.github.com/wanabe/5520026> 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
08fbd2cee2
commit
babae04960
3 changed files with 32 additions and 21 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
Sun May 5 18:56:52 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* insns.def (defined): use vm_search_superclass() like as normal super
|
||||||
|
call. based on a patch <https://gist.github.com/wanabe/5520026> 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.
|
||||||
|
|
||||||
Sun May 5 16:29:41 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun May 5 16:29:41 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* insns.def (defined): get method entry from the method top level
|
* insns.def (defined): get method entry from the method top level
|
||||||
|
|
19
insns.def
19
insns.def
|
@ -764,21 +764,10 @@ defined
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEFINED_ZSUPER:{
|
case DEFINED_ZSUPER:{
|
||||||
const rb_method_entry_t *me = GET_CFP()->me;
|
rb_call_info_t cit;
|
||||||
if (!me) {
|
if (vm_search_superclass(GET_CFP(), GET_ISEQ(), Qnil, &cit) == 0) {
|
||||||
const rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(GET_THREAD());
|
VALUE klass = cit.klass;
|
||||||
const rb_control_frame_t *cfp = GET_CFP();
|
ID id = cit.mid;
|
||||||
const VALUE *const local_ep = rb_vm_ep_local_ep(cfp->ep);
|
|
||||||
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp), end_cfp)) {
|
|
||||||
if (cfp->ep == local_ep) {
|
|
||||||
me = cfp->me;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (me) {
|
|
||||||
VALUE klass = vm_search_normal_superclass(GET_CFP()->klass);
|
|
||||||
ID id = me->def ? me->def->original_id : me->called_id;
|
|
||||||
if (rb_method_boundp(klass, id, 0)) {
|
if (rb_method_boundp(klass, id, 0)) {
|
||||||
expr_type = DEFINED_ZSUPER;
|
expr_type = DEFINED_ZSUPER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1954,7 +1954,7 @@ vm_super_outside(void)
|
||||||
rb_raise(rb_eNoMethodError, "super called outside of method");
|
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)
|
vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, rb_call_info_t *ci)
|
||||||
{
|
{
|
||||||
while (iseq && !iseq->klass) {
|
while (iseq && !iseq->klass) {
|
||||||
|
@ -1962,7 +1962,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iseq == 0) {
|
if (iseq == 0) {
|
||||||
vm_super_outside();
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ci->mid = iseq->defined_method_id;
|
ci->mid = iseq->defined_method_id;
|
||||||
|
@ -1973,7 +1973,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
|
||||||
|
|
||||||
if (!sigval) {
|
if (!sigval) {
|
||||||
/* zsuper */
|
/* 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) {
|
while (lcfp->iseq != iseq) {
|
||||||
|
@ -1982,7 +1982,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
|
||||||
while (1) {
|
while (1) {
|
||||||
lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp);
|
lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp);
|
||||||
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, lcfp)) {
|
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, lcfp)) {
|
||||||
vm_super_outside();
|
return -1;
|
||||||
}
|
}
|
||||||
if (lcfp->ep == tep) {
|
if (lcfp->ep == tep) {
|
||||||
break;
|
break;
|
||||||
|
@ -1992,7 +1992,7 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
|
||||||
|
|
||||||
/* temporary measure for [Bug #2420] [Bug #3136] */
|
/* temporary measure for [Bug #2420] [Bug #3136] */
|
||||||
if (!lcfp->me) {
|
if (!lcfp->me) {
|
||||||
vm_super_outside();
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ci->mid = lcfp->me->def->original_id;
|
ci->mid = lcfp->me->def->original_id;
|
||||||
|
@ -2001,6 +2001,8 @@ vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval,
|
||||||
else {
|
else {
|
||||||
ci->klass = vm_search_normal_superclass(reg_cfp->klass);
|
ci->klass = vm_search_normal_superclass(reg_cfp->klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2030,7 +2032,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));
|
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 */
|
/* TODO: use inline cache */
|
||||||
ci->me = rb_method_entry(ci->klass, ci->mid, &ci->defined_class);
|
ci->me = rb_method_entry(ci->klass, ci->mid, &ci->defined_class);
|
||||||
|
|
Loading…
Reference in a new issue