mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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`.
This commit is contained in:
+14
-16
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user