From 2249551c638be6a3a339c2459d06bdfb4087d110 Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Thu, 10 Aug 2017 23:19:11 +0200 Subject: Fixed calling missing method through super with 126 args --- src/vm.c | 55 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/vm.c b/src/vm.c index 171776807..9bfac5e61 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1379,9 +1379,7 @@ RETRY_TRY_BLOCK: c = mrb_class(mrb, recv); m = mrb_method_search_vm(mrb, &c, mid); if (!m) { - mrb_value sym = mrb_symbol_value(mid); mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); - m = mrb_method_search_vm(mrb, &c, missing); if (!m) { mrb_value args; @@ -1404,7 +1402,7 @@ RETRY_TRY_BLOCK: regs[a+2] = blk; n = CALL_MAXARGS; } - mrb_ary_unshift(mrb, regs[a+1], sym); + mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); } /* push callinfo */ @@ -1579,6 +1577,23 @@ RETRY_TRY_BLOCK: goto L_RAISE; } recv = regs[0]; + if (n == CALL_MAXARGS) { + bidx = a+2; + } + else { + bidx = a+n+1; + } + blk = regs[bidx]; + if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { + mrb_value result; + + if (bidx >= ci->nregs) { + stack_extend(mrb, bidx+1); + ci->nregs = bidx+1; + } + result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + regs[bidx] = result; + } c = mrb->c->ci->target_class->super; m = mrb_method_search_vm(mrb, &c, mid); if (!m) { @@ -1597,35 +1612,15 @@ RETRY_TRY_BLOCK: mrb_method_missing(mrb, mid, recv, args); } mid = missing; - if (n == CALL_MAXARGS-1) { + if (n != CALL_MAXARGS) { + if (a+2 >= ci->nregs) { + stack_extend(mrb, a+3); + } regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); - n++; - } - if (n == CALL_MAXARGS) { - mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); - } - else { - value_move(regs+a+2, regs+a+1, ++n); - SET_SYM_VALUE(regs[a+1], ci->mid); - } - } - - if (n == CALL_MAXARGS) { - bidx = a+2; - } - else { - bidx = a+n+1; - } - blk = regs[bidx]; - if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - mrb_value result; - - if (bidx >= ci->nregs) { - stack_extend(mrb, bidx+1); - ci->nregs = bidx+1; + regs[a+2] = blk; + n = CALL_MAXARGS; } - result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); - regs[bidx] = result; + mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); } /* push callinfo */ -- cgit v1.2.3 From ab39ed4f825c1957546217a8c2e510244a967193 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 11 Aug 2017 13:15:50 +0900 Subject: Defer `mid` update after `unshift`; ref #3776 --- src/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm.c b/src/vm.c index f37ce57c8..22d7f997f 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1393,7 +1393,6 @@ RETRY_TRY_BLOCK: ERR_PC_SET(mrb, pc); mrb_method_missing(mrb, mid, recv, args); } - mid = missing; if (n != CALL_MAXARGS) { if (a+2 >= irep->nregs) { stack_extend(mrb, a+3); @@ -1403,6 +1402,7 @@ RETRY_TRY_BLOCK: n = CALL_MAXARGS; } mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); + mid = missing; } /* push callinfo */ -- cgit v1.2.3