diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-03-17 15:55:18 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-03-17 15:55:18 +0900 |
| commit | fca17b41c7a9c93787c90b715f1fb054021fab28 (patch) | |
| tree | 863b5ff7dc5f01333c1ae105a2142776dba55d4a /mrbgems/mruby-eval | |
| parent | 9ecebebf3e12d6d8125a7a24b8ac4e124c7cd98a (diff) | |
| download | mruby-fca17b41c7a9c93787c90b715f1fb054021fab28.tar.gz mruby-fca17b41c7a9c93787c90b715f1fb054021fab28.zip | |
Avoid trampoline when #eval is called from mrb_funcall(); fix #3522
Diffstat (limited to 'mrbgems/mruby-eval')
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 8b402e78c..5e8952f0d 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -133,7 +133,9 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) break; case OP_STOP: - irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL); + if (mrb->c->ci->acc >= 0) { + irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL); + } break; } } @@ -210,6 +212,19 @@ create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, con } static mrb_value +exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) +{ + if (mrb->c->ci->acc < 0) { + mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0); + if (mrb->exc) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); + } + return ret; + } + return mrb_exec_irep(mrb, self, proc); +} + +static mrb_value f_eval(mrb_state *mrb, mrb_value self) { char *s; @@ -223,11 +238,9 @@ f_eval(mrb_state *mrb, mrb_value self) proc = create_proc_from_string(mrb, s, len, binding, file, line); mrb_assert(!MRB_PROC_CFUNC_P(proc)); - return mrb_exec_irep(mrb, self, proc); + return exec_irep(mrb, self, proc); } -#define CI_ACC_SKIP -1 - static mrb_value f_instance_eval(mrb_state *mrb, mrb_value self) { @@ -250,7 +263,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self) proc->target_class = mrb_class_ptr(cv); mrb->c->ci->env = NULL; mrb_assert(!MRB_PROC_CFUNC_P(proc)); - return mrb_exec_irep(mrb, self, proc); + return exec_irep(mrb, self, proc); } else { mrb_get_args(mrb, "&", &b); |
