diff --git a/ChangeLog b/ChangeLog index 5dea9355e2..48c4203e74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sat Dec 14 01:31:52 2013 Nobuyoshi Nakada + + * eval.c (rb_rescue2): reuse tags pushed for body proc to protect + rescue proc too. + Sat Dec 14 01:15:51 2013 Masaya Tarui * gc.c (wmap_final_func): Bugfix. Should update *value to new pointer. diff --git a/eval.c b/eval.c index 2882c57295..3a0206f24a 100644 --- a/eval.c +++ b/eval.c @@ -741,7 +741,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1, int state; rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp = th->cfp; - volatile VALUE result; + volatile VALUE result = Qfalse; volatile VALUE e_info = th->errinfo; va_list args; @@ -750,6 +750,15 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1, retry_entry: result = (*b_proc) (data1); } + else if (result) { + /* escape from r_proc */ + if (state == TAG_RETRY) { + state = 0; + th->errinfo = Qnil; + result = Qfalse; + goto retry_entry; + } + } else { th->cfp = cfp; /* restore */ @@ -767,25 +776,12 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1, va_end(args); if (handle) { + result = Qnil; + state = 0; if (r_proc) { - PUSH_TAG(); - if ((state = EXEC_TAG()) == 0) { - result = (*r_proc) (data2, th->errinfo); - } - POP_TAG(); - if (state == TAG_RETRY) { - state = 0; - th->errinfo = Qnil; - goto retry_entry; - } - } - else { - result = Qnil; - state = 0; - } - if (state == 0) { - th->errinfo = e_info; + result = (*r_proc) (data2, th->errinfo); } + th->errinfo = e_info; } } }