summaryrefslogtreecommitdiffhomepage
path: root/src/variable.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-09-04 06:51:31 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-09-04 06:51:31 +0900
commit3acaa44a70a44a816076dee65310f0f2487aeebd (patch)
treedb7b29708bd51a1521d2695d0debdf562101d99a /src/variable.c
parent8a5d783f2ee5ddccdb2b8de2edf5dc6b5ba1c3fc (diff)
downloadmruby-3acaa44a70a44a816076dee65310f0f2487aeebd.tar.gz
mruby-3acaa44a70a44a816076dee65310f0f2487aeebd.zip
Restructure `irep->outer` chain; fix #3804
Instead of `irep -> proc` chain, we use `irep -> irep` chain to avoid GC bugs like #3804. We added `target_class` reference to `mrb_irep` struct. That means one more word consumption per `irep`.
Diffstat (limited to 'src/variable.c')
-rw-r--r--src/variable.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/src/variable.c b/src/variable.c
index 96ae7ea25..50fc70682 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -702,7 +702,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
struct RClass *c = mrb->c->ci->proc->target_class;
struct RClass *c2;
mrb_value v;
- struct RProc *proc;
+ mrb_irep *irep;
if (!c) c = mrb->c->ci->target_class;
mrb_assert(c != NULL);
@@ -719,16 +719,15 @@ 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));
- proc = mrb->c->ci->proc->body.irep->outer;
- while (proc && proc->tt == MRB_TT_PROC) {
- mrb_assert(!MRB_PROC_CFUNC_P(proc));
- if (MRB_PROC_CLASS_P(proc) && proc->target_class) {
- c2 = proc->target_class;
+ 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 = proc->body.irep->outer;
+ irep = irep->outer;
}
return const_get(mrb, c, sym);
}