[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
This commit is contained in:
Jemma Issroff 2023-12-07 14:13:33 -05:00
Родитель 7738b31d39
Коммит a0c7bb4328
2 изменённых файлов: 29 добавлений и 3 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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
@ -832,6 +834,13 @@ module Prism
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
@ -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|