should look for outermost scope to return; close #547

This commit is contained in:
Yukihiro Matz Matsumoto
2012-11-16 11:51:51 +09:00
parent a5d7ebbad0
commit 470bb14dc8
+21 -5
View File
@@ -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 */