Skip to content

Commit

Permalink
[PRISM] Account for multiple arguments when compiling ArgumentsNode
Browse files Browse the repository at this point in the history
BreakNode, ReturnNode and NextNode all compile the ArgumentsNode
directly, but we weren't accounting for multiple arguments. If there
is more than one argument, we need to also emit a newarray
instruction to put the arguments onto the stack
  • Loading branch information
jemmaissroff committed Dec 7, 2023
1 parent 7738b31 commit a0c7bb4
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
7 changes: 5 additions & 2 deletions prism_compile.c
Expand Up @@ -1762,6 +1762,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
for (size_t index = 0; index < node_list.size; index++) {
PM_COMPILE(node_list.nodes[index]);
}
if (node_list.size > 1) {
ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(node_list.size));
}
return;
}
case PM_ARRAY_NODE: {
Expand Down Expand Up @@ -3578,7 +3581,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->start_label);

if (next_node->arguments) {
PM_COMPILE((pm_node_t *)next_node->arguments);
PM_COMPILE_NOT_POPPED((pm_node_t *)next_node->arguments);
}
else {
PM_PUTNIL;
Expand Down Expand Up @@ -3618,7 +3621,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
if (ip != 0) {
if (next_node->arguments) {
PM_COMPILE((pm_node_t *)next_node->arguments);
PM_COMPILE_NOT_POPPED((pm_node_t *)next_node->arguments);
}
else {
PM_PUTNIL;
Expand Down
25 changes: 24 additions & 1 deletion test/ruby/test_compile_prism.rb
Expand Up @@ -742,6 +742,8 @@ def test_BeginNode
def test_BreakNode
assert_prism_eval("while true; break; end")
assert_prism_eval("while true; break 1; end")
assert_prism_eval("while true; break 1, 2; end")

assert_prism_eval("[].each { break }")
end

Expand Down Expand Up @@ -832,6 +834,13 @@ def test_NextNode
res
CODE

assert_prism_eval(<<-CODE)
(1..5).map do |i|
next i, :even if i.even?
i
end
CODE

assert_prism_eval(<<-CODE)
res = []
i = 0
Expand Down Expand Up @@ -1001,7 +1010,20 @@ def test_RetryNode
end

def test_ReturnNode
assert_prism_eval("def return_node; return 1; end")
assert_prism_eval(<<-CODE)
def self.prism_test_return_node
return 1
end
prism_test_return_node
CODE

assert_prism_eval(<<-CODE)
def self.prism_test_return_node
return 1, 2
end
prism_test_return_node
CODE

assert_prism_eval(<<-CODE)
def self.prism_test_return_node
[1].each do |e|
Expand All @@ -1010,6 +1032,7 @@ def self.prism_test_return_node
end
prism_test_return_node
CODE

assert_prism_eval(<<-CODE)
def self.prism_test_return_node
[1].map do |i|
Expand Down

0 comments on commit a0c7bb4

Please sign in to comment.