From 3f591d71c61cb490c4c28c4d87142520366eaa64 Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Sat, 12 Aug 2017 14:31:18 +0200 Subject: Refactored variable usage in OP_SEND and OP_SUPER --- src/vm.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index 27334765f..f93e78de9 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1347,9 +1347,8 @@ RETRY_TRY_BLOCK: struct RProc *m; struct RClass *c; mrb_callinfo *ci = mrb->c->ci; - mrb_value recv, result; + mrb_value recv, blk; mrb_sym mid = syms[GETARG_B(i)]; - mrb_value blk; recv = regs[a]; if (GET_OPCODE(i) != OP_SENDB) { @@ -1358,7 +1357,7 @@ RETRY_TRY_BLOCK: ci->nregs = bidx+1; } SET_NIL_VALUE(regs[bidx]); - blk = mrb_nil_value(); + blk = regs[bidx]; } else { blk = regs[bidx]; @@ -1367,8 +1366,7 @@ RETRY_TRY_BLOCK: stack_extend(mrb, bidx+1); ci->nregs = bidx+1; } - result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); - blk = regs[bidx] = result; + blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } } c = mrb_class(mrb, recv); @@ -1409,7 +1407,7 @@ RETRY_TRY_BLOCK: if (MRB_PROC_CFUNC_P(m)) { ci->nregs = (argc < 0) ? 3 : n+2; - result = m->body.func(mrb, recv); + recv = m->body.func(mrb, recv); mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; @@ -1417,7 +1415,6 @@ RETRY_TRY_BLOCK: if (GET_OPCODE(i) == OP_SENDB) { if (mrb_type(blk) == MRB_TT_PROC) { struct RProc *p = mrb_proc_ptr(blk); - if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) { p->flags |= MRB_PROC_ORPHAN; } @@ -1426,7 +1423,7 @@ RETRY_TRY_BLOCK: if (!ci->target_class) { /* return from context modifying method (resume/yield) */ if (ci->acc == CI_ACC_RESUMED) { mrb->jmp = prev_jmp; - return result; + return recv; } else { mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); @@ -1436,7 +1433,7 @@ RETRY_TRY_BLOCK: syms = irep->syms; } } - mrb->c->stack[0] = result; + mrb->c->stack[0] = recv; /* pop stackpos */ mrb->c->stack = ci->stackent; pc = ci->pc; @@ -1538,31 +1535,25 @@ RETRY_TRY_BLOCK: int n = GETARG_C(i); int argc = (n == CALL_MAXARGS) ? -1 : n; int bidx = (argc < 0) ? a+2 : a+n+1; - mrb_value recv; - mrb_callinfo *ci = mrb->c->ci; struct RProc *m; struct RClass *c; + mrb_callinfo *ci = mrb->c->ci; + mrb_value recv, blk; mrb_sym mid = ci->mid; - mrb_value blk; if (mid == 0 || !ci->target_class) { - mrb_value exc; - - exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); + mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); mrb_exc_set(mrb, exc); goto L_RAISE; } recv = regs[0]; 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; + blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } c = ci->target_class->super; m = mrb_method_search_vm(mrb, &c, mid); -- cgit v1.2.3 From f2d46409983676383d8562fa79012ac855ff7210 Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Sat, 12 Aug 2017 14:47:22 +0200 Subject: Extended stack always based on ci->nregs --- src/vm.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index f93e78de9..e0bc7b13d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -501,14 +501,9 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) if (MRB_PROC_CFUNC_P(p)) { return p->body.func(mrb, self); } - if (ci->argc < 0) { - stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs); - } - else { - stack_extend(mrb, p->body.irep->nregs); - } - ci->nregs = p->body.irep->nregs; + stack_extend(mrb, (ci->argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + ci = cipush(mrb); ci->nregs = 0; ci->target_class = 0; @@ -584,7 +579,6 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) { struct RProc *p; mrb_callinfo *ci; - mrb_int max = 3; if (mrb_nil_p(blk)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); @@ -607,8 +601,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) return p->body.func(mrb, self); } ci->nregs = p->body.irep->nregs; - if (max < ci->nregs) max = ci->nregs; - stack_extend(mrb, max); + stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs); mrb->c->stack[0] = self; mrb->c->stack[1] = self; mrb->c->stack[2] = mrb_nil_value(); @@ -712,14 +705,8 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ci->target_class = c; ci->acc = CI_ACC_SKIP; mrb->c->stack = mrb->c->stack + n; - if (MRB_PROC_CFUNC_P(p)) { - ci->nregs = argc + 2; - stack_extend(mrb, ci->nregs); - } - else { - ci->nregs = p->body.irep->nregs; - stack_extend(mrb, ci->nregs); - } + ci->nregs = MRB_PROC_CFUNC_P(p) ? argc+2 : p->body.irep->nregs; + stack_extend(mrb, ci->nregs); mrb->c->stack[0] = self; if (argc > 0) { @@ -1353,8 +1340,8 @@ RETRY_TRY_BLOCK: recv = regs[a]; if (GET_OPCODE(i) != OP_SENDB) { if (bidx >= ci->nregs) { - stack_extend(mrb, bidx+1); ci->nregs = bidx+1; + stack_extend(mrb, ci->nregs); } SET_NIL_VALUE(regs[bidx]); blk = regs[bidx]; @@ -1363,8 +1350,8 @@ RETRY_TRY_BLOCK: blk = regs[bidx]; if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { if (bidx >= ci->nregs) { - stack_extend(mrb, bidx+1); ci->nregs = bidx+1; + stack_extend(mrb, ci->nregs); } blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } @@ -1447,7 +1434,7 @@ RETRY_TRY_BLOCK: pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; - stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); + stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); pc = irep->iseq; JUMP; } @@ -1512,7 +1499,7 @@ RETRY_TRY_BLOCK: pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; - stack_extend(mrb, irep->nregs); + stack_extend(mrb, ci->nregs); if (ci->argc < 0) { if (irep->nregs > 3) { stack_clear(regs+3, irep->nregs-3); @@ -1550,8 +1537,8 @@ RETRY_TRY_BLOCK: blk = regs[bidx]; if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { if (bidx >= ci->nregs) { - stack_extend(mrb, bidx+1); ci->nregs = bidx+1; + stack_extend(mrb, ci->nregs); } blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } @@ -1627,7 +1614,7 @@ RETRY_TRY_BLOCK: pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; - stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); + stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); pc = irep->iseq; JUMP; } @@ -2755,9 +2742,9 @@ RETRY_TRY_BLOCK: irep = p->body.irep; pool = irep->pool; syms = irep->syms; - stack_extend(mrb, irep->nregs); - stack_clear(regs+1, irep->nregs-1); ci->nregs = irep->nregs; + stack_extend(mrb, ci->nregs); + stack_clear(regs+1, ci->nregs-1); pc = irep->iseq; JUMP; } -- cgit v1.2.3 From 198df6103924149d74f9668b5bb63c2e8e9e79ab Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Sat, 12 Aug 2017 23:27:17 +0200 Subject: Removed unneeded ci->nregs checks in OP_SEND and OP_SUPER Because of #3504 `ci->nregs = bidx+1` was introduced in b64f08784cc50861dec80c26fce715982c02c9e9. This led to the follow up error #3551 whose fix introduced the `if (bidx >= ci->nregs)` check in 071164b7999d0932fd60fb3c580a6c374ab1cf4f and the `stack_extend(mrb, ci->nregs)` in 93d802987e722444d0520a8d3f28002841c4f825. Then, the code causing #3504 reappeared again in #3590. The fix for it moved the code dealing with the block in OP_SUPER from below the `cipush` to above the `cipush` in d9fb8b69b0621e8cd2c7c43fd8511a83718d7e45. The `if (bidx >= ci->nregs) { ... }` from then on works with the original callinfo and not the pushed one. `ci->nregs` needed to be modified for the pushed one because it is initialized to 0. But for the original ci it is propertly set and a check is not needed. --- src/vm.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index e0bc7b13d..90fa6b3b7 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1339,20 +1339,12 @@ RETRY_TRY_BLOCK: recv = regs[a]; if (GET_OPCODE(i) != OP_SENDB) { - if (bidx >= ci->nregs) { - ci->nregs = bidx+1; - stack_extend(mrb, ci->nregs); - } SET_NIL_VALUE(regs[bidx]); blk = regs[bidx]; } else { blk = regs[bidx]; if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - if (bidx >= ci->nregs) { - ci->nregs = bidx+1; - stack_extend(mrb, ci->nregs); - } blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } } @@ -1536,10 +1528,6 @@ RETRY_TRY_BLOCK: recv = regs[0]; blk = regs[bidx]; if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - if (bidx >= ci->nregs) { - ci->nregs = bidx+1; - stack_extend(mrb, ci->nregs); - } blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } c = ci->target_class->super; -- cgit v1.2.3 From d5ac785b315530bcdba7b0a5bf9fd49f1daaaad7 Mon Sep 17 00:00:00 2001 From: Christopher Aue Date: Sat, 12 Aug 2017 23:59:35 +0200 Subject: Reintroduced not storing converted proc directly in the stack --- src/vm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/vm.c') diff --git a/src/vm.c b/src/vm.c index 90fa6b3b7..2df465b9d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1345,7 +1345,10 @@ RETRY_TRY_BLOCK: else { blk = regs[bidx]; if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + /* store the converted proc not directly in the stack because the stack + might have been reallocated during mrb_convert_type(), see #3622 */ + blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + regs[bidx] = blk; } } c = mrb_class(mrb, recv); @@ -1528,7 +1531,10 @@ RETRY_TRY_BLOCK: recv = regs[0]; blk = regs[bidx]; if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { - blk = regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + /* store the converted proc not directly in the stack because the stack + might have been reallocated during mrb_convert_type(), see #3622 */ + blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); + regs[bidx] = blk; } c = ci->target_class->super; m = mrb_method_search_vm(mrb, &c, mid); -- cgit v1.2.3