Feature #5895 ยป iter_break.diff
i/ext/-test-/iter/break.c | ||
---|---|---|
#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);
|
||
}
|
i/ext/-test-/iter/extconf.rb | ||
---|---|---|
create_makefile("-test-/iter/break")
|
i/include/ruby/ruby.h | ||
---|---|---|
NORETURN(void rb_sys_fail(const char*));
|
||
NORETURN(void rb_mod_sys_fail(VALUE, const char*));
|
||
NORETURN(void rb_iter_break(void));
|
||
NORETURN(void rb_iter_break_value(VALUE));
|
||
NORETURN(void rb_exit(int));
|
||
NORETURN(void rb_notimplement(void));
|
||
VALUE rb_syserr_new(int, const char *);
|
i/test/-ext-/iter/test_iter_break.rb | ||
---|---|---|
require 'test/unit'
|
||
require '-test-/iter/break'
|
||
class TestIterBreak < Test::Unit::TestCase
|
||
def test_iter_break
|
||
assert_equal(42, 1.times{Bug::Breakable.iter_break(42)})
|
||
end
|
||
end
|
i/vm.c | ||
---|---|---|
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 */
|
||
... | ... | |
#endif
|
||
}
|
||
th->errinfo = Qnil;
|
||
th->state = 0;
|
||
goto vm_loop_start;
|
||
}
|
||
}
|
i/vm_eval.c | ||
---|---|---|
state = 0;
|
||
th->state = 0;
|
||
th->errinfo = Qnil;
|
||
retval = GET_THROWOBJ_VAL(err);
|
||
/* check skipped frame */
|
||
while (th->cfp != cfp) {
|