From: nobu.nokada@... Date: 2004-07-08T07:17:12+09:00 Subject: Re: arguments to Thread#raise ? Hi, At Thu, 8 Jul 2004 02:53:57 +0900, Paul Brannan wrote in [ruby-talk:105512]: > On Thu, Jul 08, 2004 at 02:05:42AM +0900, ts wrote: > > >>>>> "P" == Paul Brannan writes: > > > > P> Thread.main.raise exc, exc.message, exc.backtrace > > > > This is Kernel#raise which can take 3 arguments : exception, message, > > backtrace > > It essentially does the same as Kernel#raise under the hood, but I'm > definitely calling Thread#raise (rb_thread_raise_m), not Kernel#raise > (rb_f_raise). The former calls the later if the target thread is current. > > P> t = Thread.new do > > P> Thread.main.raise exc, exc.message, exc.backtrace > > > > This is Thread#raise which can take only 2 arguments : exception and > > message > > Why is that (I mean, is there any technical reason for the > inconsistency)? I don't know exact reason, but it feels wrong. Also, I suspect the arguments should be evaluated in the caller's context. Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.675 diff -u -2 -p -r1.675 eval.c --- eval.c 5 Jul 2004 00:03:11 -0000 1.675 +++ eval.c 7 Jul 2004 22:05:53 -0000 @@ -145,4 +145,6 @@ static VALUE rb_f_block_given_p _((void) static VALUE umethod_bind _((VALUE, VALUE)); static VALUE rb_mod_define_method _((int, VALUE*, VALUE)); +NORETURN(static void rb_raise_jump _((VALUE))); +static VALUE rb_make_exception _((int argc, VALUE *argv)); static int scope_vmode; @@ -4391,4 +4393,13 @@ rb_f_raise(argc, argv) VALUE *argv; { + rb_raise_jump(rb_make_exception(argc, argv)); + return Qnil; /* not reached */ +} + +static VALUE +rb_make_exception(argc, argv) + int argc; + VALUE *argv; +{ VALUE mesg; ID exception; @@ -4430,4 +4441,11 @@ rb_f_raise(argc, argv) } + return mesg; +} + +static void +rb_raise_jump(mesg) + VALUE mesg; +{ if (ruby_frame != top_frame) { PUSH_FRAME(); /* fake frame */ @@ -4437,6 +4455,4 @@ rb_f_raise(argc, argv) } rb_longjmp(TAG_RAISE, mesg); - - return Qnil; /* not reached */ } @@ -9765,6 +9781,5 @@ rb_thread_check(data) static VALUE rb_thread_raise _((int, VALUE*, rb_thread_t)); -static int th_raise_argc; -static VALUE th_raise_argv[2]; +static VALUE th_raise_exception; static NODE *th_raise_node; static VALUE th_cmd; @@ -9866,5 +9881,5 @@ rb_thread_switch(n) ruby_frame->last_func = 0; ruby_current_node = th_raise_node; - rb_f_raise(th_raise_argc, th_raise_argv); + rb_raise_jump(th_raise_exception); break; case RESTORE_SIGNAL: @@ -9872,5 +9887,5 @@ rb_thread_switch(n) break; case RESTORE_EXIT: - ruby_errinfo = th_raise_argv[0]; + ruby_errinfo = th_raise_exception; ruby_current_node = th_raise_node; error_print(); @@ -10035,6 +10050,5 @@ rb_thread_main_jump(err, tag) { curr_thread = main_thread; - th_raise_argc = 1; - th_raise_argv[0] = err; + th_raise_exception = err; th_raise_node = ruby_current_node; rb_thread_restore_context(main_thread, tag); @@ -11817,4 +11831,5 @@ rb_thread_raise(argc, argv, th) { volatile rb_thread_t th_save = th; + VALUE exc; if (!th->next) { @@ -11822,6 +11837,7 @@ rb_thread_raise(argc, argv, th) } if (rb_thread_dead(th)) return Qnil; + exc = rb_make_exception(argc, argv); if (curr_thread == th) { - rb_f_raise(argc, argv); + rb_raise_jump(exc); } @@ -11832,9 +11848,8 @@ rb_thread_raise(argc, argv, th) } - rb_scan_args(argc, argv, "11", &th_raise_argv[0], &th_raise_argv[1]); rb_thread_ready(th); curr_thread = th; - th_raise_argc = argc; + th_raise_exception = exc; th_raise_node = ruby_current_node; rb_thread_restore_context(curr_thread, RESTORE_RAISE); -- Nobu Nakada