summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--eval.c22
-rw-r--r--eval_intern.h1
-rw-r--r--thread.c12
4 files changed, 37 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index f01f96f074..17a01898d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Oct 10 14:09:40 2009 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
+
+ * thread.c (rb_threadptr_execute_interrupts_rec, rb_threadptr_raise):
+ Thread#raise with no argument will now re-raise the current exception
+ if there is one [ruby-core:25367]
+
+ * eval.c (get_errinfo, rb_rubylevel_thread_errinfo): Getter for
+ current exception for a given thread
+
Sat Oct 10 12:21:31 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* transcode.c (rb_transcoding, str_transcoding_resize): fixed
diff --git a/eval.c b/eval.c
index bf5b5c8f87..e9e76ad4fb 100644
--- a/eval.c
+++ b/eval.c
@@ -902,9 +902,8 @@ VALUE rb_f_trace_var();
VALUE rb_f_untrace_var();
static VALUE *
-errinfo_place(void)
+errinfo_place(rb_thread_t *th)
{
- rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
@@ -925,19 +924,24 @@ errinfo_place(void)
}
static VALUE
-get_errinfo(void)
+get_thread_errinfo(rb_thread_t *th)
{
- VALUE *ptr = errinfo_place();
+ VALUE *ptr = errinfo_place(th);
if (ptr) {
return *ptr;
}
else {
- rb_thread_t *th = GET_THREAD();
return th->errinfo;
}
}
static VALUE
+get_errinfo(void)
+{
+ return get_thread_errinfo(GET_THREAD());
+}
+
+static VALUE
errinfo_getter(ID id)
{
return get_errinfo();
@@ -951,7 +955,7 @@ errinfo_setter(VALUE val, ID id, VALUE *var)
rb_raise(rb_eTypeError, "assigning non-exception to $!");
}
else {
- VALUE *ptr = errinfo_place();
+ VALUE *ptr = errinfo_place(GET_THREAD());
if (ptr) {
*ptr = val;
}
@@ -984,6 +988,12 @@ rb_rubylevel_errinfo(void)
return get_errinfo();
}
+VALUE
+rb_rubylevel_thread_errinfo(rb_thread_t *th)
+{
+ return get_thread_errinfo(th);
+}
+
static VALUE
errat_getter(ID id)
{
diff --git a/eval_intern.h b/eval_intern.h
index b7790828dc..c5b1fd8b2e 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -212,6 +212,7 @@ void rb_thread_terminate_all(void);
VALUE rb_vm_top_self();
VALUE rb_vm_cbase(void);
void rb_trap_restore_mask(void);
+VALUE rb_rubylevel_thread_errinfo(rb_thread_t *);
#ifndef CharNext /* defined as CharNext[AW] on Windows. */
#define CharNext(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE))
diff --git a/thread.c b/thread.c
index da4cf9cf30..fc33fe568d 100644
--- a/thread.c
+++ b/thread.c
@@ -76,6 +76,7 @@ void rb_thread_stop_timer_thread(void);
static const VALUE eKillSignal = INT2FIX(0);
static const VALUE eTerminateSignal = INT2FIX(1);
+static const VALUE eReRaiseSignal = INT2FIX(2);
static volatile int system_working = 1;
inline static void
@@ -1246,6 +1247,10 @@ rb_threadptr_execute_interrupts_rec(rb_thread_t *th, int sched_depth)
TH_JUMP_TAG(th, TAG_FATAL);
}
else {
+ if (err == eReRaiseSignal) {
+ err = rb_rubylevel_thread_errinfo(th);
+ err = rb_make_exception(NIL_P(err) ? 0 : 1, &err);
+ }
rb_exc_raise(err);
}
}
@@ -1312,7 +1317,12 @@ rb_threadptr_raise(rb_thread_t *th, int argc, VALUE *argv)
goto again;
}
- exc = rb_make_exception(argc, argv);
+ if (argc == 0) {
+ exc = eReRaiseSignal;
+ }
+ else {
+ exc = rb_make_exception(argc, argv);
+ }
th->thrown_errinfo = exc;
rb_threadptr_ready(th);
return Qnil;