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) {
|
||