diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | bootstraptest/test_block.rb | 14 | ||||
-rw-r--r-- | vm_insnhelper.c | 4 |
3 files changed, 21 insertions, 3 deletions
@@ -1,3 +1,9 @@ +Fri Jan 23 23:57:05 2015 Misumi Rize <r@ayase-e.li> + + * vm_insnhelper.c (vm_throw_start): search the target to break + from a block with nested rescue, from the nested blocks. + [ruby-core:67765] [Bug #10775] [Fix GH-820] + Fri Jan 23 20:00:59 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> * marshal.c (w_object, marshal_dump): use indetity tables for diff --git a/bootstraptest/test_block.rb b/bootstraptest/test_block.rb index 6a2ccfc6da..cdc5960a59 100644 --- a/bootstraptest/test_block.rb +++ b/bootstraptest/test_block.rb @@ -597,3 +597,17 @@ assert_equal 'true', %q{ C1.new.foo{} } +assert_equal 'ok', %q{ + 1.times do + begin + raise + rescue + begin + raise + rescue + break + end + end + end + 'ok' +} diff --git a/vm_insnhelper.c b/vm_insnhelper.c index f8939b6bf1..c1c4e3f28e 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -609,13 +609,11 @@ vm_throw_start(rb_thread_t * const th, rb_control_frame_t * const reg_cfp, int s rb_iseq_t *base_iseq = GET_ISEQ(); escape_cfp = reg_cfp; - search_parent: - if (base_iseq->type != ISEQ_TYPE_BLOCK) { + while (base_iseq->type != ISEQ_TYPE_BLOCK) { if (escape_cfp->iseq->type == ISEQ_TYPE_CLASS) { escape_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(escape_cfp); ep = escape_cfp->ep; base_iseq = escape_cfp->iseq; - goto search_parent; } else { ep = VM_EP_PREV_EP(ep); |