diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-10-28 21:09:25 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-10-28 23:08:31 +0900 |
| commit | c7c9543bed57db12fd8aa57391e0b652ee27cb23 (patch) | |
| tree | 0d86333105b620e7ed735a58708f193c03f6befd /src | |
| parent | 57dad6e3fd1a670702bd252be07d2999b6b5735d (diff) | |
| download | mruby-c7c9543bed57db12fd8aa57391e0b652ee27cb23.tar.gz mruby-c7c9543bed57db12fd8aa57391e0b652ee27cb23.zip | |
Fixed UPVAR gotchas; fix #3835
Both `uvenv` function and `env` generation in `create_proc_from_string`
function have bugs to handling enclosed environment objects.
Diffstat (limited to 'src')
| -rw-r--r-- | src/vm.c | 21 |
1 files changed, 16 insertions, 5 deletions
@@ -217,13 +217,24 @@ uvenv(mrb_state *mrb, int up) struct RProc *proc = mrb->c->ci->proc; struct REnv *e; - do { - e = MRB_PROC_ENV(proc); - if (!e) return NULL; + while (up--) { proc = proc->upper; if (!proc) return NULL; - } while (up--); - return e; + } + e = MRB_PROC_ENV(proc); + if (e) return e; /* proc has enclosed env */ + else { + mrb_callinfo *ci = mrb->c->ci; + mrb_callinfo *cb = mrb->c->cibase; + + while (cb <= ci) { + if (ci->proc == proc) { + return ci->env; + } + ci--; + } + } + return NULL; } static inline struct RProc* |
