diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-08-01 15:57:32 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-08-01 15:57:32 +0900 |
| commit | 3f6a098626d95ef59f566dad4afbef83249e9334 (patch) | |
| tree | 0bc3d741f49e152100f9276e72af08b475a4a745 /src/variable.c | |
| parent | 9e10afe1d0ee1fb751182e42044e891b4b13f9a4 (diff) | |
| download | mruby-3f6a098626d95ef59f566dad4afbef83249e9334.tar.gz mruby-3f6a098626d95ef59f566dad4afbef83249e9334.zip | |
Reimplement constant look-up rule to follow lexical scoping.
This update fix CRuby scoping incompatibility; close #600; close #3200
Diffstat (limited to 'src/variable.c')
| -rw-r--r-- | src/variable.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/variable.c b/src/variable.c index 86ac32e61..9f4b2e728 100644 --- a/src/variable.c +++ b/src/variable.c @@ -833,31 +833,35 @@ mrb_value 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; if (!c) c = mrb->c->ci->target_class; - if (c) { - struct RClass *c2; - mrb_value v; + mrb_assert(c != NULL); - if (c->iv && iv_get(mrb, c->iv, sym, &v)) { - return v; - } - c2 = c; - while (c2 && c2->tt == MRB_TT_SCLASS) { - mrb_value klass; - klass = mrb_obj_iv_get(mrb, (struct RObject *)c2, - mrb_intern_lit(mrb, "__attached__")); - c2 = mrb_class_ptr(klass); - } - if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2; - c2 = c; - for (;;) { - c2 = mrb_class_outer_module(mrb, c2); - if (!c2) break; + if (c->iv && iv_get(mrb, c->iv, sym, &v)) { + return v; + } + c2 = c; + while (c2 && c2->tt == MRB_TT_SCLASS) { + mrb_value klass; + klass = mrb_obj_iv_get(mrb, (struct RObject *)c2, + mrb_intern_lit(mrb, "__attached__")); + c2 = mrb_class_ptr(klass); + } + 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) { + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + if (MRB_PROC_CLASS_P(proc) && proc->target_class) { + c2 = proc->target_class; if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) { return v; } } + proc = proc->body.irep->outer; } return const_get(mrb, c, sym); } |
