From: nobu.nokada@... Date: 2003-06-06T00:01:54+09:00 Subject: Re: [1.8] Exception::new Hi, At Thu, 5 Jun 2003 20:18:38 +0900, ts wrote: > but, there is also this case > > svg% ./ruby -e 'def Exception::new(*args) $SAFE = 4; raise; end; raise' > Segmentation fault > svg% Hmmm, at such disaster, nothing might be possible. Index: eval.c =================================================================== RCS file: //sharui/cvs/ruby/src/ruby/eval.c,v retrieving revision 1.454 diff -u -2 -p -r1.454 eval.c --- eval.c 5 Jun 2003 06:40:42 -0000 1.454 +++ eval.c 5 Jun 2003 14:58:16 -0000 @@ -1049,5 +1049,5 @@ error_print() errat = Qnil; } - POP_TAG(); + if (EXEC_TAG()) goto error; if (NIL_P(errat)){ ruby_set_current_source(); @@ -1070,5 +1070,4 @@ error_print() eclass = CLASS_OF(ruby_errinfo); - PUSH_TAG(PROT_NONE); if (EXEC_TAG() == 0) { VALUE e = rb_obj_as_string(ruby_errinfo); @@ -1080,5 +1079,5 @@ error_print() elen = 0; } - POP_TAG(); + if (EXEC_TAG()) goto error; if (eclass == rb_eRuntimeError && elen == 0) { warn_print(": unhandled exception\n"); @@ -1134,4 +1133,6 @@ error_print() } } + error: + POP_TAG(); } @@ -3842,4 +3843,7 @@ static int thread_set_raised(); static void thread_reset_raised(); +static VALUE exception_error; +static VALUE sysstack_error; + static void rb_longjmp(tag, mesg) @@ -3849,4 +3853,8 @@ rb_longjmp(tag, mesg) VALUE at; + if (thread_set_raised()) { + ruby_errinfo = exception_error; + JUMP_TAG(TAG_FATAL); + } if (NIL_P(mesg)) mesg = ruby_errinfo; if (NIL_P(mesg)) { @@ -3867,5 +3875,4 @@ rb_longjmp(tag, mesg) if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo) - && !thread_set_raised() && !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) { VALUE e = ruby_errinfo; @@ -3881,6 +3888,8 @@ rb_longjmp(tag, mesg) } POP_TAG(); - thread_reset_raised(); - if (status) JUMP_TAG(status); + if (status) { + thread_reset_raised(); + JUMP_TAG(status); + } } @@ -3895,4 +3904,5 @@ rb_longjmp(tag, mesg) error_print(); } + thread_reset_raised(); JUMP_TAG(tag); } @@ -4574,5 +4584,5 @@ stack_check() PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { - rb_raise(rb_eSysStackError, "stack level too deep"); + rb_exc_raise(sysstack_error); } POP_TAG(); @@ -7628,5 +7638,10 @@ Init_Proc() rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0); + exception_error = rb_exc_new2(rb_eFatal, "recursed exception"); + rb_global_variable(&exception_error); + rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError); + sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep"); + rb_global_variable(&sysstack_error); rb_cBlock = rb_define_class("Block", rb_cObject); -- Nobu Nakada