[Prism] Fix IfNode and ElseNode

ElseNode looks to have been implemented at the same time as IfNode, but
was resulting in a stack underflow error.

The following is from the test code

```
if foo
  bar
end
```

```
❯ make run
compiling compile.c
linking miniruby
./miniruby -I./lib -I. -I.ext/common  -r./arm64-darwin22-fake  ./test.rb
CRUBY: **************************************************
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(2,19)>
0000 putself                                                          (   2)[Li]
0001 opt_send_without_block                 <calldata!mid:foo, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 branchunless                           9
0005 putself
0006 opt_send_without_block                 <calldata!mid:bar, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0008 pop
0009 putobject_INT2FIX_1_
0010 leave
PRISM: **************************************************
-- raw disasm--------
   0000 putself                                                          (   2)
   0001 send                 <calldata:foo, 0>, nil                      (   2)
   0004 branchunless         <L001>                                      (   2)
   0006 jump                 <L000>                                      (   2)
 <L000> [sp: 0]
*  0008 pop                                                              (   1)
   0009 putself                                                          (   2)
   0010 send                 <calldata:bar, 0>, nil                      (   2)
   0013 pop                                                              (   2)
   0014 jump                 <L002>                                      (   1)
 <L001> [sp: 0]
 <L002> [sp: -1]
   0016 putobject            1                                           (   2)
   0018 leave                                                            (   1)
---------------------
<compiled>: <compiled>:1: argument stack underflow (-1) (SyntaxError)
make: *** [run] Error 1
```

This commit fixes the stack underflow error for both IfNode and ElseNode
and introduces tests for them.
This commit is contained in:
Matt Valentine-House 2023-10-02 17:51:14 +01:00 коммит произвёл Kevin Newton
Родитель f834b1a40d
Коммит 05b9b58d55
2 изменённых файлов: 18 добавлений и 3 удалений

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

@ -407,7 +407,6 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body,
INIT_ANCHOR(then_seq);
if (node_body) {
pm_compile_node(iseq, (pm_node_t *)node_body, then_seq, src, popped, compile_context);
PM_POP_IF_POPPED;
} else {
PM_PUTNIL_UNLESS_POPPED;
}
@ -415,7 +414,6 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body,
if (else_label->refcnt) {
end_label = NEW_LABEL(line);
ADD_INSNL(then_seq, &dummy_line_node, jump, end_label);
PM_POP_UNLESS_POPPED;
}
ADD_SEQ(ret, then_seq);
}
@ -426,7 +424,7 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body,
DECL_ANCHOR(else_seq);
INIT_ANCHOR(else_seq);
if (node_else) {
pm_compile_node(iseq, (pm_node_t *)(((pm_else_node_t *)node_else)->statements), else_seq, src, popped, compile_context);
pm_compile_node(iseq, (pm_node_t *)node_else, else_seq, src, popped, compile_context);
}
else {
PM_PUTNIL_UNLESS_POPPED;
@ -1365,6 +1363,11 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse);
}
return;
case PM_ELSE_NODE: {
pm_else_node_t *cast = (pm_else_node_t *)node;
PM_COMPILE((pm_node_t *)cast->statements);
return;
}
case PM_FLIP_FLOP_NODE: {
// TODO: The labels here are wrong, figure out why.....
pm_flip_flop_node_t *flip_flop_node = (pm_flip_flop_node_t *)node;

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

@ -338,6 +338,18 @@ module Prism
test_prism_eval("false || 1")
end
def test_IfNode
test_prism_eval("if true; 1; end")
test_prism_eval("1 if true")
end
def test_ElseNode
test_prism_eval("if false; 0; else; 1; end")
test_prism_eval("if true; 0; else; 1; end")
test_prism_eval("true ? 1 : 0")
test_prism_eval("false ? 0 : 1")
end
############################################################################
# Calls / arugments #
############################################################################