Aaron Patterson
7a33a1aee2
Insert all locals in the locals index table
...
Prism provides an index (local_body_index) which is supposed to point at
the start of locals declared in the method body. Prism assumed that
method body locals would only occur _after_ parameter names.
Unfortunately this assumption is not correct, which meant that we would
in some cases not insert all locals in the local table. This commit
iterates over locals a second time, inserting any that didn't get
inserted on the first pass.
Fixes: https://github.com/ruby/prism/issues/2245
Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com>
2024-01-24 09:40:30 -08:00
Peter Zhu
927928badb
[PRISM] Fix anonymous keyword arguments
...
Fixes ruby/prism#2256 .
2024-01-24 11:41:08 -05:00
Kevin Newton
4220bdba39
[PRISM] Remove dead code from prism_compile.c
...
Previously, we were using the main pm_compile_node switch to compile
target nodes. Eventually we switched to pm_compile_target_node and
updated all the call sites. As such, all of this has become dead
code.
However, the multi target code was reused for both parameters and
multi writes (it was just incorrect for multi writes). So that code
has now been moved into its own function that is more specific to
destructured parameters (and has more assertions to that effect).
Overall now you should not see target nodes when you call into
pm_compile_node, since they are more specialized and require more
special handling.
2024-01-24 11:18:58 -05:00
Kevin Newton
767f5d045f
[PRISM] Use lvar depths for starting
2024-01-24 10:37:08 -05:00
Peter Zhu
529700d314
[PRISM] Nested MultiWriteNode with method calls
...
Fixes ruby/prism#2247 .
2024-01-24 10:08:25 -05:00
Peter Zhu
909a710a69
[PRISM] Fix anonymous splat nodes
...
Fixes ruby/prism#2257 .
2024-01-23 17:45:51 -05:00
Peter Zhu
cecf42601a
[PRISM] Fix block fowarding
2024-01-23 15:23:13 -05:00
Peter Zhu
333f4b4930
[PRISM] Support block parameters with no name
...
Fixes ruby/prism#2249 .
2024-01-23 15:23:13 -05:00
Aaron Patterson
cfa15bb173
Handle trailing commas on blocks
...
We need to set a special flag on block iseqs when there is a trailing
comma.
Fixes: https://github.com/ruby/prism/issues/2244
2024-01-22 16:35:58 -08:00
Aaron Patterson
270a46e392
Check keyword parameters correctly
...
We weren't checking the right offsets when compiling methods with
keyword parameters that had complex code.
Fixes: https://github.com/ruby/prism/issues/2228
2024-01-22 16:02:41 -08:00
Peter Zhu
708fa77404
[PRISM] Fix keyword arguments in IndexOrWriteNode
...
Fixes ruby/prism#2236 .
2024-01-22 15:07:52 -08:00
Peter Zhu
1838dbf6e7
[PRISM] Fix splat and block in aset
2024-01-22 15:07:39 -08:00
Peter Zhu
1847192366
[PRISM] Fix block in aset
...
Fixes ruby/prism#2223 .
2024-01-22 15:07:39 -08:00
Peter Zhu
8065672d99
[PRISM] Force semicolon at the end of PM macros
2024-01-22 15:22:12 -05:00
Peter Zhu
2630941696
[PRISM] Use PM_SWAP macro
2024-01-22 15:21:09 -05:00
Peter Zhu
789de5972b
[PRISM] Use PM_POP macro
2024-01-22 15:16:14 -05:00
Aaron Patterson
7db6832225
Fix compiling rescue + ensure
...
When we're compiling begin / rescue / ensure nodes, we need to "wrap"
the code in the begin statements correctly. The wrapping is like this:
(ensure code (rescue code (begin code)))
This patch pulls the each leg in to its own function, then calls the
appropriate wrapping function depending on whether there are ensure /
rescue legs.
Fixes: https://github.com/ruby/prism/issues/2221
2024-01-22 12:02:03 -08:00
Peter Zhu
dbd76d9101
[PRISM] Fix keyword splat in IndexAndWriteNode and IndexOrWriteNode
...
Fixes ruby/prism#2232 and ruby/prism#2234 .
2024-01-22 12:56:43 -05:00
Kevin Newton
ab99ce910c
[PRISM] Insert concatarray for index targets with splat
2024-01-22 12:55:06 -05:00
Kevin Newton
e5f8585a29
[PRISM] Fix line for leave instructions
2024-01-22 12:54:32 -05:00
Peter Zhu
a7af34fa8b
[PRISM] Fix keywords arguments in IndexAndWriteNode
...
Fixes ruby/prism#2233 .
2024-01-22 11:26:21 -05:00
Kevin Newton
6401f282d2
[PRISM] Fix up source line for 1-indexed line numbers
2024-01-22 11:21:04 -05:00
Kevin Newton
d68aaa6672
[PRISM] Freeze regex literals in iseqs
2024-01-22 11:12:38 -05:00
Peter Zhu
580429d27c
[PRISM] Fix incorrect ordering of MultiTargetNode
...
Fixes ruby/prism#2218 .
2024-01-22 10:51:43 -05:00
Matt Valentine-House
2abf153016
[PRISM] Add TP call/return events to method ISEQs
2024-01-22 09:40:52 -05:00
Kevin Newton
99d6e2f1ee
[PRISM] Revisit target nodes
2024-01-19 20:12:07 -05:00
eileencodes
ed50161bd6
[PRISM] Fix ensure code running twice
...
Fixes : ruby/prism#2212
2024-01-19 13:04:01 -08:00
Aaron Patterson
4778b0eeda
Fix kwarg ordering
...
Required keyword arguments need to come first.
Fixes: https://github.com/ruby/prism/issues/2158
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
2024-01-19 12:32:20 -08:00
Peter Zhu
740f0b52e0
[PRISM] Fix typo with pm_scope_node_destroy
...
We need to run the pm_scope_node_destroy after compiling the iseq.
2024-01-19 14:09:32 -05:00
Aaron Patterson
efe4b8ac0f
Fix ensure code when running break in a while loop
...
We need to run ensure code when breaking from a while loop
Co-authored-by: John Hawthorn <jhawthorn@github.com>
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
2024-01-19 09:35:36 -08:00
Peter Zhu
5a5cf23d02
[PRISM] Fix indentation for PM_SCOPE_NODE [ci skip]
2024-01-19 11:18:47 -05:00
Peter Zhu
c28094d385
[PRISM] Add function to free scope node
...
pm_scope_node_destroy frees the scope node after we're done using it to
make sure that the index_lookup_table is not leaked.
For example:
10.times do
100_000.times do
RubyVM::InstructionSequence.compile_prism("begin; 1; rescue; 2; end")
end
puts `ps -o rss= -p #{$$}`
end
Before:
33056
50304
67776
84544
101520
118448
135712
152352
169136
186656
After:
15264
15296
15408
17040
17152
17152
18320
18352
18400
18608
2024-01-18 16:33:25 -05:00
Peter Zhu
47081c3ee3
[PRISM] Pass pm_scope_node_t by reference
...
We can pass pm_scope_node_t by reference to pm_new_child_iseq rather
than by value.
2024-01-18 16:33:25 -05:00
Matt Valentine-House
60dd731125
[PRISM] Correct checkmatch flags for splat in rescue
2024-01-18 20:25:28 +00:00
Matt Valentine-House
8a3e7f08b8
[PRISM] Fix case splat with no predicate
2024-01-18 20:03:27 +00:00
Peter Zhu
686b1655a0
[PRISM] Fix indentation in switch [ci skip]
2024-01-18 14:59:59 -05:00
Peter Zhu
d8ac96efc5
[PRISM] Fix memory leak in case nodes
...
The temporary array conditions_labels is heap allocated and never freed.
We can use alloca instead to stack allocate it so that we don't need to
manually free it.
For example:
code = "case; #{100.times.map { "when #{it}; " }.join}; end"
10.times do
10_000.times do
RubyVM::InstructionSequence.compile_prism(code)
end
puts `ps -o rss= -p #{$$}`
end
Before:
21376
30304
38800
47184
55456
64192
72288
80400
89040
97104
After:
13088
13632
13760
14016
14688
14992
15120
15232
15744
15744
2024-01-18 13:40:14 -05:00
Peter Zhu
00814fd672
[PRISM] Fix memory leak in iseq
...
rb_iseq_compile_prism_node calls both rb_translate_prism and iseq_setup.
Both of these functions call iseq_set_sequence. This means that the first
iseq_set_sequence will leak because the iseq will be overwritten.
For example:
10.times do
100_000.times do
RubyVM::InstructionSequence.compile_prism("")
end
puts `ps -o rss= -p #{$$}`
end
Before:
20528
27328
33840
40208
46400
52960
59168
65600
71888
78352
After:
13696
13712
13712
13712
13712
14352
14352
14992
14992
14992
2024-01-18 10:35:46 -05:00
eileencodes
db9f5fc916
[Prism] Implement defined? for PM_UNLESS_NODE
...
Ruby code:
```ruby
defined?(unless true; 1; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
555af5e599
[Prism] Implement defined? for PM_UNTIL_NODE
...
Ruby code:
```ruby
defined?(until a == 1; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
24d02cd485
[Prism] Implement defined? for PM_WHILE_NODE
...
Ruby code:
```ruby
defined?(while a != 1; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
b5d3d61130
[Prism] Implement defined? for PM_SINGLETON_CLASS_NODE
...
Ruby code:
```ruby
defined?(class << self; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
d2000e0e6c
[Prism] Implement defined? for PM_RATIONAL_NODE
...
Ruby code:
```ruby
defined?(1.2r)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
913772a08a
[Prism] Implement defined? for PM_MODULE_NODE
...
Ruby code:
```ruby
defined?(module M; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
a9a22b9f2d
[Prism] Implement defined? for PM_MATCH_REQUIRED_NODE
...
Ruby code:
```ruby
defined?(1 => 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
b40fc4f0a7
[Prism] Implement defined? for PM_MATCH_WRITE_NODE
...
Ruby code:
```ruby
defined?(/(?<foo>bar)/ =~ 'barbar')
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,35)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] foo@0
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,35)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] foo@0
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
a2092ef207
[Prism] Implement defined? for PM_IF_NODE
...
Ruby code:
```ruby
defined?(if true; 1; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,43)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,43)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
fb1eed3f70
[Prism] Implement defined? for PM_FOR_NODE
...
Ruby code:
```ruby
defined?(for i in [1,2] do; i; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,43)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,43)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
7460820fec
[Prism] Implement defined? for PM_DEF_NODE
...
Ruby code:
```ruby
defined?(def prism_test_def_node; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,43)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,43)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
30e7dbb78d
[Prism] Implement defined? for PM_CLASS_NODE
...
Ruby code:
```ruby
defined?(class PrismClassA; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,43)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,43)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
9bcd42c378
[Prism] Implement defined? for PM_CASE_MATCH_NODE
...
Ruby code:
```ruby
defined?(case [1, 2, 3]; in [1, 2, 3]; 4; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,43)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,43)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
eileencodes
75bed8c61a
[Prism] Implement defined? for PM_CASE_NODE
...
Ruby code:
```ruby
defined?(case :a; when :a; 1; else; 2; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,43)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,43)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 17:21:29 -05:00
Peter Zhu
9f0d38960f
[PRISM] Refactor keyword hash nodes
...
Follow up to #9540 .
2024-01-17 17:07:51 -05:00
Peter Zhu
00f9456f16
[PRISM] Remove unnecessary flag setting
...
VM_CALL_KW_SPLAT and VM_CALL_KW_SPLAT_MUT are guaranteeed to be set in
this code path, so we don't need to set it again.
2024-01-17 17:07:51 -05:00
eileencodes
e1bae2c693
[Prism] Implement defined? for PM_INDEX_OR_WRITE_NODE
...
Ruby code:
```ruby
defined?([0][0] ||= 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
ff54a8f4c7
[Prism] Implement defined? for PM_INDEX_OPERATOR_WRITE_NODE
...
Ruby code:
```ruby
defined?([0][0] += 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
f8ef77af3b
[Prism] Implement defined? for PM_INDEX_AND_WRITE_NODE
...
Ruby code:
```ruby
defined?([0][0] &&= 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
e217c5772b
[Prism] Implement defined? for PM_CONSTANT_PATH_WRITE_NODE
...
Ruby code:
```ruby
defined?(Prism::CPWN = 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
54b8330e45
[Prism] Implement defined? for PM_CONSTANT_PATH_OR_WRITE_NODE
...
Ruby code:
```ruby
defined?(Prism::CPOrWN ||= 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
3c9dc2f806
[Prism] Implement defined? for PM_CONSTANT_PATH_OPERATOR_WRITE_NODE
...
Ruby code:
```ruby
defined?(Prism::CPOWN += 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
98d6f50312
[Prism] Implement defined? for PM_CONSTANT_PATH_AND_WRITE_NODE
...
Ruby code:
```ruby
defined?(Prism::CPAWN &&= 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
7522e867ee
[Prism] Implement defined? for PM_CALL_OR_WRITE_NODE
...
Ruby code:
```ruby
defined?(PrismTestSubclass.test_call_or_write_node ||= 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
9c5391d7dc
[Prism] Implement defined? for PM_CALL_OPERATOR_WRITE_NODE
...
Ruby code:
```ruby
defined?(PrismTestSubclass.test_call_operator_write_node += 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
eileencodes
f657fd150f
[Prism] Implement defined? for PM_CALL_AND_WRITE_NODE
...
Ruby code:
```ruby
defined?(PrismTestSubclass.test_call_and_write_node &&= 1)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,58)>
0000 putobject "assignment" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,58)>
0000 putobject "assignment" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 13:08:49 -08:00
Peter Zhu
ebc4704696
[PRISM] Fix indentation in pm_setup_args [ci skip]
2024-01-17 14:45:05 -05:00
Peter Zhu
f43a919be4
[PRISM] Fix fallthrough for PM_ENSURE_NODE
...
This caused it to fall into PM_ELSE_NODE which caused ensure nodes to be
compiled twice.
Fixes ruby/prism#2176 .
2024-01-17 13:17:44 -05:00
Peter Zhu
947194aacb
[PRISM] Fix memory leak of ST table
...
This commit fixes a memory leak in rb_translate_prism because the ST
table is never freed. There are still more memory leaks which still need
to be fixed.
For example:
10.times do
100_000.times do
RubyVM::InstructionSequence.compile_prism("")
end
puts `ps -o rss= -p #{$$}`
end
Before:
34544
57120
79360
102176
123712
146320
168192
190592
212192
234896
After:
18336
24592
31488
37648
44592
50944
57280
63632
69904
76160
2024-01-17 11:35:30 -05:00
eileencodes
78ad91f83f
[Prism] Fix more method call argumnents
...
In #2087 it was noted that there was a bug in the number of arguments in
`SplatNode` and `KeywordHashNode`. I looked into this with Aaron before
the linked PR was merged and we found a bunch of cases that weren't
working quite right. This PR aims to fix some of those cases, but there
may be more.
A splat argument followed by a positional argument will concat the array
until the end or unless the argument is a kwarg or splat kwarg. For
example
```
foo(a, *b, c, *d, e)
```
Will have an `argc` of 2, because `b`, `c`, `d`, and `e` will be
concatenated together.
```
foo(a, *b, c, *d, **e)
```
Will have an `argc` of 3, because `b`, `c`, and `d` will be concatenated
together and `e` is a separate argument.
2024-01-17 10:57:19 -05:00
eileencodes
dcf9d77b45
[Prism] Implement defined? for PM_BEGIN_NODE
...
Ruby code:
```ruby
defined?(begin; 1; end)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,23)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,23)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
338aa465c0
[Prism] Implement defined? for PM_RETRY_NODE
...
Ruby code:
```ruby
defined?(retry)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,15)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,15)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
8774abad55
[Prism] Implement defined? for PM_RETURN_NODE
...
Ruby code:
```ruby
defined?(return)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,16)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,16)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
d0a7c33f05
[Prism] Implement defined? for PM_REDO_NODE
...
Ruby code:
```ruby
defined?(redo)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,14)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,14)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
2697acf7ff
[Prism] Implement defined? for PM_INTERPOLATED_X_STRING_NODE
...
Ruby code:
```ruby
defined?(`echo #{1}`)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,21)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,21)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
e0c90199c9
[Prism] Implement defined? for PM_INTERPOLATED_SYMBOL_NODE
...
Ruby code:
```ruby
defined?(:"1 #{1 + 2} 1")
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,25)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,25)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
25f1a8e447
[Prism] Implement defined? for PM_DEFINED_NODE
...
Ruby code:
```ruby
defined?(defined?(a))
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,21)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,21)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
82ed90950e
[Prism] Implement defined? for PM_BREAK_NODE
...
Ruby code:
```ruby
defined?(break)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,15)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,15)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
eileencodes
0c814092ee
[Prism] Implement defined for PM_NEXT_NODE
...
Ruby code:
```ruby
defined?(next)
```
Instructions
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(59,15)>
0000 putobject "expression" ( 59)[Li]
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:58 (58,0)-(58,15)>
0000 putobject "expression" ( 58)[Li]
0002 leave
```
Related: ruby/prism#2188
2024-01-17 10:17:59 -05:00
Matt Valentine-House
ef4a08eb65
[PRISM] Fix stack inconsistency in MultiWriteNode
2024-01-17 14:48:46 +00:00
Peter Zhu
07b9b53459
[PRISM] Fix crash with empty ensure blocks
...
Fixes ruby/prism#2179 .
2024-01-16 12:55:57 -05:00
Matt Valentine-House
7bd7030a96
[PRISM] Replace local lookup recursion with loop
2024-01-16 12:43:53 -05:00
Peter Zhu
70a8ed0775
[PRISM] Don't allocate labels when not needed
...
The labels lstart, lend, lcont are only needed when there is a rescue
clause. They are not needed when there is only an ensure clause or
neither.
2024-01-16 12:43:14 -05:00
Peter Zhu
1caa881a56
[PRISM] Fix splat assignment
...
Fixes ruby/prism#2177
2024-01-16 11:12:06 -05:00
Matt Valentine-House
fef8ccff11
Rename pm_lookup_local_index_any_scope
...
Now it's the only local lookup function we can just call it
pm_lookup_local_index
2024-01-16 14:58:55 +00:00
Matt Valentine-House
543bd7f3db
Remove scope_node->local_depth_offset
2024-01-16 14:58:55 +00:00
Matt Valentine-House
1b97f61168
Remove pm_lookup_local_index_with_depth
2024-01-16 14:58:55 +00:00
Matt Valentine-House
0d705b342f
Remove the found_depth pointer
...
Now that we're returning pm_local_index_t
2024-01-16 14:58:55 +00:00
Matt Valentine-House
da383c0d74
Return pm_local_index_t when looking up local indexes
...
instead of returning the index and updating found_depth in the parent
scope
2024-01-16 14:58:55 +00:00
Matt Valentine-House
f4b299a1ed
Bind index & depth together into pm_local_index_t
2024-01-16 14:58:55 +00:00
Matt Valentine-House
3d45b743e4
Replace pm_lookup_local_index with lookup_local_index_with_depth
2024-01-16 14:58:55 +00:00
Peter Zhu
0520e9675b
[PRISM] Fix defined? for chained calls
...
Fixes ruby/prism#2148 .
2024-01-16 08:32:21 -05:00
Peter Zhu
6a175902f4
[PRISM] Fix keyword splat inside of array
...
Fixes ruby/prism#2155 .
2024-01-15 17:12:53 -05:00
Peter Zhu
7c6d7fbc28
[PRISM] Fix case without predicate
...
Fixes ruby/prism#2149 .
2024-01-15 09:58:44 -05:00
Aaron Patterson
475663f039
Only intern constants upon compilation entry
...
Before this commit the Prism compiler would try to intern constants
every time it re-entered. This pool of constants is "constant" (there is
only one pool per parser instance), so we should do it only once: upon
the top level entry to the compiler.
This change does just that: it populates the interned constants once.
Fixes: https://github.com/ruby/prism/issues/2152
2024-01-12 14:53:14 -08:00
Aaron Patterson
2c27a3a0dd
Fix splat assigns with no lefties
...
We still need to emit an expand array even if there's no "left side"
variables
Fixes: https://github.com/ruby/prism/issues/2153
2024-01-12 12:46:28 -08:00
Aaron Patterson
774eef692c
Always freeze strings that are in the instructions
...
Any objects that the instructions reference should be frozen.
Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com>
2024-01-12 12:20:04 -08:00
Jemma Issroff
84f14ff089
[PRISM] Pre-concatenate Strings in InterpolatedStringNode
...
This commit concatenates String VALUEs within
InterpolatedStringNodes to allow us to preserve frozenness of
concatenated strings such as `"a""b"`
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2024-01-12 12:20:04 -08:00
Peter Zhu
0462b1b350
[PRISM] Fix splat in when
...
Fixes ruby/prism#2147 .
2024-01-12 13:04:23 -05:00
Kevin Newton
2d9db72d37
Write to constant path, call, and index in rescue
...
When compiling a rescue reference, you can write to a constant
path, a call, or an index. In these cases we need to compile the
prefix expression first, then handle actually doing the write/call.
2024-01-12 11:30:25 -05:00
Aaron Patterson
371256775f
Anonymous rest nodes should increase the local table size
...
When we calculate the local table size, we need to account for anonymous
"rest" parameters. Since they don't have a name, they won't be in the
"locals" table that Prism provides, but we need to reserve room for them
anyway.
Fixes: https://github.com/ruby/prism/issues/2154
2024-01-11 15:53:52 -08:00
Peter Zhu
45dd8edf82
[PRISM] Fix splat inside of aset
...
Fixes ruby/prism#2146 .
2024-01-11 14:58:24 -05:00
Aaron Patterson
f2149dc094
[PRISM] Support repeated required parameter names.
...
Fixes: https://github.com/ruby/prism/issues/2062
This patch only fixes positional parameters, we still need to fix the
other cases spelled out in test/prism/fixtures/repeat_parameters.txt
2024-01-11 11:31:59 -08:00
Peter Zhu
51061b6631
[PRISM] Don't increment argc for PM_ASSOC_SPLAT_NODE
...
Fixes ruby/prism#2087 .
2024-01-10 13:32:19 -05:00
Peter Zhu
55b7121358
[PRISM] Frozen string literals should be fstrings
...
Frozen string literals should not just be frozen, but deduplicated as an
fstring so that two string literals with the same contents are the exact
same object.
Fixes ruby/prism#2095 .
2024-01-09 12:24:18 -05:00
Matt Valentine-House
47ff4a1658
[PRISM] Blocks should track the found local depth
...
Rather than rely purely on local depth offset. This is because we can't
assume a specific depth offset for all variable accesses happening
within a block in the same way that we can for rescue/ensure/for or
other nodes that push scopes.
This is because block parameters are defined in the scope level, so we
always need to start from the top most scope and walk backwards.
Fixes ruby/prism@2053
2024-01-08 19:55:26 +00:00
Kevin Newton
04f64608e8
Sync to latest prism
2024-01-02 09:13:43 -08:00
Matt Valentine-House
3d984366ca
[PRISM] Correct the jump target for redo in FOR_NODE
2023-12-19 22:50:59 +00:00
Matt Valentine-House
371ff80840
[PRISM] Fix parameter numbering in For Node
2023-12-19 22:50:59 +00:00
eileencodes
b8074c2f04
[PRISM] Fix incorrect instructions for `default_proc=`
...
This is kind of specific and was found via debugging ruby/prism#2061 but
does not actually fix that issue.
The change here checks for `!popped` for the additional instructions
that are normally added for nodes with the `attribute_write` flag.
I also removed the extra catch table by deleting the
`ISEQ_COMPILE_DATA(iseq)->catch_except_p = true;` line. I'm...not
entirely sure why it was added but it doesn't match the upstream
compiler
[code](92b10f5be7/compile.c (L887-L892)
).
The changes here unfortunately don't improve the test failures mentioned in
the linked issue so we still have other issues with instructions for
hashes.
Instructions before:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(34,8)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] h@0
0000 putnil ( 32)[Li]
0001 putobject true
0003 getconstant :Hash
0005 send <calldata!mid:new, argc:0, ARGS_SIMPLE>, nil
0008 setlocal h@0, 0
0011 getlocal h@0, 0 ( 33)[Li]
0014 putspecialobject 1
0016 send <calldata!mid:lambda, argc:0, FCALL>, block in <compiled>
0019 send <calldata!mid:default_proc=, argc:1, ARGS_SIMPLE>, nil
0022 pop
0023 getlocal h@0, 0 ( 34)[Li]
0026 putobject :nope
0028 send <calldata!mid:[], argc:1, ARGS_SIMPLE>, nil
0031 leave
== disasm: #<ISeq:block in <compiled>@<compiled>:33 (33,19)-(33,32)>
local table (size: 2, argc: 2 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] _@0<Arg> [ 1] _@1<Arg>
0000 putobject true ( 33)[LiBc]
0002 leave [Br]
true
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:31 (31,0)-(33,8)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] h@0
0000 putnil ( 31)[Li]
0001 putobject true
0003 getconstant :Hash
0005 send <calldata!mid:new, argc:0, ARGS_SIMPLE>, nil
0008 setlocal h@0, 0
0011 putnil ( 32)[Li]
0012 getlocal h@0, 0
0015 putspecialobject 1
0017 send <calldata!mid:lambda, argc:0, FCALL>, block in <compiled>
0020 setn 2
0022 send <calldata!mid:default_proc=, argc:1, ARGS_SIMPLE>, nil
0025 pop
0026 pop
0027 getlocal h@0, 0 ( 33)[Li]
0030 putobject :nope
0032 send <calldata!mid:[], argc:1, ARGS_SIMPLE>, nil
0035 leave ( 31)
== disasm: #<ISeq:block in <compiled>@<compiled>:32 (32,17)-(32,32)>
== catch table
| catch type: redo st: 0000 ed: 0002 sp: 0000 cont: 0000
| catch type: next st: 0000 ed: 0002 sp: 0000 cont: 0002
|------------------------------------------------------------------------
local table (size: 2, argc: 2 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] _@0<Arg> [ 1] _@1<Arg>
0000 putobject true ( 32)[LiBc]
0002 leave [Br]
```
Instructions after:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(34,8)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] h@0
0000 putnil ( 32)[Li]
0001 putobject true
0003 getconstant :Hash
0005 send <calldata!mid:new, argc:0, ARGS_SIMPLE>, nil
0008 setlocal h@0, 0
0011 getlocal h@0, 0 ( 33)[Li]
0014 putspecialobject 1
0016 send <calldata!mid:lambda, argc:0, FCALL>, block in <compiled>
0019 send <calldata!mid:default_proc=, argc:1, ARGS_SIMPLE>, nil
0022 pop
0023 getlocal h@0, 0 ( 34)[Li]
0026 putobject :nope
0028 send <calldata!mid:[], argc:1, ARGS_SIMPLE>, nil
0031 leave
== disasm: #<ISeq:block in <compiled>@<compiled>:33 (33,19)-(33,32)>
local table (size: 2, argc: 2 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] _@0<Arg> [ 1] _@1<Arg>
0000 putobject true ( 33)[LiBc]
0002 leave [Br]
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:31 (31,0)-(33,8)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] h@0
0000 putnil ( 31)[Li]
0001 putobject true
0003 getconstant :Hash
0005 send <calldata!mid:new, argc:0, ARGS_SIMPLE>, nil
0008 setlocal h@0, 0
0011 getlocal h@0, 0 ( 32)[Li]
0014 putspecialobject 1
0016 send <calldata!mid:lambda, argc:0, FCALL>, block in <compiled>
0019 send <calldata!mid:default_proc=, argc:1, ARGS_SIMPLE>, nil
0022 pop
0023 getlocal h@0, 0 ( 33)[Li]
0026 putobject :nope
0028 send <calldata!mid:[], argc:1, ARGS_SIMPLE>, nil
0031 leave ( 31)
== disasm: #<ISeq:block in <compiled>@<compiled>:32 (32,17)-(32,32)>
local table (size: 2, argc: 2 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] _@0<Arg> [ 1] _@1<Arg>
0000 putobject true ( 32)[LiBc]
0002 leave [Br]
```
2023-12-15 16:23:06 -05:00
Matt Valentine-House
161787f9be
[PRISM] Compile CallTargetNode
2023-12-15 16:15:10 -05:00
Matt Valentine-House
5b6a4d8c12
[PRISM] Compile IndexTargetNode
2023-12-15 16:15:10 -05:00
Jemma Issroff
5587bd4b37
[PRISM] Implement safe navigation in CallNodes
...
This commit implements safe navigation for CallNodes,
CallAndWriteNodes and CallOperatorWriteNodes
2023-12-14 17:11:54 -05:00
Kevin Newton
d3deb1b823
[prism] Fix build with no asserts
2023-12-14 15:26:01 -05:00
Ufuk Kayserilioglu
d07fdc5ede
[PRISM] Fix keyword hash handling in method calls
...
* Start using the renamed `PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS` flag
to check if all keys of the keyword hash node are symbols.
* For arguments passed as a hash, start marking them as `KW_SPLAT_MUT` only if the number of entries in the hash is greater than 1 (which is what the old compiler used to do).
2023-12-14 14:08:37 -05:00
Kevin Newton
295d97ab4d
Pattern matching
2023-12-14 14:06:26 -05:00
eileencodes
5a66832952
[Prism] Fix cvar or assignment instructions
...
The instructions for `PM_CLASS_VARIABLE_OR_WRITE_NODE` were incorrect as
they were missing a `putnil`, a `defined`, and a `branchunless`.
I verified this is fixed via the instructions and running the following:
`RUBY_ISEQ_DUMP_DEBUG=prism make test/csv/interface/test_read_write.rb`.
These new instructions can't go in the defined function because
`defined?(@@fop ||= 1)` should return "assignment" not "class variable".
Instructions before:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(30,11)>
0000 putnil ( 30)[Li]
0001 defined class variable, :@@foo, true
0005 branchunless 14
0007 getclassvariable :@@foo, <is:0>
0010 dup
0011 branchif 20
0013 pop
0014 putobject 1
0016 dup
0017 setclassvariable :@@foo, <is:0>
0020 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:29 (29,0)-(29,11)>
0000 getclassvariable :@@foo, <is:0> ( 29)[Li]
0003 dup
0004 branchif 13
0006 pop
0007 putobject 1
0009 dup
0010 setclassvariable :@@foo, <is:0>
0013 leave
```
Instructions after:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(30,11)>
0000 putnil ( 30)[Li]
0001 defined class variable, :@@foo, true
0005 branchunless 14
0007 getclassvariable :@@foo, <is:0>
0010 dup
0011 branchif 20
0013 pop
0014 putobject 1
0016 dup
0017 setclassvariable :@@foo, <is:0>
0020 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:29 (29,0)-(29,11)>
0000 putnil ( 29)[Li]
0001 defined class variable, :@@foo, true
0005 branchunless 14
0007 getclassvariable :@@foo, <is:0>
0010 dup
0011 branchif 20
0013 pop
0014 putobject 1
0016 dup
0017 setclassvariable :@@foo, <is:0>
0020 leave
```
Fixes ruby/prism#2064
2023-12-14 13:48:38 -05:00
Jemma Issroff
7ac93e99a3
[PRISM] Account for multiple anonymous locals
...
This commit adjusts the local table size to be consistent regardless
of the number of anonymous locals.
2023-12-14 13:45:41 -05:00
Jemma Issroff
157e6c8a51
[PRISM] Check for static literal, excluding array, hash, range
2023-12-14 11:46:54 -05:00
Jemma Issroff
e71f011713
[PRISM] Fix bugs in compiling optional keyword parameters
...
This PR fixes two bugs when compiling optional keyword parameters:
- It moves keyword parameter compilation to STEP 5 in the parameters
sequence, where the rest of compilation happens. This is important
because keyword parameter compilation relies on the value of
body->param.keyword->bits_start which gets set in an earlier step
- It compiles array and hash values for keyword parameters, which
it didn't previously
2023-12-14 11:46:54 -05:00
Jemma Issroff
8e1c148fd9
[PRISM] Use frozen flag on StringNode
2023-12-14 11:14:45 -05:00
Matt Valentine-House
a10c11a66b
[PRISM] Add anon KW args to the block local table
2023-12-14 07:01:19 -05:00
eileencodes
110dbf62ac
[Prism] Fix InterpolatedMatchLastLine Instructions
...
I looked at this at RubyConf with Kevin, and we noticed that there was a
`putobject` empty string missing from the instructions. I just got back
around to implementing this and pushing a PR and while doing that
noticed that we also have a `getspecial` when we want a `getglobal`.
This change adds the `putobject` instruction and replaces the
`getspecial` with a `getglobal`. If we look at the parsetree for the
following code:
```ruby
$pit = '.oo'; if /"#{$pit}"/mix; end
```
We can see it has a `NODE_GVAR` and the [Ruby
compiler](a4b43e9264/compile.c (L10024-L10030)
) shows that should
use `getglobal.
```
@ NODE_SCOPE (id: 14, line: 1, location: (1,0)-(22,36))
+- nd_tbl: (empty)
+- nd_args:
| (null node)
+- nd_body:
@ NODE_BLOCK (id: 12, line: 22, location: (22,0)-(22,36))
+- nd_head (1):
| @ NODE_GASGN (id: 0, line: 22, location: (22,0)-(22,12))*
| +- nd_vid: :$pit
| +- nd_value:
| @ NODE_STR (id: 1, line: 22, location: (22,7)-(22,12))
| +- nd_lit: ".oo"
+- nd_head (2):
@ NODE_IF (id: 11, line: 22, location: (22,14)-(22,36))*
+- nd_cond:
| @ NODE_MATCH2 (id: 10, line: 22, location: (22,14)-(22,36))
| +- nd_recv:
| | @ NODE_DREGX (id: 2, line: 22, location: (22,17)-(22,31))
| | +- nd_lit: "\""
| | +- nd_next->nd_head:
| | | @ NODE_EVSTR (id: 4, line: 22, location: (22,19)-(22,26))
| | | +- nd_body:
| | | @ NODE_GVAR (id: 3, line: 22, location: (22,21)-(22,25))
| | | +- nd_vid: :$pit
| | +- nd_next->nd_next:
| | @ NODE_LIST (id: 7, line: 22, location: (22,26)-(22,27))
| | +- as.nd_alen: 1
| | +- nd_head:
| | | @ NODE_STR (id: 6, line: 22, location: (22,26)-(22,27))
| | | +- nd_lit: "\""
| | +- nd_next:
| | (null node)
| +- nd_value:
| @ NODE_GVAR (id: 9, line: 22, location: (22,14)-(22,36))
| +- nd_vid: :$_
+- nd_body:
| @ NODE_BEGIN (id: 8, line: 22, location: (22,32)-(22,32))
| +- nd_body:
| (null node)
+- nd_else:
(null node)
```
I'm struggling with writing a failing test, but the before/after
instructions show that `getglobal` is correct here. I compared the
instructions for the other `InterpolatedMatchLastLine` node tests
and they also used `getglobal`. I've edited the existing
`InterpolatedLastMatchLineNode` test so that it will use that instruction when
copied out of the test. Without the quotes it thinks it's just a
`MatchLastLineNode`.
Incorrect instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(22,36)>
0000 putstring ".oo" ( 22)[Li]
0002 setglobal :$pit
0004 putobject "\""
0006 getglobal :$pit
0008 dup
0009 objtostring <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0011 anytostring
0012 putobject "\""
0014 toregexp 7, 3
0017 getglobal :$_
0019 send <calldata!mid:=~, argc:1, ARGS_SIMPLE>, nil
0022 branchunless 30
0024 jump 26
0026 putnil
0027 jump 31
0029 pop
0030 putnil
0031 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:21 (21,0)-(21,36)>
0000 putstring ".oo" ( 21)[Li]
0002 setglobal :$pit
0004 putobject "\""
0006 getglobal :$pit
0008 dup
0009 objtostring <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0011 anytostring
0012 putobject "\""
0014 toregexp 7, 3
0017 getspecial 0, 0
0020 send <calldata!mid:=~, argc:1, ARGS_SIMPLE>, nil
0023 branchunless 31
0025 jump 27
0027 putnil
0028 jump 32
0030 pop
0031 putnil
0032 leave
```
Fixed instructions:
```
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(22,36)>
0000 putstring ".oo" ( 22)[Li]
0002 setglobal :$pit
0004 putobject "\""
0006 getglobal :$pit
0008 dup
0009 objtostring <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0011 anytostring
0012 putobject "\""
0014 toregexp 7, 3
0017 getglobal :$_
0019 send <calldata!mid:=~, argc:1, ARGS_SIMPLE>, nil
0022 branchunless 30
0024 jump 26
0026 putnil
0027 jump 31
0029 pop
0030 putnil
0031 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:21 (21,0)-(21,36)>
0000 putstring ".oo" ( 21)[Li]
0002 setglobal :$pit
0004 putobject "\""
0006 getglobal :$pit
0008 dup
0009 objtostring <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0011 anytostring
0012 putobject "\""
0014 toregexp 7, 3
0017 getglobal :$_
0019 send <calldata!mid:=~, argc:1, ARGS_SIMPLE>, nil
0022 branchunless 30
0024 jump 26
0026 putnil
0027 jump 31
0029 pop
0030 putnil
0031 leave
```
2023-12-13 13:42:17 -05:00
Takashi Kokubun
ea4a4c302c
[PRISM] Fix a -Wformat-zero-length warning
...
../prism_compile.c: In function ‘pm_compile_node’:
../prism_compile.c:2330:20: warning: zero-length gnu_printf format string [-Wformat-zero-length]
2330 | rb_bug("");
| ^~
2023-12-13 10:28:20 -08:00
John Hawthorn
02528f647d
[PRISM] Use xcalloc for iseq id table
...
We use xfree on the other end, so we need to use a form of xmalloc here.
Co-authored-by: Matthew Draper <matthew@trebex.net>
2023-12-13 10:20:11 -08:00
John Hawthorn
b55de590f3
[PRISM] Fix st_table memory leak
...
Co-authored-by: Matthew Draper <matthew@trebex.net>
2023-12-13 10:20:11 -08:00
Matt Valentine-House
9eba7a0892
[PRISM] Break nodes should add an entry to the parent catch table
2023-12-13 09:33:07 -05:00
Matt Valentine-House
cb8a9851ca
[PRISM] Remove errant NOP when redo_label is set
2023-12-13 09:33:07 -05:00
Matt Valentine-House
9267dbdd7a
[PRISM] Generate instruction for when redo_label is set
2023-12-13 09:33:07 -05:00
Ufuk Kayserilioglu
f390c51b15
[PRISM] Use `PM_KEYWORD_HASH_NODE_FLAGS_STATIC_KEYS` flag in compiler
2023-12-13 08:16:11 -05:00
Jemma Issroff
798a89fae1
[PRISM] If receiver on CallNode is SelfNode, use FCALL flags
2023-12-13 08:11:45 -05:00
eileencodes
1ad991c54d
[PRISM] Fix attrset edge cases
...
In some cases code may look like an attrset ID but should actually
return the value of the method, not the passed values.
In ruby/prism#2051 a flag was added when we have a attribute write call.
I used this flag to add the proper instructions when we have a real
attrset instead of using `rb_is_attrset_id` which was kind of hacky
anyway.
The value that should be returned in the newly added test is 42, not 2.
Previously the changes we had made returned 2.
Related to ruby/prism#1715
2023-12-13 08:11:21 -05:00
Jemma Issroff
196c24620e
[PRISM] Correctly parse non-base 10 integers in Prism
...
This commit passes an `end` to rb_int_parse_cstr which allows us
to correctly parse non-base 10 integers which are enclosed in
parenthesis. Prior to this commit, we were getting a putobject nil
when compiling `(0o0)` for example.
2023-12-12 22:00:50 -05:00
eileencodes
a6526342f3
[PRISM] Fix segv with regex once flag
...
When you have an interpolated regex with a `once` flag and local
variable is outside the block created by the `once` flag, Prism would
see a segv. This is because it was not taking the depth into account.
To fix this, we need to add 1 to the `local_depth_offset` on the
`scope`.
Fixes : ruby/prism#2047
2023-12-12 15:15:02 -05:00
Matt Valentine-House
43ede3f26c
[PRISM] Compile NextNode arguments
2023-12-12 13:46:36 -05:00
Jemma Issroff
b9dfe04a73
[PRISM] Implementing forwarding of args for ForwardingSuperNode
...
ForwardingSuperNodes need to actually forward any applicable
arguments. This commit implements that logic, by using the data
stored on the local iseq about the parameters to forward the
appropriate arguments.
2023-12-12 13:45:21 -05:00
Jemma Issroff
68753e4408
[PRISM] Allow rest parameter to be `*`
...
Prior to this commit, if a rest parameters was `*`, we did not add
it to the locals table correctly. This commit fixes that.
2023-12-12 13:45:21 -05:00
Nobuyoshi Nakada
f466afa176
[PRISM] Do not hide syntactically required parentheses within macros
...
It makes code formatters confused when auto indenting.
2023-12-12 23:57:27 +09:00
Jemma Issroff
69d60cc67b
[PRISM] Properly compile MultiTargetNodes within parameters
...
If there are MultiTargetNodes within parameters, we need to
iterate over them and compile them individually correctly, once
the locals are all in the correct spaces. We need to add one
getlocal for the hidden variable, and then can recurse into the
MultiTargetNodes themselves
2023-12-11 17:04:46 -05:00
Jemma Issroff
5c8e1911ca
[PRISM] Fixed rest in MultiTargetNodes
2023-12-11 17:04:46 -05:00
Jemma Issroff
aaeccc2924
[PRISM] Correctly implemented forwarding parameters in methods
2023-12-11 17:04:46 -05:00
Jemma Issroff
85ad5be9ee
[PRISM] Restructure parameters on ScopeNodes
...
This commit completely restructures how we handle parameters. The
motivation for this commit was the fix compilation of MultiTargetNodes
within parameters, including nested MultiTargetNodes. A subsequent
commit will actually do the compilation for the MultiTargetNodes.
This commit's main accomplishment is restructuring the locals table
and how we account for it on the ScopeNode, specifically with regards
to hidden variables.
It has multiple steps, all commented within the code, to calculate
the locals table correctly and compile the parameters:
- Step 1: Caculate the table size for the locals
- Step 2: Populate iv index table and local table
- Step 3: Fill in parameter names of MultiTargetNodes on local table
- Step 4: Fill in method body locals on local table
- Step 5: Compile any locals
2023-12-11 17:04:46 -05:00
Jemma Issroff
fb93535070
[PRISM] Define and use a pm_add_ensure_iseq
...
Prior to this commit, we were using `add_ensure_iseq` which compiled
a node as if it was a CRuby node. This commit defines
`pm_add_ensure_iseq` which compiles the Prism node appropriately.
2023-12-11 12:53:47 -05:00
Jemma Issroff
c69d1367a7
[PRISM] Fix ElseNode within CaseNode
...
The logic within the consequent for the CaseNodes in popped cases
was incorrect as it wouldn't emit consequent instructions for a
popped CaseNode. This commit fixes that.
2023-12-11 09:47:59 -05:00
Ufuk Kayserilioglu
0562c246eb
Add handling of implicit hash arguments
...
Arguments that are passed as a hash need special consideration since in certain case they are not treated as keyword arguments. For example, if a call is passing `"a" => 1` as an argument, this will be turned into an implicit hash argument and not a keyword argument.
The existing compiler checks to see if all hash nodes can be treated as keyword arguments. If they can, then it will treat them as keyword arguments. If not, then it will treat them as implicit hash arguments.
This commit implements the same logic inside the Prism compiler.
2023-12-11 09:47:33 -05:00
eileencodes
1cbe114d1c
[PRISM] Fix `PM_CALL_NODE` assignment
...
This PR fixes ruby/prism#1963 . Array and variable assignment was broken
for call nodes. The change checks if the `method_id` is related to
assignment and if is adds a `putnil`, `setn` and a `pop`.
The incorrect instructions meant that in some cases (demonstrated in
tests) the wrong value would be returned.
I verified that this fixes the test mentioned in the issue
(run: `RUBY_ISEQ_DUMP_DEBUG=prism make test/-ext-/st/test_numhash.rb`)
Incorrect instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(4,10)>
0000 putnil ( 4)[Li]
0001 putself
0002 send <calldata!mid:tbl, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0005 putself
0006 send <calldata!mid:i, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0009 putself
0010 send <calldata!mid:j, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0013 setn 3
0015 send <calldata!mid:[]=, argc:2, ARGS_SIMPLE>, nil
0018 pop
0019 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:3 (3,0)-(3,10)>
0000 putself ( 3)[Li]
0001 send <calldata!mid:tbl, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0004 putself
0005 send <calldata!mid:i, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0008 putself
0009 send <calldata!mid:j, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0012 send <calldata!mid:[]=, argc:2, ARGS_SIMPLE>, nil
0015 leave
```
Fixed instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(4,10)>
0000 putnil ( 4)[Li]
0001 putself
0002 send <calldata!mid:tbl, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0005 putself
0006 send <calldata!mid:i, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0009 putself
0010 send <calldata!mid:j, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0013 setn 3
0015 send <calldata!mid:[]=, argc:2, ARGS_SIMPLE>, nil
0018 pop
0019 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:3 (3,0)-(3,10)>
0000 putnil ( 3)[Li]
0001 putself
0002 send <calldata!mid:tbl, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0005 putself
0006 send <calldata!mid:i, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0009 putself
0010 send <calldata!mid:j, argc:0, FCALL|VCALL|ARGS_SIMPLE>, nil
0013 setn 3
0015 send <calldata!mid:[]=, argc:2, ARGS_SIMPLE>, nil
0018 pop
0019 leave
```
Fixes ruby/prism#1963
2023-12-08 12:45:40 -08:00
Aaron Patterson
9d696aa204
Support method calls inside `defined?`
...
This commit supports all kinds of method calls (including methods with
parameters) inside `defined?` calls.
2023-12-07 14:07:09 -08:00
Jemma Issroff
b361a800c2
Added comment
2023-12-07 15:29:35 -05:00
Jemma Issroff
a0c7bb4328
[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
2023-12-07 15:29:35 -05:00
Matt Valentine-House
41b299d639
[PRISM] Stop catch table entries being deleted by the optimiser
2023-12-07 14:12:20 -05:00
Jemma Issroff
b8df6b9e01
[PRISM] Don't pop arguments on a return node
...
Since ReturnNodes don't get popped, their arguments shouldn't either
2023-12-07 10:34:39 -05:00
Matt Valentine-House
8e86a4347e
[PRISM] Ensure should set correct end_label
2023-12-07 09:38:24 -05:00
Matt Valentine-House
c4b9695350
[PRISM] Rescue should set correct end_label
...
In order for a break inside the rescue to have the correct jump target
2023-12-07 09:38:24 -05:00
Matt Valentine-House
c8b60c8ac2
[PRISM] Correct depth offset for block local vars
...
Blocks should always look at their own local table first, even when
defined inside an ensure/rescue or something else that uses depth
offset. We can ignore the depth offset if we're doing local lookups
inside a block
2023-12-06 21:12:08 +00:00
Kevin Newton
153c09f24b
[prism] Handle string and xstring encodings
2023-12-06 14:23:38 -05:00
Jemma Issroff
9620ca6789
[PRISM] Extract a PM_NOP helper
2023-12-06 13:05:03 -05:00
Jemma Issroff
0316e666c0
[PRISM] Fix ReturnNodes
...
This code is almost exactly the same (fixed variable names) as
what exists already in compile.c
2023-12-06 12:25:49 -05:00
Jemma Issroff
f80262b14d
[PRISM] Account for nil parent in Call{Operator,And,Or}PathWriteNodes
...
Prior to this commit, we were not accounting for the case of a nil
parent in a CallXPathWriteNode, for example ::A ||= 1. This commit
checks if the parent exists, and if not, uses Object as the inferred
parent
2023-12-06 11:31:43 -05:00
eileencodes
da1519b223
[PRISM] Implement `PM_MATCH_PREDICATE_NODE` for `defined?`
...
Ruby code:
```ruby
defined? 1 in 1
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,16)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,16)>
0000 putobject "expression"
0002 leave
```
2023-12-06 09:46:19 -05:00
eileencodes
4547108448
[PRISM] Implement `PM_KEYWORD_HASH_NODE` for `defined?`
...
Ruby code:
```ruby
defined? [a: [:b, :c]]
```
Instructions (without optimizations):
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,23)>
== catch table
| catch type: rescue st: 0001 ed: 0007 sp: 0000 cont: 0009
| == disasm: #<ISeq:defined guard in <compiled>@<compiled>:0 (0,0)-(-1,-1)>
| local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
| [ 1] "$!"@0
| 0000 putnil
| 0001 leave
|------------------------------------------------------------------------
0000 putnil
0001 putobject true
0003 branchunless 9
0005 putobject "expression"
0007 swap
0008 pop
0009 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,23)>
== catch table
| catch type: rescue st: 0000 ed: 0009 sp: 0000 cont: 0009
| == disasm: #<ISeq:defined guard in <compiled>@<compiled>:0 (0,0)-(-1,-1)>
| local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
| [ 1] "$!"@0
| 0000 putnil
| 0001 leave
|------------------------------------------------------------------------
0000 putnil
0001 putobject true
0003 branchunless 9
0005 putobject "expression"
0007 swap
0008 pop
0009 leave
```
Instructions (with optimizations):
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,23)>
== catch table
| catch type: rescue st: 0001 ed: 0003 sp: 0000 cont: 0005
| == disasm: #<ISeq:defined guard in <compiled>@<compiled>:0 (0,0)-(-1,-1)>
| local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
| [ 1] "$!"@0
| 0000 putnil
| 0001 leave
|------------------------------------------------------------------------
0000 putnil
0001 putobject "expression"
0003 swap
0004 pop
0005 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,23)>
== catch table
| catch type: rescue st: 0000 ed: 0005 sp: 0000 cont: 0005
| == disasm: #<ISeq:defined guard in <compiled>@<compiled>:0 (0,0)-(-1,-1)>
| local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
| [ 1] "$!"@0
| 0000 putnil
| 0001 leave
|------------------------------------------------------------------------
0000 putnil
0001 putobject "expression"
0003 swap
0004 pop
0005 leave
```
2023-12-06 09:46:19 -05:00
eileencodes
8649764522
[PRISM] Implement `PM_SPLAT_NODE` for `defined?`
...
In an array for `defined?` we need to check if there is a
`contains_splat` flag, if so bail early.
Ruby code:
```ruby
defined?([[*1..2], 3, *4..5])
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,29)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,29)>
0000 putobject "expression"
0002 leave
```
2023-12-06 09:46:19 -05:00
eileencodes
02961fdbab
[PRISM] Implement `PM_SOURCE_LINE_NODE` for `defined?`
...
Ruby code:
```ruby
defined?(__LINE__)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,18)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,18)>
0000 putobject "expression"
0002 leave
```
2023-12-06 09:46:19 -05:00
eileencodes
d474239537
[PRISM] Implement `PM_SOURCE_FILE_NODE` for `defined?`
...
Ruby code:
```ruby
defined?(__FILE__)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,18)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,18)>
0000 putobject "expression"
0002 leave
```
2023-12-06 09:46:19 -05:00
eileencodes
41b117e50c
[PRISM] Implement `PM_SOURCE_ENCODING_NODE` for `defined?
...
Ruby code:
```ruby
defined?(__ENCODING__)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,22)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,22)>
0000 putobject "expression"
0002 leave
```
2023-12-06 09:46:19 -05:00
eileencodes
b04255deff
[PRISM] Implement `PM_IMAGINARY_NODE` for `defined?`
...
Ruby Code:
```
defined?(1i)
```
Instructions:
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,12)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,12)>
0000 putobject "expression"
0002 leave
```
2023-12-06 09:46:19 -05:00
Matt Valentine-House
d6ec1aa0a7
[PRISM] Compile Rescue Modifier nodes
2023-12-06 07:02:04 -05:00
Matt Valentine-House
6b9622ebdf
[PRISM] Implement Retry node.
2023-12-05 08:56:22 -05:00
Jemma Issroff
81a700853d
[PRISM] Fixed redo node
2023-12-04 17:02:04 -05:00
eileencodes
7d371ca25d
[PRISM] Handle percent literals for `defined?`
...
Tests all the possible percent literal with `defined?`. Implements the
missing `PM_X_STRING_NODE` for the `%x` literal.
Code:
```ruby
defined?(%x[1,2,3])
```
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,19)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,19)>
0000 putobject "expression"
0002 leave
```
2023-12-04 16:45:18 -05:00
eileencodes
09e8d37f5b
[PRISM] Implement `PM_INTERPOLATED_REGULAR_EXPRESSION_NODE`
...
Implements `PM_INTERPOLATED_REGULAR_EXPRESSION_NODE` for `defined?`
Code:
```ruby
defined?(/#{1}/)
```
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,16)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,16)>
0000 putobject "expression"
0002 leave
```
2023-12-04 16:45:18 -05:00
eileencodes
33bc22efe5
[PRISM] Implement `PM_INTERPOLATED_STRING_NODE`
...
Implements `PM_INTERPOLATED_STRING_NODE` for `defined?`
Code:
```ruby
defined?("#{expr}")
```
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,19)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,19)>
0000 putobject "expression"
0002 leave
```
2023-12-04 16:45:18 -05:00
eileencodes
c23b2e5353
[PRISM] Fix `PM_PARENTHESES_NODE`
...
In #9101 I only accounted for an empty paren. This change implements the
`PM_PARENTHESES_NODE` for when it's `nil` and when it's an expression.
Code:
```ruby
defined?(("a"))
```
```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,15)>
0000 putobject "expression"
0002 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,15)>
0000 putobject "expression"
0002 leave
```
2023-12-04 16:45:18 -05:00
eileencodes
569750f624
[Prism] Implement backref and numbered reference for `defined?`
...
This PR implements `PM_BACK_REFERENCE_READ_NODE` and
`PM_NUMBERED_REFERENCE_READ_NODE` for `defined?`. The following now
works:
* `PM_NUMBERED_REFERENCE_READ_NODE`
```
defined? $1
defined? $2
```
Instructions:
```
"********* RUBY *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,12)>
0000 putnil
0001 defined ref, :$1, "global-variable"
0005 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,12)>
0000 putnil
0001 defined ref, :$1, "global-variable"
0005 leave
```
* `PM_BACK_REFERENCE_READ_NODE`
```
defined? $'
defined? $`
defined? $&
```
Instructions:
```
"********* RUBY *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,12)>
0000 putnil
0001 defined ref, :$`, "global-variable"
0005 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:0 (0,0)-(0,12)>
0000 putnil
0001 defined ref, :$`, "global-variable"
0005 leave
```
2023-12-04 12:03:22 -08:00
Jemma Issroff
e3ca50b02f
[PRISM] Fix compilation for NextNode
...
This code was almost enitrely the same as the existing compiler's
code for its NextNode.
2023-12-04 14:03:00 -05:00
eileencodes
818813c2bd
Implement paren node for `defined?`
...
Implements and adds a test for passing a parentheses node to `defined?`.
2023-12-01 14:56:25 -08:00
eileencodes
39238888bc
Implements missing literals for `defined?`
...
This PR implements the following literals:
- String
- Symbols
- Integers
- Floats
- Regexs
- Ranges
- Lambdas
- Hashes
and tests for them.
2023-12-01 12:05:22 -08:00
Jemma Issroff
2a8d9c59ff
[PRISM] Account for RescueNodes with no statements
...
We need a PUTNIL if a RescueNode has no statements.
2023-12-01 13:23:23 -05:00
Jemma Issroff
d6584a0201
[PRISM] Fix behavior of BlockParameters with only one parameter
...
This commit sets the ambiguous param flag if there is only one
parameter on a block node. It also fixes a small bug with a trailing
comma on params.
2023-12-01 13:07:59 -05:00
Jemma Issroff
9d20909342
[PRISM] Clean up trailing comment
2023-12-01 12:20:16 -05:00
Jemma Issroff
d224618bea
[PRISM] Restructure parameters
...
Prior to this commit, we weren't accounting for hidden variables
on the locals table, so we would have inconsistencies on the stack.
This commit fixes params, and introduces a hidden_variable_count
on the scope, both of which fix parameters.
2023-12-01 12:14:54 -05:00
Kevin Newton
5150ba0dbe
[prism] Update to latest numbered parameters
2023-12-01 12:03:09 -05:00
Matt Valentine-House
90d9c20a0c
[PRISM] Compile RescueNode
2023-12-01 16:40:25 +00:00
Matt Valentine-House
3b21932d14
[PRISM] Use depth_offset not transparent scopes for FOR
2023-12-01 15:04:13 +00:00
Matt Valentine-House
0c7c654b4d
[Prism] Fix local variable access for POST_EXECUTION_NODE
2023-11-30 21:31:57 +00:00
Matt Valentine-House
57782d3d47
Store depth offset inside the scope node.
...
Instead of incrementing the depth using call by reference as we're
recursing up the stack we could instead store an offset for each known
scope where we know the depth is going to represented differently in the
Prism ast.
2023-11-30 21:31:57 +00:00
Aaron Patterson
630c97acc7
Add a rescue for `defined?(A::B::C)`
...
It's possible for `defined?(A::B::C)` to raise an exception. `defined?`
must swallow the exception and return nil, so this commit adds a rescue
entry for `defined?` expressions on constant paths
2023-11-30 09:48:14 -05:00
Jemma Issroff
8234763816
[PRISM] Compile empty array as newarray 0
...
Prior to this commit, we were compiling an empty array as a
duparray of [] which meant we were allocating a new value
unnecessarily. With this commit, we emit a newarray with size 0
instead.
2023-11-29 16:20:30 -05:00
Jemma Issroff
853fd44745
[PRISM] Implement CallNodes with splat followed by args
2023-11-29 16:19:14 -05:00
Jemma Issroff
2233204cc1
[PRISM] Account for ImplicitRestNode
...
Prism introduced a new ImplicitRestNode. This adds tests for the
ImplicitRestNode cases, and changes one assert which is no longer
accurate.
2023-11-29 16:14:28 -05:00
Jemma Issroff
53841941f0
[PRISM] Fix EnsureNode, pass depth to get locals
...
This commit fixes a bug with locals in ensure nodes by setting
the local tables correctly. It also changes accessing locals to
look at local tables in parent scopes, and account for this
correctly on depths of get or setlocals.
2023-11-29 16:00:00 -05:00
Jemma Issroff
a9c07cbd21
[PRISM] Don't calculate params size based on locals
...
Prior to this commit, we were conflating the size of the locals
list with the number of parameters. This commit distinguishes
the two, and fixes a related bug which would occur if we set a local
that was not a parameter
2023-11-28 17:01:34 -05:00
Jemma Issroff
7bd172744f
[PRISM] Implement more compilation of SplatNodes
...
There was a bug with the rest argument in SplatNodes, this commit
fixes it, and adds more tests illustrating the behavior of
SplatNodes
2023-11-28 14:03:57 -05:00
Jemma Issroff
2760f23774
[PRISM] Compile YieldNode with different arguments
2023-11-28 14:02:53 -05:00
Jemma Issroff
1acea50100
[PRISM] Small fixes to parameters ordering and methods
2023-11-27 16:02:38 -05:00
Jemma Issroff
e4dd8f6c9c
[PRISM] Renamed some variables, added comments
2023-11-27 15:14:40 -05:00
Jemma Issroff
ba26c6eae0
[PRISM] Compile IndexOperatorWriteNode
2023-11-27 15:14:40 -05:00
Jemma Issroff
ec5eddf695
[PRISM] Compile IndexAndWriteNode
2023-11-27 15:14:40 -05:00
Jemma Issroff
13b7cddc2b
[PRISM] Compile IndexOrWriteNode
2023-11-27 15:14:40 -05:00
Jemma Issroff
95064bb88d
[PRISM] Fix compilation for SplatNodes within ArrayNodes
...
SplatNodes within ArrayNodes (e.g. [*1..2, 3]) need to be special
cased in the compiler because they use a combination of concatarray
and newarray instructions to treat each sequence of splat or non-splat
elements as independent arrays which get concatenated. This commit
implements those cases.
2023-11-27 12:52:07 -05:00
Jemma Issroff
6d447fa35f
[PRISM] Don't pop several args related nodes
2023-11-27 12:51:50 -05:00
Matt Valentine-House
406dafbb34
[PRISM] Insert Tracepoint line events on line change
2023-11-24 12:54:35 +00:00
Jemma Issroff
3db21d2d4c
[PRISM] Rename flag to CONTAINS_KEYWORD_SPLAT
...
We need to do this change first on ruby/ruby before merging to
ruby/prism to avoid breaking ruby/ruby CI
2023-11-21 17:29:07 -05:00
Kevin Newton
a5b482837b
Remove string concat node in prism
2023-11-21 11:35:46 -05:00
Kevin Newton
914640eadd
Use new match write targets
2023-11-20 18:00:44 -05:00
Jemma Issroff
103bbd21f8
[PRISM] Updated LocalVariableTargetNodes too
2023-11-20 13:48:46 -08:00
Jemma Issroff
b913626bea
[PRISM] Fix LocalVariableWriteNodes within blocks
...
Prior to this commit, we weren't recursing up scopes to look for
the local definition. With this commit, we do so, fixing local writes
within blocks
2023-11-20 13:48:46 -08:00
eileencodes
2796e4ece2
[PRISM] Implement once node for interpolated regex
...
This PR implements the once node on interpolated regexes.
There is a bug in Prism where the interpolated regex with the once flag
only works when there is not a local variable so the test uses a "1".
We'll need to fix that.
2023-11-20 12:42:05 -08:00
Jemma Issroff
c5d5929443
[PRISM] Don't pop args to YieldNode
2023-11-20 12:12:34 -08:00
eileencodes
4dd11c067d
Switching first argument in pm_interpolated_node_compile
...
This changes the first argument in `pm_interpolated_node_compile` to use
a pointer.
2023-11-20 07:05:09 -08:00
Jemma Issroff
775ed27d6d
[PRISM] Initialize keyword to silence warning
2023-11-13 17:48:55 -05:00
Jemma Issroff
ae1fad4cd7
[PRISM] Implement compilation for ForwardingArgumentssNode
2023-11-09 09:45:59 -03:00
Nobuyoshi Nakada
0f02fbd9ff
Range check in pm_constant_id_lookup
2023-11-09 18:21:45 +09:00
Nobuyoshi Nakada
e824b69a86
Remove useless casts
2023-11-09 18:21:45 +09:00
Matt Valentine-House
5c8d2c2d45
[PRISM] Always lookup idERROR_INFO consistently.
...
We know where it is in the iseq local table, because we forced it using
`iseq_set_exception_local_table` when compiling the BEGIN_NODE, so we
can always look it up from the same place.
Co-Authored-By Peter Zhu <peter@peterzhu.ca>
2023-11-08 20:28:58 -05:00
Jemma Issroff
f9e34a1fd3
[PRISM] Add tests for OptionalKeywordParameterNode
...
This commit adds tests for the compilation of the
OptionalKeywordParameterNode, and fixes cases on the
RequiredKeywordParameterNode
2023-11-08 18:15:47 -03:00
Jemma Issroff
70e4ff9feb
[PRISM] Added tests for ForwardingParameterNode, KeywordRestParameterNode
2023-11-08 18:15:47 -03:00
Jemma Issroff
26cff6ae2b
[PRISM] Add tests for several parameters nodes
...
This commit adds tests for BlockParameterNode, RequiredParameterNode,
RequiredKeywordParameterNode and RestParameterNode
2023-11-08 18:15:47 -03:00
Jemma Issroff
bc07b0b9e1
[PRISM] Implement compilation for different parameters
...
This commit compiles most parameter types, setting appropriate values on
the ISEQ_BODY. It also adds tests for callers and callees of methods,
using many versions of tests from bootstraptest
2023-11-07 15:15:16 -03:00
Matt Valentine-House
e7bdd9e498
[PRISM] Move Local table setup into EnsureNode compilation
2023-11-07 14:03:57 +00:00
Matt Valentine-House
b7d5a63b9a
[PRISM] Don't generate leave insns for Ensure nodes
2023-11-07 14:03:57 +00:00
Matt Valentine-House
8ef7f27321
[PRISM] CompileEnsureNode
2023-11-07 14:03:57 +00:00
Matt Valentine-House
237b85c256
[PRISM] PM_COMPILE into a specified LINK_ANCHOR
2023-11-07 14:03:57 +00:00
Jemma Issroff
f6ba87ca88
[PRISM] Implement compilation for MultiWriteNodes, fix MultiTargetNodes
...
Compilation now works for MultiWriteNodes and MultiTargetNodes, with
nesting on MultiWrites. See the tests added in this commit for example
behavior.
2023-11-06 10:39:07 -03:00
Matt Valentine-House
cdb410f688
[PRISM] Fix stack consistency with Popped begin
...
When a begin node is popped it only needs to putnil if that nil is going
to be the return value, otherwise it can successfully be optimised out.
2023-11-03 15:19:28 +00:00
Matt Valentine-House
dcb9ded6c9
[PRISM] Fix CallNode with arguments when popped
...
Previously emitting a call node with an argument followed by another
node would cause the argument to be mistakenly omitted from the argument
list causing a stack underflow.
```
PRISM: **************************************************
-- raw disasm--------
0000 putself ( 0)
0001 send <calldata:puts, 1>, nil ( 0)
* 0004 pop ( 0)
0005 putobject 1 ( 0)
0007 leave ( 0)
---------------------
```
2023-11-03 07:28:05 +00:00
Jemma Issroff
c6f5c64639
[PRISM] Fix popped for ForNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
7f18448a8e
[PRISM] Fix popped for CallOperatorWriteNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
d8bdb15a8b
[PRISM] Fix popped for Call{And,Or}WriteNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
5acced49c2
[PRISM] Fix popped for SingletonClassNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
33f18b3d2f
[PRISM] Fix popped for CaseNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
62baf723b6
[PRISM] Fix popped for AssocSplatNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
8b4b3b1d38
[PRISM] Fix popped for MatchWriteNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
0359f9ca67
[PRISM] Fix popped for ConstantPathOperatorWriteNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
ddf12e8a3b
[PRISM] Fix popped for ConstantPathOrWriteNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
ca24136da6
[PRISM] Fix popped on DefinedNode
2023-11-02 17:46:43 -03:00
Jemma Issroff
698654ca84
[PRISM] Fixed popped for ConstantPathAndWriteNode
2023-11-02 17:46:43 -03:00
Kevin Newton
717fb5bb0b
[prism] Use a pointer for optional node list
2023-11-01 10:36:21 -04:00
Jemma Issroff
b7a3e2e71d
[PRISM] Remove unnecessary variable
2023-10-31 15:57:25 -03:00
Jemma Issroff
b3744c749d
[PRISM] Implement compilation for SuperNode
2023-10-31 13:59:40 -03:00
Jemma Issroff
57748ef2a2
[PRISM] Compile forwarding super node
2023-10-31 13:08:09 -03:00
Jemma Issroff
85ad102532
[PRISM] Implement compilation for PostExecutionNode
...
This commit implements compilation for the PostExeuctionNode by
using the ScopeNode to create child iseqs where appropriate.
2023-10-31 12:51:06 -03:00
HParker
d8a9245513
Add defined array node
2023-10-31 07:01:00 -03:00
HParker
b05a7bc512
compile defined with nested constants and stovetop
2023-10-31 07:01:00 -03:00
Matt Valentine-House
962c62057f
Fix warning in Prism compile For Node
2023-10-31 09:01:56 +00:00
Jemma Issroff
f0b7895637
[PRISM] Implement all argument types for CallNodes
2023-10-30 18:07:04 -03:00
Matt Valentine-House
b17b0336b6
Document TEMP_CONSTANT_IDENTIFIER
2023-10-30 19:44:42 +00:00
Matt Valentine-House
9249b8622b
Move constant indexing into rb_translate_prism
2023-10-30 19:44:42 +00:00
Matt Valentine-House
5dfba84cff
[Prism] Compile ForNode
...
Fixes ruby/prism#1648
2023-10-30 19:44:42 +00:00
Matt Valentine-House
b0f715fa3b
More accurate functions documentation
2023-10-30 19:44:42 +00:00
Kevin Newton
e3258dd627
Integrate new prism multi target names
2023-10-26 15:03:33 -04:00
eileencodes
a082e560bb
[PRISM] Implement regex encoding flags
...
Added the correct encoding to the allocated regex. This required making
a new method to set the encoding and pass that to `rb_enc_reg_new`
instead of `rb_reg_new`. The former `rb_reg_new` would set the encoding
to ASCII8BIT regardless of encoding flag.
2023-10-26 11:11:52 -07:00
Jemma Issroff
4f8a33eb05
[PRISM] Cleanup macro usage for common ADD_INSN
2023-10-26 12:47:28 -03:00