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/kernel.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/kernel.c')
| -rw-r--r-- | src/kernel.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/src/kernel.c b/src/kernel.c index 9fcee2413..4e95ab24b 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1151,8 +1151,8 @@ static mrb_value mrb_local_variables(mrb_state *mrb, mrb_value self) { struct RProc *proc; + mrb_irep *irep; mrb_value vars; - struct mrb_irep *irep; size_t i; proc = mrb->c->ci[-1].proc; @@ -1161,18 +1161,16 @@ mrb_local_variables(mrb_state *mrb, mrb_value self) return mrb_ary_new(mrb); } vars = mrb_hash_new(mrb); - while (proc) { - if (MRB_PROC_CFUNC_P(proc)) break; - irep = proc->body.irep; + irep = proc->body.irep; + while (irep) { if (!irep->lv) break; for (i = 0; i + 1 < irep->nlocals; ++i) { if (irep->lv[i].name) { mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value()); } } - if (MRB_PROC_CLASS_P(proc)) break; if (!proc->env) break; - proc = proc->body.irep->outer; + irep = irep->outer; } return mrb_hash_keys(mrb, vars); |
