From b210cfa34ea9e0d288d35b3c9b78c98d33f25dae Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 10 Jan 2021 10:00:26 +0900 Subject: Use `uint16_t` for `argc` and `acc` of `mrb_callinfo` This is because it is enough to express the range up to (-1..255) or (-3..255). --- include/mruby.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/mruby.h b/include/mruby.h index ccb76ebe4..79eb5e26f 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -155,8 +155,8 @@ typedef struct { struct REnv *env; const mrb_code *pc; /* return address */ const mrb_code *err; /* error position */ - mrb_int argc; - mrb_int acc; + int16_t argc; + int16_t acc; struct RClass *target_class; } mrb_callinfo; -- cgit v1.2.3 From 58e94427377952b0953bcdf2d544c62b0fefd4a6 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 10 Jan 2021 10:20:01 +0900 Subject: Unified `target_class` and `env` of `mrb_callinfo` If there is `env`, `env->c` means `target_class`. --- include/mruby.h | 6 ++- include/mruby/proc.h | 61 +++++++++++++++++++++++++++++ lib/mruby/gem.rb | 4 +- mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 8 ++-- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 4 +- mrbgems/mruby-class-ext/src/class.c | 3 +- mrbgems/mruby-compiler/core/parse.y | 2 +- mrbgems/mruby-compiler/core/y.tab.c | 2 +- mrbgems/mruby-eval/src/eval.c | 10 ++--- mrbgems/mruby-fiber/src/fiber.c | 4 +- mrbgems/mruby-object-ext/src/object.c | 2 +- src/gc.c | 5 +-- src/kernel.c | 3 +- src/proc.c | 10 ++--- src/vm.c | 47 +++++++++++----------- 15 files changed, 116 insertions(+), 55 deletions(-) (limited to 'include') diff --git a/include/mruby.h b/include/mruby.h index 79eb5e26f..9f6dde746 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -152,12 +152,14 @@ typedef struct { mrb_sym mid; const struct RProc *proc; mrb_value *stackent; - struct REnv *env; const mrb_code *pc; /* return address */ const mrb_code *err; /* error position */ int16_t argc; int16_t acc; - struct RClass *target_class; + union { + struct REnv *env; + struct RClass *target_class; + } u; } mrb_callinfo; enum mrb_fiber_state { diff --git a/include/mruby/proc.h b/include/mruby/proc.h index f8681b40b..b4d0927a9 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -136,6 +136,67 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc); +static inline struct RClass * +mrb_vm_ci_target_class(const mrb_callinfo *ci) +{ + if (ci->u.env && ci->u.env->tt == MRB_TT_ENV) { + return ci->u.env->c; + } + else { + return ci->u.target_class; + } +} + +static inline void +mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc) +{ + struct REnv *e = ci->u.env; + if (e) { + if (e->tt == MRB_TT_ENV) { + e->c = tc; + } + else { + ci->u.target_class = tc; + } + } +} + +static inline struct REnv * +mrb_vm_ci_env(const mrb_callinfo *ci) +{ + if (ci->u.env && ci->u.env->tt == MRB_TT_ENV) { + return ci->u.env; + } + else { + return NULL; + } +} + +static inline void +mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +{ + if (ci->u.env) { + if (ci->u.env->tt == MRB_TT_ENV) { + if (e) { + e->c = ci->u.env->c; + ci->u.env = e; + } + else { + ci->u.target_class = ci->u.env->c; + } + } + else { + if (e) { + e->c = ci->u.target_class; + ci->u.env = e; + } + } + } + else { + ci->u.env = e; + } +} + MRB_END_DECL #endif /* MRUBY_PROC_H */ diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index 951a5abde..3f9c1cf46 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -218,8 +218,8 @@ module MRuby f.puts %Q[ mrb_close(mrb);] f.puts %Q[ exit(EXIT_FAILURE);] f.puts %Q[ }] - f.puts %Q[ struct REnv *e = mrb->c->cibase->env;] - f.puts %Q[ mrb->c->cibase->env = NULL;] + f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);] + f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);] f.puts %Q[ mrb_env_unshare(mrb, e);] end f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index b626024d1..12adfc4a6 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -516,8 +516,8 @@ main(int argc, char **argv) } mrb_load_file_cxt(mrb, lfp, cxt); fclose(lfp); - e = mrb->c->cibase->env; - mrb->c->cibase->env = NULL; + e = mrb_vm_ci_env(mrb->c->cibase); + mrb_vm_ci_env_set(mrb->c->cibase, NULL); mrb_env_unshare(mrb, e); mrbc_cleanup_local_variables(mrb, cxt); } @@ -658,8 +658,8 @@ main(int argc, char **argv) mrb_codedump_all(mrb, proc); } /* adjust stack length of toplevel environment */ - if (mrb->c->cibase->env) { - struct REnv *e = mrb->c->cibase->env; + if (mrb->c->cibase->u.env) { + struct REnv *e = mrb_vm_ci_env(mrb->c->cibase); if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) { MRB_ENV_SET_LEN(e, proc->body.irep->nlocals); } diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 43e0b90f3..5c8b631a4 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -333,8 +333,8 @@ main(int argc, char **argv) v = mrb_load_detect_file_cxt(mrb, lfp, c); } fclose(lfp); - e = mrb->c->cibase->env; - mrb->c->cibase->env = NULL; + e = mrb_vm_ci_env(mrb->c->cibase); + mrb_vm_ci_env_set(mrb->c->cibase, NULL); mrb_env_unshare(mrb, e); mrbc_cleanup_local_variables(mrb, c); } diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index b7b5e18f8..39c16fc48 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -1,6 +1,7 @@ #include "mruby.h" #include "mruby/class.h" #include "mruby/string.h" +#include "mruby/proc.h" static mrb_value mrb_mod_name(mrb_state *mrb, mrb_value self) @@ -51,7 +52,7 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self) if (mrb->c->ci->acc < 0) { return mrb_yield_with_class(mrb, blk, argc, argv, self, c); } - mrb->c->ci->target_class = c; + mrb_vm_ci_target_class_set(mrb->c->ci, c); return mrb_yield_cont(mrb, blk, self, argc, argv); } diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index c5d40375c..5b58c902e 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -6783,7 +6783,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) } MRB_PROC_SET_TARGET_CLASS(proc, target); if (mrb->c->ci) { - mrb->c->ci->target_class = target; + mrb_vm_ci_target_class_set(mrb->c->ci, target); } v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep); if (mrb->exc) return mrb_nil_value(); diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index 64a68d03f..c389c19e2 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -12784,7 +12784,7 @@ mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) } MRB_PROC_SET_TARGET_CLASS(proc, target); if (mrb->c->ci) { - mrb->c->ci->target_class = target; + mrb_vm_ci_target_class_set(mrb->c->ci, target); } v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep); if (mrb->exc) return mrb_nil_value(); diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index c7a511fe4..26bc039e1 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -79,19 +79,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi target_class = MRB_PROC_TARGET_CLASS(ci->proc); } if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { - if (ci->env) { - e = ci->env; + if ((e = mrb_vm_ci_env(ci)) != NULL) { + /* do nothing, because e is assigned already */ } else { e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci[1].stackent, target_class); - ci->env = e; + ci->u.env = e; } proc->e.env = e; proc->flags |= MRB_PROC_ENVSET; mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); } proc->upper = ci->proc; - mrb->c->ci->target_class = target_class; + mrb_vm_ci_target_class_set(mrb->c->ci, target_class); /* mrb_codedump_all(mrb, proc); */ mrb_parser_free(p); @@ -157,7 +157,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self) proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv)); mrb_assert(!MRB_PROC_CFUNC_P(proc)); - mrb->c->ci->target_class = mrb_class_ptr(cv); + mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(cv)); return exec_irep(mrb, self, proc); } else { diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 006aed50f..328f43fd9 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -120,7 +120,7 @@ fiber_init(mrb_state *mrb, mrb_value self) /* adjust return callinfo */ ci = c->ci; - ci->target_class = MRB_PROC_TARGET_CLASS(p); + mrb_vm_ci_target_class_set(ci, MRB_PROC_TARGET_CLASS(p)); ci->proc = p; mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); ci->pc = p->body.irep->iseq; @@ -154,7 +154,7 @@ fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len) } /* mark return from context modifying method */ -#define MARK_CONTEXT_MODIFY(c) (c)->ci->target_class = NULL +#define MARK_CONTEXT_MODIFY(c) (c)->ci->u.target_class = NULL static void fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c) diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c index 2d99ce8c2..b636c9823 100644 --- a/mrbgems/mruby-object-ext/src/object.c +++ b/mrbgems/mruby-object-ext/src/object.c @@ -105,7 +105,7 @@ mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) if (mrb->c->ci->acc < 0) { return mrb_yield_with_class(mrb, blk, argc, argv, self, c); } - mrb->c->ci->target_class = c; + mrb_vm_ci_target_class_set(mrb->c->ci, c); return mrb_yield_cont(mrb, blk, self, argc, argv); } diff --git a/src/gc.c b/src/gc.c index eeabc3bf9..73b7838e5 100644 --- a/src/gc.c +++ b/src/gc.c @@ -660,9 +660,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c) /* mark call stack */ if (c->cibase) { for (ci = c->cibase; ci <= c->ci; ci++) { - mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->proc); - mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); + mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class); } } /* mark fibers */ @@ -840,7 +839,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) mrb_callinfo *ce = c->cibase; while (ce <= ci) { - struct REnv *e = ci->env; + struct REnv *e = ci->u.env; if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) { mrb_env_unshare(mrb, e); diff --git a/src/kernel.c b/src/kernel.c index b98e52c42..f14f6af7c 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -176,8 +176,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) if (bidx < 0) return mrb_false_value(); bp = &e->stack[bidx]; } - else if (ci->env) { - e = ci->env; + else if ((e = mrb_vm_ci_env(ci)) != NULL) { /* top-level does not have block slot (always false) */ if (e->stack == mrb->c->stbase) return mrb_false_value(); bidx = env_bidx(e); diff --git a/src/proc.c b/src/proc.c index d58d9d0df..66a8e5d64 100644 --- a/src/proc.c +++ b/src/proc.c @@ -46,7 +46,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) tc = MRB_PROC_TARGET_CLASS(ci->proc); } if (tc == NULL) { - tc = ci->target_class; + tc = mrb_vm_ci_target_class(ci); } p->upper = ci->proc; p->e.target_class = tc; @@ -83,14 +83,14 @@ closure_setup(mrb_state *mrb, struct RProc *p) const struct RProc *up = p->upper; struct REnv *e = NULL; - if (ci && ci->env) { - e = ci->env; + if (ci && (e = mrb_vm_ci_env(ci)) != NULL) { + /* do nothing, because e is assigned already */ } else if (up) { struct RClass *tc = MRB_PROC_TARGET_CLASS(p); e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, mrb->c->stack, tc); - ci->env = e; + ci->u.env = e; if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) { e->mid = MRB_PROC_ENV(up)->mid; } @@ -211,7 +211,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) proc = mrb_obj_value(p); mrb_funcall_with_block(mrb, proc, MRB_SYM(initialize), 0, NULL, proc); if (!MRB_PROC_STRICT_P(p) && - mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].env) { + mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].u.env) { p->flags |= MRB_PROC_ORPHAN; } return proc; diff --git a/src/vm.c b/src/vm.c index 57b38ee39..902cbfffb 100644 --- a/src/vm.c +++ b/src/vm.c @@ -133,7 +133,7 @@ stack_init(mrb_state *mrb) c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ci = c->cibase; - c->ci->target_class = mrb->object_class; + c->ci->u.target_class = mrb->object_class; c->ci->stackent = c->stack; } @@ -144,7 +144,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize if (newbase == oldbase) return; while (ci <= mrb->c->ci) { - struct REnv *e = ci->env; + struct REnv *e = mrb_vm_ci_env(ci); mrb_value *st; if (e && MRB_ENV_ONSTACK_P(e) && @@ -154,7 +154,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize e->stack = newbase + off; } - if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) { + if (ci->proc && MRB_PROC_ENV_P(ci->proc) && e != MRB_PROC_ENV(ci->proc)) { e = MRB_PROC_ENV(ci->proc); if (e && MRB_ENV_ONSTACK_P(e) && @@ -240,7 +240,7 @@ uvenv(mrb_state *mrb, mrb_int up) while (cb <= ci) { if (ci->proc == proc) { - return ci->env; + return mrb_vm_ci_env(ci); } ci--; } @@ -284,9 +284,8 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, ci->pc = pc; ci->argc = argc; ci->acc = acc; - ci->target_class = target_class; + ci->u.target_class = target_class; ci->err = 0; - ci->env = 0; c->stack += push_stacks; return ci; @@ -302,7 +301,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e) if (!MRB_ENV_ONSTACK_P(e)) return; if (e->cxt != mrb->c) return; - if (e == mrb->c->cibase->env) return; /* for mirb */ + if (e == mrb_vm_ci_env(mrb->c->cibase)) return; /* for mirb */ p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); if (len > 0) { stack_copy(p, e->stack, len); @@ -317,7 +316,7 @@ static inline mrb_callinfo* cipop(mrb_state *mrb) { struct mrb_context *c = mrb->c; - struct REnv *env = c->ci->env; + struct REnv *env = mrb_vm_ci_env(c->ci); mrb->c->stack = c->ci->stackent; c->ci--; @@ -573,7 +572,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } ci->mid = name; - ci->target_class = c; + ci->u.target_class = c; regs = mrb->c->stack+1; /* remove first symbol from arguments */ if (ci->argc >= 0) { @@ -609,7 +608,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) if (ci->acc == CI_ACC_DIRECT) { return mrb_yield_with_class(mrb, blk, 1, &self, self, c); } - ci->target_class = c; + ci->u.target_class = c; p = mrb_proc_ptr(blk); ci->proc = p; ci->argc = 1; @@ -1005,7 +1004,7 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta static mrb_bool check_target_class(mrb_state *mrb) { - if (!mrb->c->ci->target_class) { + if (!mrb_vm_ci_target_class(mrb->c->ci)) { mrb_value exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, "no target class or module"); mrb_exc_set(mrb, exc); return FALSE; @@ -1476,11 +1475,11 @@ RETRY_TRY_BLOCK: ci = mrb->c->ci; if (mrb_proc_p(blk)) { struct RProc *p = mrb_proc_ptr(blk); - if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) { + if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) { p->flags |= MRB_PROC_ORPHAN; } } - if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (!ci->u.target_class) { /* return from context modifying method (resume/yield) */ if (ci->acc == CI_ACC_RESUMED) { mrb->jmp = prev_jmp; return recv; @@ -1518,7 +1517,7 @@ RETRY_TRY_BLOCK: /* replace callinfo */ ci = mrb->c->ci; - ci->target_class = MRB_PROC_TARGET_CLASS(m); + ci->u.target_class = MRB_PROC_TARGET_CLASS(m); ci->proc = m; if (MRB_PROC_ENV_P(m)) { ci->mid = MRB_PROC_ENV(m)->mid; @@ -1591,10 +1590,10 @@ RETRY_TRY_BLOCK: goto L_RAISE; } if (target_class->flags & MRB_FL_CLASS_IS_PREPENDED) { - target_class = ci->target_class; + target_class = mrb_vm_ci_target_class(ci); } else if (target_class->tt == MRB_TT_MODULE) { - target_class = ci->target_class; + target_class = mrb_vm_ci_target_class(ci); if (target_class->tt != MRB_TT_ICLASS) { mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]"); mrb_exc_set(mrb, exc); @@ -1659,7 +1658,7 @@ RETRY_TRY_BLOCK: if (mrb->exc) goto L_RAISE; ci = mrb->c->ci; mrb_assert(!mrb_break_p(v)); - if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (!mrb_vm_ci_target_class(ci)) { /* return from context modifying method (resume/yield) */ if (ci->acc == CI_ACC_RESUMED) { mrb->jmp = prev_jmp; return v; @@ -1700,7 +1699,7 @@ RETRY_TRY_BLOCK: mrb_int lv = (b>>0)&0xf; mrb_value *stack; - if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) { + if (mrb->c->ci->mid == 0 || mrb_vm_ci_target_class(mrb->c->ci) == NULL) { mrb_value exc; L_NOSUPER: @@ -1951,7 +1950,7 @@ RETRY_TRY_BLOCK: struct RProc *p = mrb_proc_ptr(blk); if (!MRB_PROC_STRICT_P(p) && - ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) { + ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) { p->flags |= MRB_PROC_ORPHAN; } } @@ -2203,7 +2202,7 @@ RETRY_TRY_BLOCK: mrb_assert(ci == mrb->c->ci); mrb_assert(mrb->exc == NULL); - if (mrb->c->vmexec && !ci->target_class) { + if (mrb->c->vmexec && !mrb_vm_ci_target_class(ci)) { mrb_gc_arena_restore(mrb, ai); mrb->c->vmexec = FALSE; mrb->jmp = prev_jmp; @@ -2780,7 +2779,7 @@ RETRY_TRY_BLOCK: CASE(OP_TCLASS, B) { if (!check_target_class(mrb)) goto L_RAISE; - regs[a] = mrb_obj_value(mrb->c->ci->target_class); + regs[a] = mrb_obj_value(mrb_vm_ci_target_class(mrb->c->ci)); NEXT; } @@ -2788,7 +2787,7 @@ RETRY_TRY_BLOCK: struct RClass *target; if (!check_target_class(mrb)) goto L_RAISE; - target = mrb->c->ci->target_class; + target = mrb_vm_ci_target_class(mrb->c->ci); mrb_alias_method(mrb, target, syms[a], syms[b]); NEXT; } @@ -2796,7 +2795,7 @@ RETRY_TRY_BLOCK: struct RClass *target; if (!check_target_class(mrb)) goto L_RAISE; - target = mrb->c->ci->target_class; + target = mrb_vm_ci_target_class(mrb->c->ci); mrb_undef_method_id(mrb, target, syms[a]); NEXT; } @@ -2884,7 +2883,7 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st return mrb_vm_run(mrb, proc, self, stack_keep); } if (mrb->c->ci == mrb->c->cibase) { - mrb->c->ci->env = NULL; + mrb_vm_ci_env_set(mrb->c->ci, NULL); return mrb_vm_run(mrb, proc, self, stack_keep); } cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); -- cgit v1.2.3 From 16baea06771f38fea810ad1eaf3239086442c258 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 10 Jan 2021 10:36:03 +0900 Subject: Changes `stackent` to `stack` of `mrb_callinfo` This enhances self-containment. Previously `mrb_context::stack` had the current call level stack, but now it owns it. The `mrb_context::stack` field, which is no longer needed, will be removed. --- include/mruby.h | 5 +- mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 2 +- mrbgems/mruby-eval/src/eval.c | 4 +- mrbgems/mruby-fiber/src/fiber.c | 9 ++-- src/class.c | 12 ++--- src/gc.c | 9 ++-- src/kernel.c | 2 +- src/proc.c | 2 +- src/vm.c | 82 ++++++++++++++------------------ 9 files changed, 60 insertions(+), 67 deletions(-) (limited to 'include') diff --git a/include/mruby.h b/include/mruby.h index 9f6dde746..3f78e66c6 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -151,7 +151,7 @@ typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud); typedef struct { mrb_sym mid; const struct RProc *proc; - mrb_value *stackent; + mrb_value *stack; const mrb_code *pc; /* return address */ const mrb_code *err; /* error position */ int16_t argc; @@ -174,8 +174,7 @@ enum mrb_fiber_state { struct mrb_context { struct mrb_context *prev; - mrb_value *stack; /* stack of virtual machine */ - mrb_value *stbase, *stend; + mrb_value *stbase, *stend; /* stack of virtual machine */ mrb_callinfo *ci; mrb_callinfo *cibase, *ciend; diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 12adfc4a6..c31c22bc9 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -683,7 +683,7 @@ main(int argc, char **argv) } p(mrb, result, 1); #ifndef MRB_NO_MIRB_UNDERSCORE - *(mrb->c->stack + 1) = result; + *(mrb->c->ci->stack + 1) = result; #endif } } diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 26bc039e1..368c7892b 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -83,7 +83,7 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi /* do nothing, because e is assigned already */ } else { - e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci[1].stackent, target_class); + e = mrb_env_new(mrb, mrb->c, ci, ci->proc->body.irep->nlocals, ci->stack, target_class); ci->u.env = e; } proc->e.env = e; @@ -115,7 +115,7 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) return ret; } /* clear block */ - mrb->c->stack[1] = mrb_nil_value(); + mrb->c->ci->stack[1] = mrb_nil_value(); return mrb_exec_irep(mrb, self, proc); } diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 328f43fd9..d75f864c1 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -93,7 +93,6 @@ fiber_init(mrb_state *mrb, mrb_value self) } c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value)); c->stend = c->stbase + slen; - c->stack = c->stbase; #ifdef MRB_NAN_BOXING { @@ -110,13 +109,12 @@ fiber_init(mrb_state *mrb, mrb_value self) #endif /* copy receiver from a block */ - c->stack[0] = mrb->c->stack[0]; + c->stbase[0] = mrb->c->ci->stack[0]; /* initialize callinfo stack */ c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + FIBER_CI_INIT_SIZE; c->ci = c->cibase; - c->ci->stackent = c->stack; /* adjust return callinfo */ ci = c->ci; @@ -124,6 +122,7 @@ fiber_init(mrb_state *mrb, mrb_value self) ci->proc = p; mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); ci->pc = p->body.irep->iseq; + ci->stack = c->stbase; ci[1] = ci[0]; c->ci++; /* push dummy callinfo */ @@ -214,7 +213,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)"); } mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */ - b = c->stack+1; + b = c->stbase+1; e = b + len; while (bci--; /* pop dummy callinfo */ } c->cibase->argc = (int)len; - value = c->stack[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; + value = c->stbase[0] = MRB_PROC_ENV(c->cibase->proc)->stack[0]; } else { value = fiber_result(mrb, a, len); diff --git a/src/class.c b/src/class.c index 85a26d343..1c0c0b1a4 100644 --- a/src/class.c +++ b/src/class.c @@ -808,7 +808,7 @@ mrb_get_argc(mrb_state *mrb) mrb_int argc = mrb->c->ci->argc; if (argc < 0) { - struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); + struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]); argc = ARY_LEN(a); } @@ -819,7 +819,7 @@ MRB_API const mrb_value* mrb_get_argv(mrb_state *mrb) { mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->stack + 1; + mrb_value *array_argv = mrb->c->ci->stack + 1; if (argc < 0) { struct RArray *a = mrb_ary_ptr(*array_argv); @@ -832,7 +832,7 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb) { mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->stack + 1; + mrb_value *array_argv = mrb->c->ci->stack + 1; if (argc < 0) { struct RArray *a = mrb_ary_ptr(*array_argv); @@ -887,7 +887,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_int i = 0; va_list ap; mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->stack+1; + mrb_value *array_argv = mrb->c->ci->stack+1; mrb_bool argv_on_stack = argc >= 0; mrb_bool opt = FALSE; mrb_bool opt_skip = TRUE; @@ -1200,10 +1200,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, mrb_value*); if (mrb->c->ci->argc < 0) { - bp = mrb->c->stack + 2; + bp = mrb->c->ci->stack + 2; } else { - bp = mrb->c->stack + mrb->c->ci->argc + 1; + bp = mrb->c->ci->stack + mrb->c->ci->argc + 1; } if (altmode && mrb_nil_p(*bp)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); diff --git a/src/gc.c b/src/gc.c index 73b7838e5..5943a0e3b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -626,11 +626,14 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) size_t e; mrb_value nil; - if (c->stack == NULL) return; - e = c->stack - c->stbase; + if (c->stbase == NULL) return; if (c->ci) { + e = (c->ci->stack ? c->ci->stack - c->stbase : 0); e += ci_nregs(c->ci); } + else { + e = 0; + } if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; istbase[i]; @@ -1001,7 +1004,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) if (!c || c->status == MRB_FIBER_TERMINATED) break; /* mark stack */ - i = c->stack - c->stbase; + i = c->ci->stack - c->stbase; if (c->ci) { i += ci_nregs(c->ci); diff --git a/src/kernel.c b/src/kernel.c index f14f6af7c..36ed0c121 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -185,7 +185,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) bp = &e->stack[bidx]; } else { - bp = ci[1].stackent+1; + bp = ci->stack+1; if (ci->argc >= 0) { bp += ci->argc; } diff --git a/src/proc.c b/src/proc.c index 66a8e5d64..2b07003be 100644 --- a/src/proc.c +++ b/src/proc.c @@ -89,7 +89,7 @@ closure_setup(mrb_state *mrb, struct RProc *p) else if (up) { struct RClass *tc = MRB_PROC_TARGET_CLASS(p); - e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, mrb->c->stack, tc); + e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, ci->stack, tc); ci->u.env = e; if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) { e->mid = MRB_PROC_ENV(up)->mid; diff --git a/src/vm.c b/src/vm.c index 902cbfffb..7a2ec29d7 100644 --- a/src/vm.c +++ b/src/vm.c @@ -127,14 +127,13 @@ stack_init(mrb_state *mrb) /* mrb_assert(mrb->stack == NULL); */ c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); c->stend = c->stbase + STACK_INIT_SIZE; - c->stack = c->stbase; /* mrb_assert(ci == NULL); */ c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ci = c->cibase; c->ci->u.target_class = mrb->object_class; - c->ci->stackent = c->stack; + c->ci->stack = c->stbase; } static inline void @@ -165,7 +164,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize } } - ci->stackent = newbase + (ci->stackent - oldbase); + ci->stack = newbase + (ci->stack - oldbase); ci++; } } @@ -179,7 +178,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) mrb_value *newstack; size_t oldsize = mrb->c->stend - mrb->c->stbase; size_t size = oldsize; - size_t off = mrb->c->stack - mrb->c->stbase; + size_t off = mrb->c->ci->stack ? mrb->c->stend - mrb->c->ci->stack : 0; if (off > size) size = off; #ifdef MRB_STACK_EXTEND_DOUBLING @@ -204,7 +203,6 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) stack_clear(&(newstack[oldsize]), size - oldsize); envadjust(mrb, oldbase, newstack, oldsize); mrb->c->stbase = newstack; - mrb->c->stack = mrb->c->stbase + off; mrb->c->stend = mrb->c->stbase + size; /* Raise an exception if the new stack size will be too large, @@ -217,7 +215,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) MRB_API void mrb_stack_extend(mrb_state *mrb, mrb_int room) { - if (mrb->c->stack + room >= mrb->c->stend) { + if (!mrb->c->ci->stack || mrb->c->ci->stack + room >= mrb->c->stend) { stack_extend_alloc(mrb, room); } } @@ -280,13 +278,12 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, ci = ++c->ci; ci->mid = mid; ci->proc = proc; - ci->stackent = c->stack; + ci->stack = ci[-1].stack + push_stacks; ci->pc = pc; ci->argc = argc; ci->acc = acc; ci->u.target_class = target_class; ci->err = 0; - c->stack += push_stacks; return ci; } @@ -318,7 +315,6 @@ cipop(mrb_state *mrb) struct mrb_context *c = mrb->c; struct REnv *env = mrb_vm_ci_env(c->ci); - mrb->c->stack = c->ci->stackent; c->ci--; if (env) mrb_env_unshare(mrb, env); return c->ci; @@ -427,7 +423,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb_int n = ci_nregs(mrb->c->ci); ptrdiff_t voff = -1; - if (!mrb->c->stack) { + if (!mrb->c->stbase) { stack_init(mrb); } if (argc < 0) { @@ -444,7 +440,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc } mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); mrb_stack_extend(mrb, n+2); - mrb->c->stack[n+1] = args; + mrb->c->ci->stack[n+1] = args; argc = -1; } if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { @@ -458,7 +454,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (argc >= CALL_MAXARGS) { mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - mrb->c->stack[1] = args; + mrb->c->ci->stack[1] = args; ci->argc = -1; argc = 1; } @@ -474,11 +470,11 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (voff >= 0) { argv = mrb->c->stbase + voff; } - mrb->c->stack[0] = self; + mrb->c->ci->stack[0] = self; if (ci->argc > 0) { - stack_copy(mrb->c->stack+1, argv, argc); + stack_copy(mrb->c->ci->stack+1, argv, argc); } - mrb->c->stack[argc+1] = blk; + mrb->c->ci->stack[argc+1] = blk; if (MRB_METHOD_CFUNC_P(m)) { ci->acc = CI_ACC_DIRECT; @@ -507,7 +503,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) mrb_callinfo *ci = mrb->c->ci; mrb_int keep, nregs; - mrb->c->stack[0] = self; + mrb->c->ci->stack[0] = self; ci->proc = p; if (MRB_PROC_CFUNC_P(p)) { return MRB_PROC_CFUNC(p)(mrb, self); @@ -520,7 +516,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) } else { mrb_stack_extend(mrb, nregs); - stack_clear(mrb->c->stack+keep, nregs-keep); + stack_clear(mrb->c->ci->stack+keep, nregs-keep); } cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); @@ -573,7 +569,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) ci->mid = name; ci->u.target_class = c; - regs = mrb->c->stack+1; + regs = mrb->c->ci->stack+1; /* remove first symbol from arguments */ if (ci->argc >= 0) { for (i=0,len=ci->argc; imid = ci[-1].mid; if (MRB_PROC_CFUNC_P(p)) { mrb_stack_extend(mrb, 3); - mrb->c->stack[0] = self; - mrb->c->stack[1] = self; - mrb->c->stack[2] = mrb_nil_value(); + mrb->c->ci->stack[0] = self; + mrb->c->ci->stack[1] = self; + mrb->c->ci->stack[2] = mrb_nil_value(); return MRB_PROC_CFUNC(p)(mrb, self); } nregs = p->body.irep->nregs; if (nregs < 3) nregs = 3; mrb_stack_extend(mrb, nregs); - mrb->c->stack[0] = self; - mrb->c->stack[1] = self; - stack_clear(mrb->c->stack+2, nregs-2); + mrb->c->ci->stack[0] = self; + mrb->c->ci->stack[1] = self; + stack_clear(mrb->c->ci->stack+2, nregs-2); ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); return self; @@ -712,15 +708,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value n = argc + 2; } mrb_stack_extend(mrb, n); - mrb->c->stack[0] = self; + mrb->c->ci->stack[0] = self; if (ci->argc < 0) { - mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); + mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); argc = 1; } else if (argc > 0) { - stack_copy(mrb->c->stack+1, argv, argc); + stack_copy(mrb->c->ci->stack+1, argv, argc); } - mrb->c->stack[argc+1] = mrb_nil_value(); + mrb->c->ci->stack[argc+1] = mrb_nil_value(); if (MRB_PROC_CFUNC_P(p)) { val = MRB_PROC_CFUNC(p)(mrb, self); @@ -765,8 +761,8 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const ci = mrb->c->ci; mrb_stack_extend(mrb, 3); - mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); - mrb->c->stack[2] = mrb_nil_value(); + 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); } @@ -852,7 +848,7 @@ argnum_error(mrb_state *mrb, mrb_int num) mrb_int argc = mrb->c->ci->argc; if (argc < 0) { - mrb_value args = mrb->c->stack[1]; + mrb_value args = mrb->c->ci->stack[1]; if (mrb_array_p(args)) { argc = RARRAY_LEN(args); } @@ -980,14 +976,14 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta ptrdiff_t cioff = c->ci - c->cibase; mrb_int nregs = irep->nregs; - if (!c->stack) { + if (!c->stbase) { stack_init(mrb); } if (stack_keep > nregs) nregs = stack_keep; mrb_stack_extend(mrb, nregs); - stack_clear(c->stack + stack_keep, nregs - stack_keep); - c->stack[0] = self; + stack_clear(c->ci->stack + stack_keep, nregs - stack_keep); + c->ci->stack[0] = self; result = mrb_vm_exec(mrb, proc, irep->iseq); if (mrb->c != c) { if (mrb->c->fib) { @@ -1056,7 +1052,7 @@ RETRY_TRY_BLOCK: mrb->jmp = &c_jmp; mrb->c->ci->proc = proc; -#define regs (mrb->c->stack) +#define regs (mrb->c->ci->stack) INIT_DISPATCH { CASE(OP_NOP, Z) { /* do nothing */ @@ -1492,7 +1488,7 @@ RETRY_TRY_BLOCK: syms = irep->syms; } } - mrb->c->stack[0] = recv; + mrb->c->ci->stack[0] = recv; /* pop stackpos */ pc = ci->pc; cipop(mrb); @@ -1512,7 +1508,7 @@ RETRY_TRY_BLOCK: CASE(OP_CALL, Z) { mrb_callinfo *ci; - mrb_value recv = mrb->c->stack[0]; + mrb_value recv = mrb->c->ci->stack[0]; struct RProc *m = mrb_proc_ptr(recv); /* replace callinfo */ @@ -1544,7 +1540,7 @@ RETRY_TRY_BLOCK: proc = m; irep = m->body.irep; if (!irep) { - mrb->c->stack[0] = mrb_nil_value(); + mrb->c->ci->stack[0] = mrb_nil_value(); a = 0; c = OP_R_NORMAL; goto L_RETURN; @@ -1645,7 +1641,7 @@ RETRY_TRY_BLOCK: ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc); /* prepare stack */ - mrb->c->stack[0] = recv; + mrb->c->ci->stack[0] = recv; if (MRB_METHOD_CFUNC_P(m)) { mrb_value v; @@ -1671,7 +1667,7 @@ RETRY_TRY_BLOCK: syms = irep->syms; } } - mrb->c->stack[0] = v; + mrb->c->ci->stack[0] = v; pc = ci->pc; cipop(mrb); JUMP; @@ -1978,7 +1974,7 @@ RETRY_TRY_BLOCK: if (ch == NULL) { L_FTOP: /* fiber top */ if (mrb->c == mrb->root_c) { - mrb->c->stack = mrb->c->stbase; + mrb->c->ci->stack = mrb->c->stbase; goto L_STOP; } else { @@ -2003,9 +1999,6 @@ RETRY_TRY_BLOCK: irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - if (ci < ci0) { - mrb->c->stack = ci[1].stackent; - } mrb_stack_extend(mrb, irep->nregs); pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); } @@ -2168,7 +2161,6 @@ RETRY_TRY_BLOCK: mrb_assert(!"wrong break tag"); } } - mrb->c->stack = ci->stackent; while (mrb->c->cibase < ci && ci[-1].proc != proc->upper) { if (ci[-1].acc == CI_ACC_SKIP) { goto L_BREAK_ERROR; -- cgit v1.2.3 From ced89c25ffc9ac748dc2dd336cce24d080ebf419 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 10 Jan 2021 10:50:22 +0900 Subject: Unified `pc` and `err` of `mrb_callinfo` This enhances self-containment. - Changed the `mrb_callinfo::pc` field to point to itself. Previously it indicated the return destination of the previous call level. `mrb_callinfo::pc` will now hold the address to its own `proc->body.irep->iseq`. - Removed `mrb_callinfo::err` field. This is because `mrb_callinfo::pc - 1` is semantically the same as the previous `err`. - The `pc0` and `pc_save` variables in `mrb_vm_exec()` are no longer needed and have been deleted. - It removes the argument because `cipush()` doesn't need to save the previous `pc`. --- include/mruby.h | 3 +- include/mruby/proc.h | 7 ++++ mrbgems/mruby-fiber/src/fiber.c | 3 +- src/backtrace.c | 16 ++++----- src/vm.c | 77 ++++++++++++++++------------------------- 5 files changed, 45 insertions(+), 61 deletions(-) (limited to 'include') diff --git a/include/mruby.h b/include/mruby.h index 3f78e66c6..b54e4f98e 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -152,8 +152,7 @@ typedef struct { mrb_sym mid; const struct RProc *proc; mrb_value *stack; - const mrb_code *pc; /* return address */ - const mrb_code *err; /* error position */ + const mrb_code *pc; /* current address on iseq of this proc */ int16_t argc; int16_t acc; union { diff --git a/include/mruby/proc.h b/include/mruby/proc.h index b4d0927a9..be45a06d8 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -136,6 +136,13 @@ MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx); MRB_API mrb_value mrb_load_proc(mrb_state *mrb, const struct RProc *proc); +static inline void +mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p) +{ + ci->proc = p; + ci->pc = (p && !MRB_PROC_CFUNC_P(p)) ? p->body.irep->iseq : NULL; +} + static inline struct RClass * mrb_vm_ci_target_class(const mrb_callinfo *ci) { diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index d75f864c1..7fd755843 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -119,9 +119,8 @@ fiber_init(mrb_state *mrb, mrb_value self) /* adjust return callinfo */ ci = c->ci; mrb_vm_ci_target_class_set(ci, MRB_PROC_TARGET_CLASS(p)); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); - ci->pc = p->body.irep->iseq; ci->stack = c->stbase; ci[1] = ci[0]; c->ci++; /* push dummy callinfo */ diff --git a/src/backtrace.c b/src/backtrace.c index 1006f2f86..508fe99e9 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -29,7 +29,7 @@ mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); static void -each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data) +each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) { ptrdiff_t i; @@ -50,15 +50,11 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr irep = ci->proc->body.irep; if (!irep) continue; - if (mrb->c->cibase[i].err) { - pc = mrb->c->cibase[i].err; - } - else if (i+1 <= ciidx) { - if (!mrb->c->cibase[i + 1].pc) continue; - pc = &mrb->c->cibase[i+1].pc[-1]; + if (mrb->c->cibase[i].pc) { + pc = &mrb->c->cibase[i].pc[-1]; } else { - pc = pc0; + continue; } loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq); @@ -159,12 +155,12 @@ packed_backtrace(mrb_state *mrb) int size; void *ptr; - each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len); + each_backtrace(mrb, ciidx, count_backtrace_i, &len); size = len * sizeof(struct backtrace_location); ptr = mrb_malloc(mrb, size); backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); backtrace->flags = (uint32_t)len; - each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr); + each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); return mrb_obj_value(backtrace); } diff --git a/src/vm.c b/src/vm.c index 7a2ec29d7..bbe812997 100644 --- a/src/vm.c +++ b/src/vm.c @@ -262,7 +262,7 @@ top_proc(mrb_state *mrb, const struct RProc *proc) #define CI_ACC_RESUMED -3 static inline mrb_callinfo* -cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, +cipush(mrb_state *mrb, mrb_int push_stacks, mrb_int acc, struct RClass *target_class, const struct RProc *proc, mrb_sym mid, mrb_int argc) { struct mrb_context *c = mrb->c; @@ -277,13 +277,11 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, } ci = ++c->ci; ci->mid = mid; - ci->proc = proc; + mrb_vm_ci_proc_set(ci, proc); ci->stack = ci[-1].stack + push_stacks; - ci->pc = pc; ci->argc = argc; ci->acc = acc; ci->u.target_class = target_class; - ci->err = 0; return ci; } @@ -446,7 +444,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } - ci = cipush(mrb, NULL, n, 0, c, NULL, mid, argc); + ci = cipush(mrb, n, 0, c, NULL, mid, argc); if (argc < 0) argc = 1; if (mrb->c->stbase <= argv && argv < mrb->c->stend) { voff = argv - mrb->c->stbase; @@ -462,7 +460,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); if (!MRB_PROC_CFUNC_P(p)) { mrb_stack_extend(mrb, p->body.irep->nregs + argc); } @@ -504,7 +502,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) mrb_int keep, nregs; mrb->c->ci->stack[0] = self; - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); if (MRB_PROC_CFUNC_P(p)) { return MRB_PROC_CFUNC(p)(mrb, self); } @@ -519,7 +517,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) stack_clear(mrb->c->ci->stack+keep, nregs-keep); } - cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); + cipush(mrb, 0, 0, NULL, NULL, 0, 0); return self; } @@ -583,7 +581,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { - ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m)); } return MRB_METHOD_CFUNC(m)(mrb, self); } @@ -606,7 +604,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) } ci->u.target_class = c; p = mrb_proc_ptr(blk); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); ci->argc = 1; ci->mid = ci[-1].mid; if (MRB_PROC_CFUNC_P(p)) { @@ -622,7 +620,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) mrb->c->ci->stack[0] = self; mrb->c->ci->stack[1] = self; stack_clear(mrb->c->ci->stack+2, nregs-2); - ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); + ci = cipush(mrb, 0, 0, NULL, NULL, 0, 0); return self; } @@ -698,7 +696,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } p = mrb_proc_ptr(b); - ci = cipush(mrb, NULL, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */); + ci = cipush(mrb, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */); if (argc >= CALL_MAXARGS) { ci->argc = -1; n = 3; @@ -928,8 +926,6 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb } while (0); \ } while (0) -#define ERR_PC_SET(mrb) mrb->c->ci->err = pc0; -#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; #ifdef MRB_USE_DEBUG_HOOK #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); #else @@ -951,7 +947,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #ifndef DIRECT_THREADED #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { -#define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops (); pc_save = pc; +#define CASE(insn,ops) case insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; #define NEXT goto L_END_DISPATCH #define JUMP NEXT #define END_DISPATCH L_END_DISPATCH:;}} @@ -959,7 +955,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #else #define INIT_DISPATCH JUMP; return mrb_nil_value(); -#define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); pc_save = pc; +#define CASE(insn,ops) L_ ## insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; #define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn] #define JUMP NEXT @@ -1014,8 +1010,6 @@ MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) { /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */ - const mrb_code *pc0 = pc; - const mrb_code *volatile pc_save = pc; const mrb_irep *irep = proc->body.irep; const mrb_pool_value *pool = irep->pool; const mrb_sym *syms = irep->syms; @@ -1050,7 +1044,7 @@ RETRY_TRY_BLOCK: goto L_RAISE; } mrb->jmp = &c_jmp; - mrb->c->ci->proc = proc; + mrb_vm_ci_proc_set(mrb->c->ci, proc); #define regs (mrb->c->ci->stack) INIT_DISPATCH { @@ -1197,9 +1191,7 @@ RETRY_TRY_BLOCK: CASE(OP_GETCV, BB) { mrb_value val; - ERR_PC_SET(mrb); val = mrb_vm_cv_get(mrb, syms[b]); - ERR_PC_CLR(mrb); regs[a] = val; NEXT; } @@ -1213,9 +1205,7 @@ RETRY_TRY_BLOCK: mrb_value val; mrb_sym sym = syms[b]; - ERR_PC_SET(mrb); val = mrb_vm_const_get(mrb, sym); - ERR_PC_CLR(mrb); regs[a] = val; NEXT; } @@ -1228,9 +1218,7 @@ RETRY_TRY_BLOCK: CASE(OP_GETMCNST, BB) { mrb_value val; - ERR_PC_SET(mrb); val = mrb_const_get(mrb, regs[a], syms[b]); - ERR_PC_CLR(mrb); regs[a] = val; NEXT; } @@ -1432,7 +1420,6 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &cls, missing); if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1); - ERR_PC_SET(mrb); mrb_method_missing(mrb, mid, recv, args); } if (argc >= 0) { @@ -1448,13 +1435,13 @@ RETRY_TRY_BLOCK: } /* push callinfo */ - ci = cipush(mrb, pc, a, a, cls, NULL, mid, argc); + ci = cipush(mrb, a, a, cls, NULL, mid, argc); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); recv = p->body.func(mrb, recv); } else if (MRB_METHOD_NOARG_P(m) && @@ -1490,13 +1477,13 @@ RETRY_TRY_BLOCK: } mrb->c->ci->stack[0] = recv; /* pop stackpos */ + ci = cipop(mrb); pc = ci->pc; - cipop(mrb); JUMP; } else { /* setup environment for calling method */ - proc = ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m))); irep = proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1514,7 +1501,7 @@ RETRY_TRY_BLOCK: /* replace callinfo */ ci = mrb->c->ci; ci->u.target_class = MRB_PROC_TARGET_CLASS(m); - ci->proc = m; + mrb_vm_ci_proc_set(ci, m); if (MRB_PROC_ENV_P(m)) { ci->mid = MRB_PROC_ENV(m)->mid; } @@ -1526,9 +1513,8 @@ RETRY_TRY_BLOCK: mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; /* pop stackpos */ - ci = mrb->c->ci; + ci = cipop(mrb); pc = ci->pc; - cipop(mrb); regs[ci->acc] = recv; irep = mrb->c->ci->proc->body.irep; pool = irep->pool; @@ -1622,7 +1608,6 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &cls, missing); if (MRB_METHOD_UNDEF_P(m)) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); - ERR_PC_SET(mrb); mrb_method_missing(mrb, mid, recv, args); } mid = missing; @@ -1638,7 +1623,7 @@ RETRY_TRY_BLOCK: } /* push callinfo */ - ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc); + ci = cipush(mrb, a, 0, cls, NULL, mid, argc); /* prepare stack */ mrb->c->ci->stack[0] = recv; @@ -1647,7 +1632,7 @@ RETRY_TRY_BLOCK: mrb_value v; if (MRB_METHOD_PROC_P(m)) { - ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m)); } v = MRB_METHOD_CFUNC(m)(mrb, recv); mrb_gc_arena_restore(mrb, ai); @@ -1668,8 +1653,8 @@ RETRY_TRY_BLOCK: } } mrb->c->ci->stack[0] = v; + ci = cipop(mrb); pc = ci->pc; - cipop(mrb); JUMP; } else { @@ -1677,7 +1662,7 @@ RETRY_TRY_BLOCK: ci->acc = a; /* setup environment for calling method */ - proc = ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m))); irep = proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1968,7 +1953,7 @@ RETRY_TRY_BLOCK: mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } - pc = ci[1].pc; + pc = ci[0].pc; if (ci == mrb->c->cibase) { ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL); if (ch == NULL) { @@ -2048,8 +2033,8 @@ RETRY_TRY_BLOCK: UNWIND_ENSURE(mrb, ci, pc, RBREAK_TAG_RETURN_BLOCK, proc, v); } CHECKPOINT_END(RBREAK_TAG_RETURN_BLOCK); - pc = ci->pc; ci = cipop(mrb); + pc = ci->pc; } proc = ci->proc; mrb->exc = NULL; /* clear break object */ @@ -2172,8 +2157,8 @@ RETRY_TRY_BLOCK: UNWIND_ENSURE(mrb, ci, pc, RBREAK_TAG_BREAK_UPPER, proc, v); } CHECKPOINT_END(RBREAK_TAG_BREAK_UPPER); - pc = ci->pc; ci = cipop(mrb); + pc = ci->pc; } CHECKPOINT_RESTORE(RBREAK_TAG_BREAK_INTARGET) { /* do nothing */ @@ -2207,7 +2192,7 @@ RETRY_TRY_BLOCK: mrb->jmp = prev_jmp; return v; } - pc = ci[1].pc; + pc = ci[0].pc; DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); proc = mrb->c->ci->proc; irep = proc->body.irep; @@ -2741,7 +2726,7 @@ RETRY_TRY_BLOCK: p->flags |= MRB_PROC_SCOPE; /* prepare call stack */ - cipush(mrb, pc, a, a, mrb_class_ptr(recv), p, 0, 0); + cipush(mrb, a, a, mrb_class_ptr(recv), p, 0, 0); irep = p->body.irep; pool = irep->pool; @@ -2812,7 +2797,6 @@ RETRY_TRY_BLOCK: mrb_assert((pool[a].tt&IREP_TT_NFLAG)==0); exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, pool[a].u.str, len); - ERR_PC_SET(mrb); mrb_exc_set(mrb, exc); goto L_RAISE; } @@ -2831,7 +2815,6 @@ RETRY_TRY_BLOCK: } CHECKPOINT_END(RBREAK_TAG_STOP); L_STOP: - ERR_PC_CLR(mrb); mrb->jmp = prev_jmp; if (mrb->exc) { mrb_assert(mrb->exc->tt == MRB_TT_EXCEPTION); @@ -2849,7 +2832,7 @@ RETRY_TRY_BLOCK: ci = cipop(mrb); } exc_catched = TRUE; - pc = pc_save; + pc = ci->pc; goto RETRY_TRY_BLOCK; } MRB_END_EXC(&c_jmp); @@ -2878,7 +2861,7 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st mrb_vm_ci_env_set(mrb->c->ci, NULL); return mrb_vm_run(mrb, proc, self, stack_keep); } - cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); + cipush(mrb, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); v = mrb_vm_run(mrb, proc, self, stack_keep); return v; -- cgit v1.2.3