diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-04-09 21:46:09 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-04-09 21:46:09 +0900 |
| commit | c2c37e1451d258c13ff160e0fd5f48acfcb1c52f (patch) | |
| tree | 65b679e3f90e68fbba233088625af5b9d2b0e97c /src | |
| parent | 6d3c0227498050d551243417340e704023fcaf42 (diff) | |
| parent | 4c196dcdaaf4127e2ce988fb79f1912c78b9dca8 (diff) | |
| download | mruby-c2c37e1451d258c13ff160e0fd5f48acfcb1c52f.tar.gz mruby-c2c37e1451d258c13ff160e0fd5f48acfcb1c52f.zip | |
Merge pull request #5401 from dearblue/mcall
Reorganize `mcall()` in `mruby-method`
Diffstat (limited to 'src')
| -rw-r--r-- | src/vm.c | 33 |
1 files changed, 29 insertions, 4 deletions
@@ -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,31 @@ 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)) { + cipush(mrb, 0, CI_ACC_DIRECT, mrb_vm_ci_target_class(ci), p, ci->mid, ci->argc); + ret = MRB_PROC_CFUNC(p)(mrb, self); + cipop(mrb); + } + 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 +663,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 +851,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* |
