* 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
This commit is contained in:
parent
d03199b6d6
commit
04726dd749
@ -1,3 +1,8 @@
|
|||||||
|
Tue Jan 24 14:20:42 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* vm.c (rb_iter_break_value): new function to break a block with
|
||||||
|
the value. [ruby-dev:45132] [Feature #5895]
|
||||||
|
|
||||||
Tue Jan 24 12:58:41 2012 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Tue Jan 24 12:58:41 2012 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* object.c (rb_Hash): add Kernel#Hash conversion method like
|
* object.c (rb_Hash): add Kernel#Hash conversion method like
|
||||||
|
15
ext/-test-/iter/break.c
Normal file
15
ext/-test-/iter/break.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <ruby.h>
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
iter_break_value(VALUE self, VALUE val)
|
||||||
|
{
|
||||||
|
rb_iter_break_value(val);
|
||||||
|
return self; /* not reached */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init_break(void)
|
||||||
|
{
|
||||||
|
VALUE breakable = rb_define_module_under(rb_define_module("Bug"), "Breakable");
|
||||||
|
rb_define_module_function(breakable, "iter_break", iter_break_value, 1);
|
||||||
|
}
|
1
ext/-test-/iter/extconf.rb
Normal file
1
ext/-test-/iter/extconf.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
create_makefile("-test-/iter/break")
|
@ -1185,6 +1185,7 @@ NORETURN(void rb_bug_errno(const char*, int));
|
|||||||
NORETURN(void rb_sys_fail(const char*));
|
NORETURN(void rb_sys_fail(const char*));
|
||||||
NORETURN(void rb_mod_sys_fail(VALUE, const char*));
|
NORETURN(void rb_mod_sys_fail(VALUE, const char*));
|
||||||
NORETURN(void rb_iter_break(void));
|
NORETURN(void rb_iter_break(void));
|
||||||
|
NORETURN(void rb_iter_break_value(VALUE));
|
||||||
NORETURN(void rb_exit(int));
|
NORETURN(void rb_exit(int));
|
||||||
NORETURN(void rb_notimplement(void));
|
NORETURN(void rb_notimplement(void));
|
||||||
VALUE rb_syserr_new(int, const char *);
|
VALUE rb_syserr_new(int, const char *);
|
||||||
|
9
test/-ext-/iter/test_iter_break.rb
Normal file
9
test/-ext-/iter/test_iter_break.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
require 'test/unit'
|
||||||
|
require '-test-/iter/break'
|
||||||
|
|
||||||
|
class TestIterBreak < Test::Unit::TestCase
|
||||||
|
def test_iter_break
|
||||||
|
feature5895 = '[ruby-dev:45132]'
|
||||||
|
assert_equal(42, 1.times{Bug::Breakable.iter_break(42)}, feature5895)
|
||||||
|
end
|
||||||
|
end
|
15
vm.c
15
vm.c
@ -987,23 +987,29 @@ rb_vm_jump_tag_but_local_jump(int state, VALUE val)
|
|||||||
JUMP_TAG(state);
|
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
|
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;
|
rb_control_frame_t *cfp = th->cfp;
|
||||||
VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp);
|
VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp);
|
||||||
|
|
||||||
th->state = TAG_BREAK;
|
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);
|
TH_JUMP_TAG(th, TAG_BREAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_iter_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 */
|
/* optimization: redefine management */
|
||||||
@ -1352,6 +1358,7 @@ vm_exec(rb_thread_t *th)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
|
th->state = 0;
|
||||||
goto vm_loop_start;
|
goto vm_loop_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -906,6 +906,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
|
|||||||
state = 0;
|
state = 0;
|
||||||
th->state = 0;
|
th->state = 0;
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
|
retval = GET_THROWOBJ_VAL(err);
|
||||||
|
|
||||||
/* check skipped frame */
|
/* check skipped frame */
|
||||||
while (th->cfp != cfp) {
|
while (th->cfp != cfp) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user