From dd34ac647fb5d6842941b3529d1452797862cc23 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 3 Apr 2021 21:17:48 +0900 Subject: Make `mrb_exec_irep()` allow non-VM to enter. Change the old `mrb_exec_irep()` as-is to static `mrb_exec_irep_vm()`. Extract the VM entry part from the old `exec_irep()` in `mruby-eval/src/eval.c` and make it the core of the new `mrb_exec_irep()`. --- src/vm.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/vm.c b/src/vm.c index edfb55586..d7f2f58d7 100644 --- a/src/vm.c +++ b/src/vm.c @@ -543,8 +543,8 @@ mrb_exec_irep_prepare_posthook(mrb_state *mrb, mrb_callinfo *ci, int nregs, mrb_ * * However, if `proc` is a C function, it will be ignored. */ -mrb_value -mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) +static mrb_value +mrb_exec_irep_vm(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) { mrb_callinfo *ci = mrb->c->ci; int keep, nregs; @@ -575,6 +575,29 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t postho return self; } +mrb_value +mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook) +{ + mrb_callinfo *ci = mrb->c->ci; + if (ci->acc >= 0) { + return mrb_exec_irep_vm(mrb, self, p, posthook); + } + else { + mrb_value ret; + if (MRB_PROC_CFUNC_P(p)) { + ret = MRB_PROC_CFUNC(p)(mrb, self); + } + else { + int keep = (ci->argc < 0 ? 1 : ci->argc) + 2 /* receiver + block */; + ret = mrb_top_run(mrb, p, self, keep); + } + if (mrb->exc && mrb->jmp) { + mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); + } + return ret; + } +} + /* 15.3.1.3.4 */ /* 15.3.1.3.44 */ /* @@ -638,7 +661,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } return MRB_METHOD_CFUNC(m)(mrb, self); } - return mrb_exec_irep(mrb, self, MRB_METHOD_PROC(m), NULL); + return mrb_exec_irep_vm(mrb, self, MRB_METHOD_PROC(m), NULL); } static mrb_value @@ -826,7 +849,7 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); mrb->c->ci->stack[2] = mrb_nil_value(); ci->argc = -1; - return mrb_exec_irep(mrb, self, p, NULL); + return mrb_exec_irep_vm(mrb, self, p, NULL); } static struct RBreak* -- cgit v1.2.3