From 7c6d7fbc28904b9814a18cc06796e0f12552778a Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Fri, 12 Jan 2024 13:04:59 -0500 Subject: [PATCH] [PRISM] Fix case without predicate Fixes ruby/prism#2149. --- prism_compile.c | 44 +++++++++++++++------------------ test/ruby/test_compile_prism.rb | 10 ++++++++ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/prism_compile.c b/prism_compile.c index a9d417550f3af8..79a122059f1628 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -3408,42 +3408,38 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, for (size_t i = 0; i < conditions.size; i++) { label = NEW_LABEL(lineno); conditions_labels[i] = label; - if (has_predicate) { - pm_when_node_t *when_node = (pm_when_node_t *)conditions.nodes[i]; + pm_when_node_t *when_node = (pm_when_node_t *)conditions.nodes[i]; - for (size_t i = 0; i < when_node->conditions.size; i++) { - pm_node_t *condition_node = when_node->conditions.nodes[i]; + for (size_t i = 0; i < when_node->conditions.size; i++) { + pm_node_t *condition_node = when_node->conditions.nodes[i]; - if (PM_NODE_TYPE_P(condition_node, PM_SPLAT_NODE)) { - ADD_INSN (ret, &dummy_line_node, dup); - PM_COMPILE_NOT_POPPED(condition_node); - ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse); - ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); - } - else { - PM_COMPILE_NOT_POPPED(condition_node); + if (PM_NODE_TYPE_P(condition_node, PM_SPLAT_NODE)) { + ADD_INSN (ret, &dummy_line_node, dup); + PM_COMPILE_NOT_POPPED(condition_node); + ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse); + ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); + } + else { + PM_COMPILE_NOT_POPPED(condition_node); + if (has_predicate) { ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1)); ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idEqq, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); } - - ADD_INSNL(ret, &dummy_line_node, branchif, label); } - } - else { - ADD_INSNL(ret, &dummy_line_node, jump, label); - PM_PUTNIL; + + ADD_INSNL(ret, &dummy_line_node, branchif, label); } } if (has_predicate) { PM_POP; + } - if (case_node->consequent) { - PM_COMPILE((pm_node_t *)case_node->consequent); - } - else { - PM_PUTNIL_UNLESS_POPPED; - } + if (case_node->consequent) { + PM_COMPILE((pm_node_t *)case_node->consequent); + } + else { + PM_PUTNIL_UNLESS_POPPED; } ADD_INSNL(ret, &dummy_line_node, jump, end_label); diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 87221289e2930a..ca76a69accf8f3 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -794,6 +794,16 @@ def self.prism_test_case_node :ng end RUBY + + # Test case without predicate + assert_prism_eval(<<~RUBY) + case + when 1 == 2 + :ng + else + :ok + end + RUBY end def test_ElseNode