Skip to content

Commit c1c3a60

Browse files
committed
[Bug #21984] Keep argument of break/next/return as array in AST
1 parent 76eb974 commit c1c3a60

3 files changed

Lines changed: 18 additions & 10 deletions

File tree

compile.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8541,18 +8541,28 @@ compile_for_masgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod
85418541
return COMPILE_OK;
85428542
}
85438543

8544+
static const NODE *
8545+
ret_args(const NODE *node)
8546+
{
8547+
if (node && nd_type_p(node, NODE_LIST) && !RNODE_LIST(node)->nd_next) {
8548+
return RNODE_LIST(node)->nd_head;
8549+
}
8550+
return node;
8551+
}
8552+
85448553
static int
85458554
compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
85468555
{
85478556
const NODE *line_node = node;
85488557
unsigned long throw_flag = 0;
8558+
const NODE *retval = ret_args(RNODE_BREAK(node)->nd_stts);
85498559

85508560
if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0 && can_add_ensure_iseq(iseq)) {
85518561
/* while/until */
85528562
LABEL *splabel = NEW_LABEL(0);
85538563
ADD_LABEL(ret, splabel);
85548564
ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
8555-
CHECK(COMPILE_(ret, "break val (while/until)", RNODE_BREAK(node)->nd_stts,
8565+
CHECK(COMPILE_(ret, "break val (while/until)", retval,
85568566
ISEQ_COMPILE_DATA(iseq)->loopval_popped));
85578567
add_ensure_iseq(ret, iseq, 0);
85588568
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
@@ -8587,7 +8597,7 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
85878597
}
85888598

85898599
/* escape from block */
8590-
CHECK(COMPILE(ret, "break val (block)", RNODE_BREAK(node)->nd_stts));
8600+
CHECK(COMPILE(ret, "break val (block)", retval));
85918601
ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_BREAK));
85928602
if (popped) {
85938603
ADD_INSN(ret, line_node, pop);
@@ -8605,12 +8615,13 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
86058615
{
86068616
const NODE *line_node = node;
86078617
unsigned long throw_flag = 0;
8618+
const NODE *retval = ret_args(RNODE_NEXT(node)->nd_stts);
86088619

86098620
if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0 && can_add_ensure_iseq(iseq)) {
86108621
LABEL *splabel = NEW_LABEL(0);
86118622
debugs("next in while loop\n");
86128623
ADD_LABEL(ret, splabel);
8613-
CHECK(COMPILE(ret, "next val/valid syntax?", RNODE_NEXT(node)->nd_stts));
8624+
CHECK(COMPILE(ret, "next val/valid syntax?", retval));
86148625
add_ensure_iseq(ret, iseq, 0);
86158626
ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
86168627
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
@@ -8624,7 +8635,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
86248635
debugs("next in block\n");
86258636
ADD_LABEL(ret, splabel);
86268637
ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->start_label);
8627-
CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts));
8638+
CHECK(COMPILE(ret, "next val", retval));
86288639
add_ensure_iseq(ret, iseq, 0);
86298640
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
86308641
ADD_ADJUST_RESTORE(ret, splabel);
@@ -8658,7 +8669,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
86588669
ip = ISEQ_BODY(ip)->parent_iseq;
86598670
}
86608671
if (ip != 0) {
8661-
CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts));
8672+
CHECK(COMPILE(ret, "next val", retval));
86628673
ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_NEXT));
86638674

86648675
if (popped) {
@@ -8931,7 +8942,7 @@ compile_return(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
89318942
enum rb_iseq_type type = ISEQ_BODY(iseq)->type;
89328943
const rb_iseq_t *is = iseq;
89338944
enum rb_iseq_type t = type;
8934-
const NODE *retval = RNODE_RETURN(node)->nd_stts;
8945+
const NODE *retval = ret_args(RNODE_RETURN(node)->nd_stts);
89358946
LABEL *splabel = 0;
89368947

89378948
while (t == ISEQ_TYPE_RESCUE || t == ISEQ_TYPE_ENSURE) {

parse.y

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14350,9 +14350,6 @@ ret_args(struct parser_params *p, NODE *node)
1435014350
{
1435114351
if (node) {
1435214352
no_blockarg(p, node);
14353-
if (nd_type_p(node, NODE_LIST) && !RNODE_LIST(node)->nd_next) {
14354-
node = RNODE_LIST(node)->nd_head;
14355-
}
1435614353
}
1435714354
return node;
1435814355
}

test/ruby/test_ast.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ def m(a)
805805
kw: nil
806806
kwrest: nil
807807
block: nil)
808-
body: (RETURN@2:2-2:10 (LVAR@2:9-2:10 :a)))))
808+
body: (RETURN@2:2-2:10 (LIST@2:9-2:10 (LVAR@2:9-2:10 :a) nil)))))
809809
EXP
810810
end
811811

0 commit comments

Comments
 (0)