diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-11-10 21:53:12 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-11-10 21:53:12 +0900 |
| commit | 181f980b6cc5dfa25b270e137c6d060a897b8bf4 (patch) | |
| tree | 10c9689c867d16ccafa2108f75923bd9154b2ba6 | |
| parent | 41c8c419cf7d9cc220a39696e2e498881394352b (diff) | |
| download | mruby-181f980b6cc5dfa25b270e137c6d060a897b8bf4.tar.gz mruby-181f980b6cc5dfa25b270e137c6d060a897b8bf4.zip | |
Need to clear stack region for local variables in eval; fix #3844
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 6 | ||||
| -rw-r--r-- | src/vm.c | 11 |
2 files changed, 15 insertions, 2 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 997b69e25..14e89ac14 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -273,13 +273,17 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, static mrb_value exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) { + /* no argument passed from eval() */ + mrb->c->ci->argc = 0; if (mrb->c->ci->acc < 0) { - mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0); + mrb_value ret = mrb_top_run(mrb, proc, self, 0); if (mrb->exc) { mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); } return ret; } + /* clear block */ + mrb->c->stack[1] = mrb_nil_value(); return mrb_exec_irep(mrb, self, proc); } @@ -491,6 +491,7 @@ mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) { mrb_callinfo *ci = mrb->c->ci; + int keep; mrb->c->stack[0] = self; ci->proc = p; @@ -499,7 +500,15 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) return p->body.func(mrb, self); } ci->nregs = p->body.irep->nregs; - stack_extend(mrb, (ci->argc < 0 && ci->nregs < 3) ? 3 : ci->nregs); + if (ci->argc < 0) keep = 3; + else keep = ci->argc + 1; + if (ci->argc < keep) { + stack_extend(mrb, keep); + } + else { + stack_extend(mrb, ci->argc); + stack_clear(mrb->c->stack+keep, ci->nregs-keep); + } ci = cipush(mrb); ci->nregs = 0; |
