Fix interpolated sybmol node instructions

If the symbol node is interpolated like this `:"#{foo}"` the instruction
sequence should be `putstring` followed by `intern`. In this case it was
a `putobject` causing the `test_yjit` tests to fail. Note that yjit is
not required to reproduce - the instructions are `putstring` and
`intern` for yjit and non-yjit with the original parser.

To fix I moved `pm_interpolated_node_compile` out of the else, and
entirely removed the conditional. `pm_interpolated_node_compile` knows
how / when to use `putstring` over `putobject` already. The `intern` is
then added by removing the conditional.

Before:

```
== disasm: #<ISeq:<main>@test2.rb:1 (1,0)-(1,11)>
0000 putobject                              :foo                      (   1)[Li]
0002 leave
```

After:

```
== disasm: #<ISeq:<main>@test2.rb:1 (1,0)-(1,11)>
0000 putstring                              "foo"                     (   1)[Li]
0002 intern
0003 leave
```

Fixes the test `TestYJIT#test_compile_dynamic_symbol`. Related to ruby/prism#2935
This commit is contained in:
eileencodes 2024-07-17 15:37:48 -04:00 committed by Kevin Newton
parent 8db2325a11
commit 69e65b9b5a
Notes: git 2024-07-19 01:16:02 +00:00

View File

@ -7452,25 +7452,17 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// :"foo #{bar}"
// ^^^^^^^^^^^^^
const pm_interpolated_symbol_node_t *cast = (const pm_interpolated_symbol_node_t *) node;
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, popped, scope_node, NULL, NULL);
if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) {
if (!popped) {
VALUE symbol = pm_static_literal_value(iseq, node, scope_node);
PUSH_INSN1(ret, location, putobject, symbol);
}
if (length > 1) {
PUSH_INSN1(ret, location, concatstrings, INT2FIX(length));
}
if (!popped) {
PUSH_INSN(ret, location, intern);
}
else {
int length = pm_interpolated_node_compile(iseq, &cast->parts, &location, ret, popped, scope_node, NULL, NULL);
if (length > 1) {
PUSH_INSN1(ret, location, concatstrings, INT2FIX(length));
}
if (!popped) {
PUSH_INSN(ret, location, intern);
}
else {
PUSH_INSN(ret, location, pop);
}
PUSH_INSN(ret, location, pop);
}
return;