diff options
| author | Matt Valentine-House <matt@eightbitraptor.com> | 2024-01-17 13:59:30 +0000 |
|---|---|---|
| committer | Matt Valentine-House <matt@eightbitraptor.com> | 2024-01-17 14:48:46 +0000 |
| commit | ef4a08eb65ab00eb0101b8b64212bef613e4f833 (patch) | |
| tree | a08aac45c4b491d280657184cb1b5b973bacfaf8 | |
| parent | e17c83e02c5019f7a8c31b31a567ab6de6d6c7f4 (diff) | |
[PRISM] Fix stack inconsistency in MultiWriteNode
| -rw-r--r-- | prism_compile.c | 12 | ||||
| -rw-r--r-- | test/ruby/test_compile_prism.rb | 4 |
2 files changed, 13 insertions, 3 deletions
diff --git a/prism_compile.c b/prism_compile.c index 722dabf8ab..55bc348492 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -5216,6 +5216,8 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_multi_write_node_t *multi_write_node = (pm_multi_write_node_t *)node; pm_node_list_t *lefts = &multi_write_node->lefts; pm_node_list_t *rights = &multi_write_node->rights; + bool has_rest_expression = (multi_write_node->rest && + PM_NODE_TYPE_P(multi_write_node->rest, PM_SPLAT_NODE)); size_t argc = 1; // pre-process the left hand side of multi-assignments. @@ -5313,9 +5315,13 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, PM_COMPILE(rights->nodes[index]); } } - else if (rest_expression) { - ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(0), INT2FIX(1)); - PM_COMPILE(rest_expression); + else if (has_rest_expression) { + if (rest_expression) { + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(0), INT2FIX(1)); + PM_COMPILE(rest_expression); + } else if (!lefts->size && !PM_NODE_TYPE_P(multi_write_node->value, PM_SPLAT_NODE)){ + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(0), INT2FIX(0)); + } } return; diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index bc9f0b3aba..9b4e998b27 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -543,6 +543,10 @@ module Prism assert_prism_eval("_, {}[:foo], _ = 1") assert_prism_eval("_, {}[:foo], _ = 1") assert_prism_eval("_,{}[:foo], _, {}[:bar] = 1") + assert_prism_eval("* = :foo") + assert_prism_eval("* = *[]") + assert_prism_eval("a, * = :foo") + assert_prism_eval(<<~CODE) class Foo |
