diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-09-04 06:51:31 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-09-04 06:51:31 +0900 |
| commit | 3acaa44a70a44a816076dee65310f0f2487aeebd (patch) | |
| tree | db7b29708bd51a1521d2695d0debdf562101d99a /src/variable.c | |
| parent | 8a5d783f2ee5ddccdb2b8de2edf5dc6b5ba1c3fc (diff) | |
| download | mruby-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.c | 13 |
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); } |
