summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authorDaniel Bovensiepen <[email protected]>2012-11-17 13:54:32 +0800
committerDaniel Bovensiepen <[email protected]>2012-11-17 13:54:32 +0800
commitd8234a45759b3bd7b107750fda886cd828b52173 (patch)
tree864fc0207a46d8d2511e66cd1affc53cdf3984c4 /src/vm.c
parentc3bd1c1d0d43e7571bc38cfa71c40c69cea1b5a4 (diff)
parent7cea9d7b945a4b00cef699f47c07654f8b7bd579 (diff)
downloadmruby-d8234a45759b3bd7b107750fda886cd828b52173.tar.gz
mruby-d8234a45759b3bd7b107750fda886cd828b52173.zip
Merge remote-tracking branch 'upstream/master' into mrbgems
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/vm.c b/src/vm.c
index b5bde896b..ebd505366 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -151,6 +151,18 @@ uvset(mrb_state *mrb, int up, int idx, mrb_value v)
mrb_write_barrier(mrb, (struct RBasic*)e);
}
+struct REnv*
+top_env(struct RProc *proc)
+{
+ struct REnv *e = proc->env;
+
+ while (e->c) {
+ if (!e) return 0;
+ e = (struct REnv*)e->c;
+ }
+ return e;
+}
+
static mrb_callinfo*
cipush(mrb_state *mrb)
{
@@ -1153,11 +1165,15 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
break;
case OP_R_RETURN:
if (!proc->env) goto NORMAL_RETURN;
- if (proc->env->cioff < 0) {
- localjump_error(mrb, "return");
- goto L_RAISE;
- }
- ci = mrb->ci = mrb->cibase + proc->env->cioff;
+ else {
+ struct REnv *e = top_env(proc);
+
+ if (e->cioff < 0) {
+ localjump_error(mrb, "return");
+ goto L_RAISE;
+ }
+ ci = mrb->ci = mrb->cibase + e->cioff;
+ }
break;
default:
/* cannot happen */