summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authordearblue <[email protected]>2021-04-03 21:17:48 +0900
committerdearblue <[email protected]>2021-04-03 21:17:48 +0900
commitdd34ac647fb5d6842941b3529d1452797862cc23 (patch)
tree028bee4037cc4050c9ddafd432d70ee02315ef9e
parentfb8e12f37c86cfbdc6a8c4fa3b327bae24a8ce27 (diff)
downloadmruby-dd34ac647fb5d6842941b3529d1452797862cc23.tar.gz
mruby-dd34ac647fb5d6842941b3529d1452797862cc23.zip
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()`.
-rw-r--r--mrbgems/mruby-eval/src/eval.c9
-rw-r--r--src/vm.c31
2 files changed, 27 insertions, 13 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index 978d4fc30..508f5ffcb 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -131,15 +131,6 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc, mrb_func_t posthoo
{
/* no argument passed from eval() */
mrb->c->ci->argc = 0;
- if (mrb->c->ci->acc < 0) {
- ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase;
- mrb_value ret = mrb_top_run(mrb, proc, self, 0);
- if (mrb->exc) {
- mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
- }
- mrb->c->ci = mrb->c->cibase + cioff;
- return ret;
- }
/* clear block */
mrb->c->ci->stack[1] = mrb_nil_value();
return mrb_exec_irep(mrb, self, proc, posthook);
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*