summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--bootstraptest/test_block.rb14
-rw-r--r--vm_insnhelper.c4
3 files changed, 21 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 50772fd0ca..7d555b0766 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);