Project

General

Profile

Feature #5895 ยป iter_break.diff

nobu (Nobuyoshi Nakada), 01/14/2012 11:42 PM

View differences:

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) {
    (1-1/1)