ruby-changes:45227
From: nobu <ko1@a...>
Date: Wed, 11 Jan 2017 00:28:21 +0900 (JST)
Subject: [ruby-changes:45227] nobu:r57300 (trunk): compile.c: check compile
nobu 2017-01-11 00:28:11 +0900 (Wed, 11 Jan 2017) New Revision: 57300 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57300 Log: compile.c: check compile * compile.c (iseq_compile_each): check if sub nodes succeeded. [ruby-core:76531] [Bug #12613] Modified files: trunk/compile.c trunk/test/ruby/test_syntax.rb Index: test/ruby/test_syntax.rb =================================================================== --- test/ruby/test_syntax.rb (revision 57299) +++ test/ruby/test_syntax.rb (revision 57300) @@ -958,6 +958,23 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L958 end end + def test_syntax_error_in_rescue + bug12613 = '[ruby-core:76531] [Bug #12613]' + assert_syntax_error("#{<<-"begin;"}\n#{<<-"end;"}", /Invalid retry/, bug12613) + begin; + while true + begin + p + rescue + retry + else + retry + end + break + end + end; + end + private def not_label(x) @result = x; @not_label ||= nil end Index: compile.c =================================================================== --- compile.c (revision 57299) +++ compile.c (revision 57300) @@ -400,6 +400,8 @@ do { \ https://github.com/ruby/ruby/blob/trunk/compile.c#L400 #define COMPILE_OK 1 #define COMPILE_NG 0 +#define CHECK(sub) if (!(sub)) {BEFORE_RETURN;return COMPILE_NG;} +#define BEFORE_RETURN /* leave name uninitialized so that compiler warn if INIT_ANCHOR is * missing */ @@ -594,7 +596,7 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NO https://github.com/ruby/ruby/blob/trunk/compile.c#L596 ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_B_CALL); ADD_LABEL(ret, start); - COMPILE(ret, "block body", node->nd_body); + CHECK(COMPILE(ret, "block body", node->nd_body)); ADD_LABEL(ret, end); ADD_TRACE(ret, nd_line(node), RUBY_EVENT_B_RETURN); @@ -606,19 +608,19 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NO https://github.com/ruby/ruby/blob/trunk/compile.c#L608 case ISEQ_TYPE_CLASS: { ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CLASS); - COMPILE(ret, "scoped node", node->nd_body); + CHECK(COMPILE(ret, "scoped node", node->nd_body)); ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END); break; } case ISEQ_TYPE_METHOD: { ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CALL); - COMPILE(ret, "scoped node", node->nd_body); + CHECK(COMPILE(ret, "scoped node", node->nd_body)); ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN); break; } default: { - COMPILE(ret, "scoped node", node->nd_body); + CHECK(COMPILE(ret, "scoped node", node->nd_body)); break; } } @@ -641,15 +643,15 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NO https://github.com/ruby/ruby/blob/trunk/compile.c#L643 return COMPILE_NG; case ISEQ_TYPE_RESCUE: iseq_set_exception_local_table(iseq); - COMPILE(ret, "rescue", node); + CHECK(COMPILE(ret, "rescue", node)); break; case ISEQ_TYPE_ENSURE: iseq_set_exception_local_table(iseq); - COMPILE_POPPED(ret, "ensure", node); + CHECK(COMPILE_POPPED(ret, "ensure", node)); break; case ISEQ_TYPE_DEFINED_GUARD: iseq_set_exception_local_table(iseq); - COMPILE(ret, "defined guard", node); + CHECK(COMPILE(ret, "defined guard", node)); break; default: compile_bug(ERROR_ARGS "unknown scope"); @@ -2779,7 +2781,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2781 lit = Qnil; } else { - COMPILE(ret, "each string", node); + CHECK(COMPILE(ret, "each string", node)); } cnt++; list = list->nd_next; @@ -2797,7 +2799,7 @@ static int https://github.com/ruby/ruby/blob/trunk/compile.c#L2799 compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node) { int cnt; - compile_dstr_fragments(iseq, ret, node, &cnt); + CHECK(compile_dstr_fragments(iseq, ret, node, &cnt)); ADD_INSN1(ret, nd_line(node), concatstrings, INT2FIX(cnt)); return COMPILE_OK; } @@ -2806,7 +2808,7 @@ static int https://github.com/ruby/ruby/blob/trunk/compile.c#L2808 compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node) { int cnt; - compile_dstr_fragments(iseq, ret, node, &cnt); + CHECK(compile_dstr_fragments(iseq, ret, node, &cnt)); ADD_INSN2(ret, nd_line(node), toregexp, INT2FIX(node->nd_cflag), INT2FIX(cnt)); return COMPILE_OK; } @@ -2825,7 +2827,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L2827 ADD_INSNL(ret, line, branchif, lend); /* *flip == 0 */ - COMPILE(ret, "flip2 beg", node->nd_beg); + CHECK(COMPILE(ret, "flip2 beg", node->nd_beg)); ADD_INSNL(ret, line, branchunless, else_label); ADD_INSN1(ret, line, putobject, Qtrue); ADD_INSN1(ret, line, setspecial, key); @@ -2835,7 +2837,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L2837 /* *flip == 1 */ ADD_LABEL(ret, lend); - COMPILE(ret, "flip2 end", node->nd_end); + CHECK(COMPILE(ret, "flip2 end", node->nd_end)); ADD_INSNL(ret, line, branchunless, then_label); ADD_INSN1(ret, line, putobject, Qfalse); ADD_INSN1(ret, line, setspecial, key); @@ -2852,18 +2854,18 @@ compile_branch_condition(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L2854 case NODE_AND: { LABEL *label = NEW_LABEL(nd_line(cond)); - compile_branch_condition(iseq, ret, cond->nd_1st, label, - else_label); + CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, label, + else_label)); ADD_LABEL(ret, label); - compile_branch_condition(iseq, ret, cond->nd_2nd, then_label, - else_label); + CHECK(compile_branch_condition(iseq, ret, cond->nd_2nd, then_label, + else_label)); break; } case NODE_OR: { LABEL *label = NEW_LABEL(nd_line(cond)); - compile_branch_condition(iseq, ret, cond->nd_1st, then_label, - label); + CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, then_label, + label)); ADD_LABEL(ret, label); compile_branch_condition(iseq, ret, cond->nd_2nd, then_label, else_label); @@ -2893,13 +2895,13 @@ compile_branch_condition(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L2895 ADD_INSNL(ret, nd_line(cond), jump, else_label); break; case NODE_FLIP2: - compile_flip_flop(iseq, ret, cond, TRUE, then_label, else_label); + CHECK(compile_flip_flop(iseq, ret, cond, TRUE, then_label, else_label)); break; case NODE_FLIP3: - compile_flip_flop(iseq, ret, cond, FALSE, then_label, else_label); + CHECK(compile_flip_flop(iseq, ret, cond, FALSE, then_label, else_label)); break; default: - COMPILE(ret, "branch condition", cond); + CHECK(COMPILE(ret, "branch condition", cond)); ADD_INSNL(ret, nd_line(cond), branchunless, else_label); ADD_INSNL(ret, nd_line(cond), jump, then_label); break; @@ -3238,7 +3240,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LIN https://github.com/ruby/ruby/blob/trunk/compile.c#L3240 VALUE dupidx; int line = nd_line(node); - COMPILE_POPPED(ret, "masgn lhs (NODE_ATTRASGN)", node); + CHECK(COMPILE_POPPED(ret, "masgn lhs (NODE_ATTRASGN)", node)); iobj = (INSN *)get_prev_insn((INSN *)LAST_ELEMENT(ret)); /* send insn */ ci = (struct rb_call_info *)iobj->operands[0]; @@ -3257,7 +3259,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LIN https://github.com/ruby/ruby/blob/trunk/compile.c#L3259 case NODE_MASGN: { DECL_ANCHOR(anchor); INIT_ANCHOR(anchor); - COMPILE_POPPED(anchor, "nest masgn lhs", node); + CHECK(COMPILE_POPPED(anchor, "nest masgn lhs", node)); REMOVE_ELEM(FIRST_ELEMENT(anchor)); ADD_SEQ(ret, anchor); break; @@ -3265,7 +3267,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LIN https://github.com/ruby/ruby/blob/trunk/compile.c#L3267 default: { DECL_ANCHOR(anchor); INIT_ANCHOR(anchor); - COMPILE_POPPED(anchor, "masgn lhs", node); + CHECK(COMPILE_POPPED(anchor, "masgn lhs", node)); REMOVE_ELEM(FIRST_ELEMENT(anchor)); ADD_SEQ(ret, anchor); } @@ -3274,13 +3276,14 @@ compile_massign_lhs(rb_iseq_t *iseq, LIN https://github.com/ruby/ruby/blob/trunk/compile.c#L3276 return COMPILE_OK; } -static void +static int compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *lhsn) { if (lhsn) { - compile_massign_opt_lhs(iseq, ret, lhsn->nd_next); - compile_massign_lhs(iseq, ret, lhsn->nd_head); + CHECK(compile_massign_opt_lhs(iseq, ret, lhsn->nd_next)); + CHECK(compile_massign_lhs(iseq, ret, lhsn->nd_head)); } + return COMPILE_OK; } static int @@ -3375,7 +3378,7 @@ compile_massign(rb_iseq_t *iseq, LINK_AN https://github.com/ruby/ruby/blob/trunk/compile.c#L3378 INIT_ANCHOR(lhsseq); while (lhsn) { - compile_massign_lhs(iseq, lhsseq, lhsn->nd_head); + CHECK(compile_massign_lhs(iseq, lhsseq, lhsn->nd_head)); llen += 1; lhsn = lhsn->nd_next; } @@ -3428,16 +3431,16 @@ compile_massign(rb_iseq_t *iseq, LINK_AN https://github.com/ruby/ruby/blob/trunk/compile.c#L3431 INT2FIX(num), INT2FIX(flag)); if ((VALUE)restn != (VALUE)-1) { - compile_massign_lhs(iseq, ret, restn); + CHECK(compile_massign_lhs(iseq, ret, restn)); } while (postn) { - compile_massign_lhs(iseq, ret, postn->nd_head); + CHECK(compile_massign_lhs(iseq, ret, postn->nd_head)); postn = postn->nd_next; } } else { /* a, b, *r */ - compile_massign_lhs(iseq, ret, splatn); + CHECK(compile_massign_lhs(iseq, ret, splatn)); } } } @@ -3465,7 +3468,7 @@ compile_colon2(rb_iseq_t *iseq, NODE *no https://github.com/ruby/ruby/blob/trunk/compile.c#L3468 ADD_INSN1(body, nd_line(node), getconstant, ID2SYM(node->nd_mid)); break; default: - COMPILE(pref, "const colon2 prefix", node); + CHECK(COMPILE(pref, "const colon2 prefix", node)); break; } return COMPILE_OK; @@ -3982,18 +3985,20 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3985 } debug_node_start(node); +#undef BEFORE_RETURN +#define BEFORE_RETURN debug_node_end() type = nd_type(node); switch (type) { case NODE_BLOCK:{ while (node && nd_type(node) == NODE_BLOCK) { - COMPILE_(ret, "BLOCK body", node->nd_head, - (node->nd_next == 0 && popped == 0) ? 0 : 1); + CHECK(COMPILE_(ret, "BLOCK body", node->nd_head, + (node->nd_next ? 1 : popped))); node = node->nd_next; } if (node) { - COMPILE_(ret, "BLOCK next", node->nd_next, popped); + CHECK(COMPILE_(ret, "BLOCK next", node->nd_next, popped)); } break; } @@ -4012,8 +4017,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4017 compile_branch_condition(iseq, cond_seq, node->nd_cond, then_label, else_label); - COMPILE_(then_seq, "then", node->nd_body, popped); - COMPILE_(else_seq, "else", node->nd_else, popped); + CHECK(COMPILE_(then_seq, "then", node->nd_body, popped)); + CHECK(COMPILE_(else_seq, "else", node->nd_else, popped)); ADD_SEQ(ret, cond_seq); @@ -4045,10 +4050,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4050 rb_hash_tbl_raw(literals)->type = &cdhash_type; if (node->nd_head == 0) { - COMPILE_(ret, "when", node->nd_body, popped); + CHECK(COMPILE_(ret, "when", node->nd_body, popped)); break; } - COMPILE(head, "case base", node->nd_head); + CHECK(COMPILE(head, "case base", node->nd_head)); node = node->nd_body; type = nd_type(node); @@ -4056,6 +4061,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4061 if (type != NODE_WHEN) { COMPILE_ERROR(ERROR_ARGS "NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type)); + ng: debug_node_end(); return COMPILE_NG; } @@ -4071,7 +4077,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4077 l1 = NEW_LABEL(line); ADD_LABEL(body_seq, l1); ADD_INSN(body_seq, line, pop); - COMPILE_(body_seq, "when body", node->nd_body, popped); + CHECK(COMPILE_(body_seq, "when body", node->nd_body, popped)); ADD_INSNL(body_seq, line, jump, endlabel); vals = node->nd_head; @@ -4085,7 +4091,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4091 case NODE_ARGSPUSH: only_special_literals = 0; ADD_INSN (cond_seq, nd_line(vals), dup); - COMPILE(cond_seq, "when/cond splat", vals); + CHECK(COMPILE(cond_seq, "when/cond splat", vals)); ADD_INSN1(cond_seq, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); ADD_INSNL(cond_seq, nd_line(vals), branchif, l1); break; @@ -4108,7 +4114,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4114 if (node) { ADD_LABEL(cond_seq, elselabel); ADD_INSN(cond_seq, line, pop); - COMPILE_(cond_seq, "else", node, popped); + CHECK(COMPILE_(cond_seq, "else", node, popped)); ADD_INSNL(cond_seq, line, jump, endlabel); } else { @@ -4147,7 +4153,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4153 while (node && nd_type(node) == NODE_WHEN) { LABEL *l1 = NEW_LABEL(line = nd_line(node)); ADD_LABEL(body_seq, l1); - COMPILE_(body_seq, "when", node->nd_body, popped); + CHECK(COMPILE_(body_seq, "when", node->nd_body, popped)); ADD_INSNL(body_seq, line, jump, endlabel); vals = node->nd_head; @@ -4158,7 +4164,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4164 case NODE_ARRAY: while (vals) { val = vals->nd_head; - COMPILE(ret, "when2", val); + CHECK(COMPILE(ret, "when2", val)); ADD_INSNL(ret, nd_line(val), branchif, l1); vals = vals->nd_next; } @@ -4167,7 +4173,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4173 case NODE_ARGSCAT: case NODE_ARGSPUSH: ADD_INSN(ret, nd_line(vals), putnil); - COMPILE(ret, "when2/cond splat", vals); + CHECK(COMPILE(ret, "when2/cond splat", vals)); ADD_INSN1(ret, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_WHEN | VM_CHECKMATCH_ARRAY)); ADD_INSNL(ret, nd_line(vals), branchif, l1); break; @@ -4177,7 +4183,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4183 node = node->nd_next; } /* else */ - COMPILE_(ret, "else", node, popped); + CHECK(COMPILE_(ret, "else", node, popped)); ADD_INSNL(ret, nd_line(orig_node), jump, endlabel); ADD_SEQ(ret, body_seq); @@ -4222,7 +4228,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4228 if (tmp_label) ADD_LABEL(ret, tmp_label); ADD_LABEL(ret, redo_label); - COMPILE_POPPED(ret, "while body", node->nd_body); + CHECK(COMPILE_POPPED(ret, "while body", node->nd_body)); ADD_LABEL(ret, next_label); /* next */ if (type == NODE_WHILE) { @@ -4280,7 +4286,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4286 NODE *var = node->nd_var; LABEL *not_single = NEW_LABEL(nd_line(var)); LABEL *not_ary = NEW_LABEL(nd_line(var)); - COMPILE(ret, "for var", var); + CHECK(COMPILE(ret, "for var", var)); ADD_INSN(ret, line, dup); ADD_CALL(ret, line, idLength, INT2FIX(0)); ADD_INSN1(ret, line, putobject, INT2FIX(1)); @@ -4306,7 +4312,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4312 ADD_LABEL(ret, retry_label); if (nd_type(node) == NODE_FOR) { - COMPILE(ret, "iter caller (for)", node->nd_iter); + 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_TYPE_BLOCK, line); @@ -4315,7 +4321,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4321 else { ISEQ_COMPILE_DATA(iseq)->current_block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); - COMPILE(ret, "iter caller", node->nd_iter); + CHECK(COMPILE(ret, "iter caller", node->nd_iter)); } ADD_LABEL(ret, retry_end_l); @@ -4337,7 +4343,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4343 LABEL *splabel = NEW_LABEL(0); ADD_LABEL(ret, splabel); ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->redo_label); - COMPILE_(ret, "break val (while/until)", node->nd_stts, ISEQ_COMPILE_DATA(iseq)->loopval_popped); + CHECK(COMPILE_(ret, "break val (while/until)", node->nd_stts, + ISEQ_COMPILE_DATA(iseq)->loopval_popped)); add_ensure_iseq(ret, iseq, 0); ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->end_label); ADD_ADJUST_RESTORE(ret, splabel); @@ -4349,7 +4356,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4356 else if (iseq->body->type == ISEQ_TYPE_BLOCK) { break_by_insn: /* escape from block */ - COMPILE(ret, "break val (block)", node->nd_stts); + CHECK(COMPILE(ret, "break val (block)", node->nd_stts)); ADD_INSN1(ret, line, throw, INT2FIX(level | TAG_BREAK)); if (popped) { ADD_INSN(ret, line, pop); @@ -4358,8 +4365,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4365 else if (iseq->body->type == ISEQ_TYPE_EVAL) { break_in_eval: COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with break"); - debug_node_end(); - return COMPILE_NG; + goto ng; } else { const rb_iseq_t *ip = iseq->body->parent_iseq; @@ -4386,8 +4392,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4392 ip = ip->body->parent_iseq; } COMPILE_ERROR(ERROR_ARGS "Invalid break"); - debug_node_end(); - return COMPILE_NG; + goto ng; } break; } @@ -4398,7 +4403,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4403 LABEL *splabel = NEW_LABEL(0); debugs("next in while loop\n"); ADD_LABEL(ret, splabel); - COMPILE(ret, "next val/valid syntax?", node->nd_stts); + CHECK(COMPILE(ret, "next val/valid syntax?", node->nd_stts)); add_ensure_iseq(ret, iseq, 0); ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->redo_label); ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->start_label); @@ -4412,7 +4417,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4417 debugs("next in block\n"); ADD_LABEL(ret, splabel); ADD_ADJUST(ret, line, ISEQ_COMPILE_DATA(iseq)->start_label); - COMPILE(ret, "next val", node->nd_stts); + CHECK(COMPILE(ret, "next val", node->nd_stts)); add_ensure_iseq(ret, iseq, 0); ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(iseq)->end_label); ADD_ADJUST_RESTORE(ret, splabel); @@ -4424,6 +4429,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4429 else if (iseq->body->type == ISEQ_TYPE_EVAL) { next_in_eval: COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with next"); + goto ng; } else { const rb_iseq_t *ip = iseq; @@ -4449,7 +4455,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4455 ip = ip->body->parent_iseq; } if (ip != 0) { - COMPILE(ret, "next val", node->nd_stts); + CHECK(COMPILE(ret, "next val", node->nd_stts)); ADD_INSN1(ret, line, throw, INT2FIX(level | TAG_NEXT)); if (popped) { @@ -4458,6 +4464,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4464 } else { COMPILE_ERROR(ERROR_ARGS "Invalid next"); + goto ng; (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/