Commit graph

637 commits

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