diff options
| author | Yukihiro Matz Matsumoto <[email protected]> | 2012-11-21 17:00:06 +0900 |
|---|---|---|
| committer | Yukihiro Matz Matsumoto <[email protected]> | 2012-11-21 17:00:06 +0900 |
| commit | 76f0e755e92d845b4b4bac1d77aa5eeb42bbbec9 (patch) | |
| tree | 37e2b0b0dbe4dbbef3959e7661e483fab67b3bbf /src | |
| parent | 1b2257c8ff212d1069b00e11a6b91672c9636ecb (diff) | |
| download | mruby-76f0e755e92d845b4b4bac1d77aa5eeb42bbbec9.tar.gz mruby-76f0e755e92d845b4b4bac1d77aa5eeb42bbbec9.zip | |
handle return from blocks, especially from lambda blocks; close #561
Diffstat (limited to 'src')
| -rw-r--r-- | src/vm.c | 20 |
1 files changed, 17 insertions, 3 deletions
@@ -151,14 +151,27 @@ uvset(mrb_state *mrb, int up, int idx, mrb_value v) mrb_write_barrier(mrb, (struct RBasic*)e); } +static inline int +is_strict(mrb_state *mrb, struct REnv *e) +{ + int cioff = e->cioff; + + if (cioff >= 0 && mrb->cibase[cioff].proc && + MRB_PROC_STRICT_P(mrb->cibase[cioff].proc)) { + return 1; + } + return 0; +} + struct REnv* -top_env(struct RProc *proc) +top_env(mrb_state *mrb, struct RProc *proc) { struct REnv *e = proc->env; + if (is_strict(mrb, e)) return e; while (e->c) { - if (!e) return 0; e = (struct REnv*)e->c; + if (is_strict(mrb, e)) return e; } return e; } @@ -1165,8 +1178,9 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) break; case OP_R_RETURN: if (!proc->env) goto NORMAL_RETURN; + if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; else { - struct REnv *e = top_env(proc); + struct REnv *e = top_env(mrb, proc); if (e->cioff < 0) { localjump_error(mrb, "return"); |
