Commit graph

345 commits

Author SHA1 Message Date
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