diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-06-08 04:13:51 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-06-08 04:13:51 +0000 |
commit | 7d8a415bc2d08a1b5e9d1ea802493b6eeb99c219 (patch) | |
tree | fabddaef86984680f9d983c80e70b4e8f22c8de8 /compile.c | |
parent | 0318de23d40c2de90f4b2126ff41f1b0dbcb5325 (diff) |
check break target correctly.
* compile.c (iseq_compile_each0): save target child_iseq in the catch-table
for break. This iseq is not for continuation, but for search key at
vm_throw_start().
* vm_insnhelper.c (vm_throw_start): check saved iseq first.
* iseq.h: add comment for it.
* test/ruby/test_iterator.rb (test_ljump): add a test for the issue:
def call b; b.call; end
call(Proc.new{break}){} #=> (1) should raise LocalJumpError
call(Proc.new{break}) #=> (2) shoudd raies LocalJumpError, too.
but (1) doesn't raise LocalJumpError.
This issue is reported by Matz.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59043 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 11 |
1 files changed, 7 insertions, 4 deletions
@@ -4399,17 +4399,20 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block; LABEL *retry_label = NEW_LABEL(line); LABEL *retry_end_l = NEW_LABEL(line); + const rb_iseq_t *child_iseq; ADD_LABEL(ret, retry_label); if (nd_type(node) == NODE_FOR) { CHECK(COMPILE(ret, "iter caller (for)", node->nd_iter)); - ISEQ_COMPILE_DATA(iseq)->current_block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), + ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq = + NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); - ADD_SEND_WITH_BLOCK(ret, line, idEach, INT2FIX(0), ISEQ_COMPILE_DATA(iseq)->current_block); + ADD_SEND_WITH_BLOCK(ret, line, idEach, INT2FIX(0), child_iseq); } else { - ISEQ_COMPILE_DATA(iseq)->current_block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), + ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq = + NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); CHECK(COMPILE(ret, "iter caller", node->nd_iter)); } @@ -4421,7 +4424,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp ISEQ_COMPILE_DATA(iseq)->current_block = prevblock; - ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, NULL, retry_end_l); + ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l); break; } |