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