summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--cont.c4
-rw-r--r--eval_intern.h5
-rw-r--r--test/ruby/test_fiber.rb16
4 files changed, 32 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index b0fb0f2ad7..274b6f818c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Wed Jun 6 02:50:53 2007 Koichi Sasada <ko1@atdot.net>
+
+ * cont.c (rb_fiber_start): clear th->tag and check error to fix
+ [ruby-dev:30888] and [ruby-dev:30889].
+
+ * eval_intern.h: fix rb_fiber_start() prototype.
+
+ * test/ruby/test_fiber.rb: add tests for above.
+
Wed Jun 6 02:40:20 2007 NAKAMURA Usaku <usa@ruby-lang.org>
* insnhelper.h, insns.def (DEC_SP): shoudn't use unary minus operator
diff --git a/cont.c b/cont.c
index 4327d14746..265e743a97 100644
--- a/cont.c
+++ b/cont.c
@@ -421,6 +421,8 @@ rb_fiber_start(void)
VALUE args;
int state;
+ th->tag = 0;
+
TH_PUSH_TAG(th);
if ((state = EXEC_TAG()) == 0) {
GetContPtr(th->fiber, cont);
@@ -436,7 +438,7 @@ rb_fiber_start(void)
TH_POP_TAG();
if (state) {
- th->thrown_errinfo = th->errinfo;
+ th->thrown_errinfo = th_make_jump_tag_but_local_jump(state, th->errinfo);
th->interrupt_flag = 1;
}
diff --git a/eval_intern.h b/eval_intern.h
index abfb7794a9..5f6ba41b71 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -122,7 +122,7 @@ char *strrchr _((const char *, const char));
stmt; \
} \
else { \
- rb_fiber_start(th); \
+ rb_fiber_start(); \
} while (0)
#define TH_PUSH_TAG(th) do { \
@@ -193,6 +193,8 @@ int thread_reset_raised(rb_thread_t *th);
VALUE rb_f_eval(int argc, VALUE *argv, VALUE self);
VALUE rb_make_exception _((int argc, VALUE *argv));
+NORETURN(void rb_fiber_start(void));
+
NORETURN(void rb_raise_jump _((VALUE)));
NORETURN(void print_undef _((VALUE, ID)));
NORETURN(void th_localjump_error(const char *, VALUE, int));
@@ -203,6 +205,7 @@ VALUE th_compile(rb_thread_t *th, VALUE str, VALUE file, VALUE line);
NODE *th_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp);
NODE *th_cref_push(rb_thread_t *th, VALUE, int);
NODE *th_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack);
+VALUE th_make_jump_tag_but_local_jump(int state, VALUE val);
static rb_control_frame_t *
th_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index 999bfd267a..97ec09c36b 100644
--- a/test/ruby/test_fiber.rb
+++ b/test/ruby/test_fiber.rb
@@ -69,5 +69,21 @@ class TestFiber < Test::Unit::TestCase
assert_equal(:ok, f1.yield)
assert_equal([:baz, :bar], ary)
end
+
+ def test_return
+ assert_raise(LocalJumpError){
+ Fiber.new do
+ return
+ end.yield
+ }
+ end
+
+ def test_throw
+ assert_raise(RuntimeError){
+ Fiber.new do
+ throw :a
+ end.yield
+ }
+ end
end