summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJemma Issroff <[email protected]>2023-12-07 14:13:33 -0500
committerJemma Issroff <[email protected]>2023-12-07 15:29:35 -0500
commita0c7bb4328c981be5f3f0e82e7ef75fc8bbd51b6 (patch)
treeadf072ec21ffe92d00c4ac9485eb1ac680004438
parent7738b31d390e70b26e913d86c133a70c8e65a645 (diff)
[PRISM] Account for multiple arguments when compiling ArgumentsNode
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
-rw-r--r--prism_compile.c7
-rw-r--r--test/ruby/test_compile_prism.rb25
2 files changed, 29 insertions, 3 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 1eeecc5c2a..71fd05dddf 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -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: {
@@ -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;
@@ -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;
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb
index 1bc08d2db6..50bb61c99d 100644
--- a/test/ruby/test_compile_prism.rb
+++ b/test/ruby/test_compile_prism.rb
@@ -742,6 +742,8 @@ module Prism
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
@@ -833,6 +835,13 @@ module Prism
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
begin
@@ -1001,7 +1010,20 @@ module Prism
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|
@@ -1010,6 +1032,7 @@ module Prism
end
prism_test_return_node
CODE
+
assert_prism_eval(<<-CODE)
def self.prism_test_return_node
[1].map do |i|