diff options
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | eval.c | 38 | ||||
-rw-r--r-- | parse.y | 32 |
3 files changed, 74 insertions, 25 deletions
@@ -1,3 +1,18 @@ +Fri Jun 6 20:29:14 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net> + + * eval.c (error_print): needs to be exception proof. + + * eval.c (error_handle, rb_longjmp): bails out when exception + reentered. (ruby-bugs-ja:PR#487), [ruby-core:01119], + [ruby-core:01122] + + * eval.c (Init_Proc): pre-allocates critical error objects. + +Fri Jun 6 20:29:14 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net> + + * parse.y (cmd_brace_block, do_block, brace_block): initialize block + variables at the beginning of the block. [ruby-talk:72521] + Fri Jun 6 18:33:27 2003 Yukihiro Matsumoto <matz@ruby-lang.org> * gc.c (define_final): eliminate rb_f_lambda() call. @@ -65,18 +80,18 @@ Thu Jun 5 15:09:06 2003 Yukihiro Matsumoto <matz@ruby-lang.org> * math.c (math_erf,math_erfc): new function. [ruby-list:37753] -Thu Jun 5 05:49:43 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net> +Thu Jun 5 14:49:43 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net> - * ext/syck/rubyext.c: using GC nodes caused segfault. [ruby-core:1071] + * ext/syck/rubyext.c: using GC nodes caused segfault. [ruby-core:1071] -Thu Jun 5 04:48:57 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net> +Thu Jun 5 13:48:57 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net> - * ext/syck/token.c: directives choked on a period. + * ext/syck/token.c: directives choked on a period. - * ext/syck/gram.y: anchors work above a collection. [ruby-core:1071] + * ext/syck/gram.y: anchors work above a collection. [ruby-core:1071] - * ext/syck/handler.c, ext/syck/syck.c: ensure a fresh strtable between - parser iterations. + * ext/syck/handler.c, ext/syck/syck.c: ensure a fresh strtable between + parser iterations. Wed Jun 4 12:06:59 2003 Yukihiro Matsumoto <matz@ruby-lang.org> @@ -1047,7 +1047,7 @@ error_print() else { errat = Qnil; } - POP_TAG(); + if (EXEC_TAG()) goto error; if (NIL_P(errat)){ ruby_set_current_source(); if (ruby_sourcefile) @@ -1068,7 +1068,6 @@ error_print() } eclass = CLASS_OF(ruby_errinfo); - PUSH_TAG(PROT_NONE); if (EXEC_TAG() == 0) { VALUE e = rb_obj_as_string(ruby_errinfo); einfo = RSTRING(e)->ptr; @@ -1078,7 +1077,7 @@ error_print() einfo = ""; elen = 0; } - POP_TAG(); + if (EXEC_TAG()) goto error; if (eclass == rb_eRuntimeError && elen == 0) { warn_print(": unhandled exception\n"); } @@ -1132,6 +1131,8 @@ error_print() } } } + error: + POP_TAG(); } #if defined(__APPLE__) @@ -1221,10 +1222,18 @@ int ruby_in_eval; static void rb_thread_cleanup _((void)); static void rb_thread_wait_other_threads _((void)); +static int thread_set_raised(); +static void thread_reset_raised(); + +static VALUE exception_error; +static VALUE sysstack_error; + static int error_handle(ex) int ex; { + if (thread_set_raised()) return 1; + switch (ex & TAG_MASK) { case 0: ex = 0; @@ -1282,6 +1291,7 @@ error_handle(ex) rb_bug("Unknown longjmp status %d", ex); break; } + thread_reset_raised(); return ex; } @@ -3838,9 +3848,6 @@ rb_iter_break() NORETURN(static void rb_longjmp _((int, VALUE))); static VALUE make_backtrace _((void)); -static int thread_set_raised(); -static void thread_reset_raised(); - static void rb_longjmp(tag, mesg) int tag; @@ -3848,6 +3855,10 @@ 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)) { mesg = rb_exc_new(rb_eRuntimeError, 0, 0); @@ -3866,7 +3877,6 @@ 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; int status; @@ -3880,8 +3890,10 @@ rb_longjmp(tag, mesg) RSTRING(e)->ptr); } POP_TAG(); - thread_reset_raised(); - if (status) JUMP_TAG(status); + if (status) { + thread_reset_raised(); + JUMP_TAG(status); + } } rb_trap_restore_mask(); @@ -3894,6 +3906,7 @@ rb_longjmp(tag, mesg) if (!prot_tag) { error_print(); } + thread_reset_raised(); JUMP_TAG(tag); } @@ -4573,7 +4586,7 @@ stack_check() overflowing = 1; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { - rb_raise(rb_eSysStackError, "stack level too deep"); + rb_exc_raise(sysstack_error); } POP_TAG(); overflowing = 0; @@ -7627,7 +7640,12 @@ Init_Proc() rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0); rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0); + exception_error = rb_exc_new2(rb_eFatal, "exception reentered"); + 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); rb_undef_alloc_func(rb_cBlock); @@ -165,6 +165,7 @@ static ID internal_id(); static struct RVarmap *dyna_push(); static void dyna_pop(); static int dyna_in_block(); +static NODE *dyna_init(); static void top_local_init(); static void top_local_setup(); @@ -645,11 +646,11 @@ cmd_brace_block : tLBRACE_ARG $<vars>$ = dyna_push(); $<num>1 = ruby_sourceline; } - opt_block_var + opt_block_var {$<vars>$ = ruby_dyna_vars;} compstmt '}' { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4)); nd_set_line($$, $<num>1); dyna_pop($<vars>2); } @@ -1714,11 +1715,11 @@ do_block : kDO_BLOCK $<vars>$ = dyna_push(); $<num>1 = ruby_sourceline; } - opt_block_var + opt_block_var {$<vars>$ = ruby_dyna_vars;} compstmt kEND { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4)); nd_set_line($$, $<num>1); dyna_pop($<vars>2); } @@ -1777,10 +1778,10 @@ brace_block : '{' $<vars>$ = dyna_push(); $<num>1 = ruby_sourceline; } - opt_block_var + opt_block_var {$<vars>$ = ruby_dyna_vars;} compstmt '}' { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4)); nd_set_line($$, $<num>1); dyna_pop($<vars>2); } @@ -1789,10 +1790,10 @@ brace_block : '{' $<vars>$ = dyna_push(); $<num>1 = ruby_sourceline; } - opt_block_var + opt_block_var {$<vars>$ = ruby_dyna_vars;} compstmt kEND { - $$ = NEW_ITER($3, 0, $4); + $$ = NEW_ITER($3, 0, dyna_init($5, $<vars>4)); nd_set_line($$, $<num>1); dyna_pop($<vars>2); } @@ -5656,6 +5657,21 @@ dyna_in_block() return (lvtbl->dlev > 0); } +static NODE * +dyna_init(node, pre) + NODE *node; + struct RVarmap *pre; +{ + struct RVarmap *post = ruby_dyna_vars; + NODE *var; + + if (!node || !post || pre == post) return node; + for (var = 0; post != pre && post->id; post = post->next) { + var = NEW_DASGN_CURR(post->id, var); + } + return block_append(var, node); +} + int ruby_parser_stack_on_heap() { |