summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-24 05:20:48 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-24 05:20:48 +0000
commit04726dd749f1f93eca39584311e224e2465fca5c (patch)
treecc2b54cfaafdca60b6aa95624c9606de00666584 /vm.c
parentd03199b6d6cedc9c5d1059aa58e5211af6b479b3 (diff)
* vm.c (rb_iter_break_value): new function to break a block with
the value. [ruby-dev:45132] [Feature #5895] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34369 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/vm.c b/vm.c
index 4e713d3bf3..86217098cb 100644
--- a/vm.c
+++ b/vm.c
@@ -987,23 +987,29 @@ rb_vm_jump_tag_but_local_jump(int state, VALUE val)
JUMP_TAG(state);
}
-NORETURN(static void vm_iter_break(rb_thread_t *th));
+NORETURN(static void vm_iter_break(rb_thread_t *th, VALUE val));
static void
-vm_iter_break(rb_thread_t *th)
+vm_iter_break(rb_thread_t *th, VALUE val)
{
rb_control_frame_t *cfp = th->cfp;
VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp);
th->state = TAG_BREAK;
- th->errinfo = (VALUE)NEW_THROW_OBJECT(Qnil, (VALUE)dfp, TAG_BREAK);
+ th->errinfo = (VALUE)NEW_THROW_OBJECT(val, (VALUE)dfp, TAG_BREAK);
TH_JUMP_TAG(th, TAG_BREAK);
}
void
rb_iter_break(void)
{
- vm_iter_break(GET_THREAD());
+ vm_iter_break(GET_THREAD(), Qnil);
+}
+
+void
+rb_iter_break_value(VALUE val)
+{
+ vm_iter_break(GET_THREAD(), val);
}
/* optimization: redefine management */
@@ -1352,6 +1358,7 @@ vm_exec(rb_thread_t *th)
#endif
}
th->errinfo = Qnil;
+ th->state = 0;
goto vm_loop_start;
}
}