From 93f5f225772c398be6e409da3d3ef0f07ffbe1cf Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 26 Oct 2017 01:13:57 +0900 Subject: Heavily refactored how lexical scope links are implemented; fix #3821 Instead of `irep` links, we added a `upper` link to `struct RProc`. To make a space for the `upper` link, we moved `target_class` reference. If a `Proc` does not have `env`, `target_class` is saved in an `union` shared with `env` (if a `Proc` has env, you can tell it by `MRB_PROC_ENV_P()). Otherwise `target_class` is referenced from `env->c`. We removed links in `env` as well. This change removes 2 members from `mrb_irep` struct, thus saving 2 words per method/proc/block. This also fixes potential memory leaks due to the circular references caused by a link from `mrb_irep`. --- src/variable.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'src/variable.c') diff --git a/src/variable.c b/src/variable.c index 4fbe82dd9..3e84c573c 100644 --- a/src/variable.c +++ b/src/variable.c @@ -632,18 +632,19 @@ mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym) mrb_value mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) { - struct RClass *c = mrb->c->ci->proc->target_class; + struct RClass *c; + c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); if (!c) c = mrb->c->ci->target_class; - return mrb_mod_cv_get(mrb, c, sym); } void mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) { - struct RClass *c = mrb->c->ci->proc->target_class; + struct RClass *c; + c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); if (!c) c = mrb->c->ci->target_class; mrb_mod_cv_set(mrb, c, sym, v); } @@ -700,11 +701,12 @@ mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) mrb_value mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) { - struct RClass *c = mrb->c->ci->proc->target_class; + struct RClass *c; struct RClass *c2; mrb_value v; - mrb_irep *irep; + struct RProc *proc; + c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); if (!c) c = mrb->c->ci->target_class; mrb_assert(c != NULL); @@ -720,15 +722,13 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) } if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2; mrb_assert(!MRB_PROC_CFUNC_P(mrb->c->ci->proc)); - irep = mrb->c->ci->proc->body.irep; - while (irep) { - if (irep->target_class) { - c2 = irep->target_class; - if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) { - return v; - } + proc = mrb->c->ci->proc; + while (proc) { + c2 = MRB_PROC_TARGET_CLASS(proc); + if (c2 && c2->iv && iv_get(mrb, c2->iv, sym, &v)) { + return v; } - irep = irep->outer; + proc = proc->upper; } return const_get(mrb, c, sym, TRUE); } @@ -746,9 +746,7 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) void mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) { - struct RClass *c = mrb->c->ci->proc->target_class; - - if (!c) c = mrb->c->ci->target_class; + struct RClass *c = mrb->c->ci->target_class; mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v); } -- cgit v1.2.3