Skip to content

Commit

Permalink
[ruby/prism] String literal hash keys should be frozen
Browse files Browse the repository at this point in the history
String literal hash keys can't be mutated by the user so we should mark
them as frozen. We were seeing instructions for hashes with string
literal keys using two `putstring` instructions when it should be a
`putobject` and `putstring`.

Code example:

```ruby
{ "a" => "b" }
```

Instructions before:

```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(2,14)>
0000 putobject                              "a"                       (   2)[Li]
0002 putstring                              "b"
0004 newhash                                2
0006 leave
"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,14)>
0000 putstring                              "a"                       (   1)[Li]
0002 putstring                              "b"
0004 newhash                                2
0006 leave
```

Instructions after:

```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(2,14)>
0000 putobject                              "a"                       (   2)[Li]
0002 putstring                              "b"
0004 newhash                                2
0006 leave

"********* PRISM *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,14)>
0000 putobject                              "a"                       (   1)[Li]
0002 putstring                              "b"
0004 newhash                                2
0006 leave
```

ruby/prism@b14ae55385
  • Loading branch information
eileencodes authored and matzbot committed Dec 15, 2023
1 parent 9c9e6d5 commit 2e8cfca
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 7 deletions.
5 changes: 5 additions & 0 deletions prism/prism.c
Expand Up @@ -1340,6 +1340,11 @@ pm_assoc_node_create(pm_parser_t *parser, pm_node_t *key, const pm_token_t *oper
flags = key->flags & value->flags & PM_NODE_FLAG_STATIC_LITERAL;
}

// Hash string keys should be frozen
if (PM_NODE_TYPE_P(key, PM_STRING_NODE)) {
key->flags |= PM_STRING_FLAGS_FROZEN;
}

*node = (pm_assoc_node_t) {
{
.type = PM_ASSOC_NODE,
Expand Down
12 changes: 6 additions & 6 deletions test/prism/snapshots/unparser/corpus/literal/literal.txt
Expand Up @@ -9,7 +9,7 @@
│ │ ├── @ AssocNode (location: (1,2)-(1,21))
│ │ │ ├── key:
│ │ │ │ @ StringNode (location: (1,2)-(1,7))
│ │ │ │ ├── flags:
│ │ │ │ ├── flags: frozen
│ │ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
│ │ │ │ ├── content_loc: (1,3)-(1,6) = "foo"
│ │ │ │ ├── closing_loc: (1,6)-(1,7) = "\""
Expand Down Expand Up @@ -39,7 +39,7 @@
│ │ └── @ AssocNode (location: (1,23)-(1,36))
│ │ ├── key:
│ │ │ @ StringNode (location: (1,23)-(1,28))
│ │ │ ├── flags:
│ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (1,23)-(1,24) = "\""
│ │ │ ├── content_loc: (1,24)-(1,27) = "bar"
│ │ │ ├── closing_loc: (1,27)-(1,28) = "\""
Expand All @@ -59,7 +59,7 @@
│ │ ├── @ AssocNode (location: (4,2)-(4,14))
│ │ │ ├── key:
│ │ │ │ @ StringNode (location: (4,2)-(4,7))
│ │ │ │ ├── flags:
│ │ │ │ ├── flags: frozen
│ │ │ │ ├── opening_loc: (4,2)-(4,3) = "\""
│ │ │ │ ├── content_loc: (4,3)-(4,6) = "foo"
│ │ │ │ ├── closing_loc: (4,6)-(4,7) = "\""
Expand All @@ -75,7 +75,7 @@
│ │ └── @ AssocNode (location: (4,16)-(4,29))
│ │ ├── key:
│ │ │ @ StringNode (location: (4,16)-(4,21))
│ │ │ ├── flags:
│ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (4,16)-(4,17) = "\""
│ │ │ ├── content_loc: (4,17)-(4,20) = "bar"
│ │ │ ├── closing_loc: (4,20)-(4,21) = "\""
Expand Down Expand Up @@ -184,7 +184,7 @@
│ │ ├── @ AssocNode (location: (10,2)-(10,21))
│ │ │ ├── key:
│ │ │ │ @ StringNode (location: (10,2)-(10,7))
│ │ │ │ ├── flags:
│ │ │ │ ├── flags: frozen
│ │ │ │ ├── opening_loc: (10,2)-(10,3) = "\""
│ │ │ │ ├── content_loc: (10,3)-(10,6) = "foo"
│ │ │ │ ├── closing_loc: (10,6)-(10,7) = "\""
Expand Down Expand Up @@ -231,7 +231,7 @@
│ │ ├── @ AssocNode (location: (13,2)-(13,14))
│ │ │ ├── key:
│ │ │ │ @ StringNode (location: (13,2)-(13,7))
│ │ │ │ ├── flags:
│ │ │ │ ├── flags: frozen
│ │ │ │ ├── opening_loc: (13,2)-(13,3) = "\""
│ │ │ │ ├── content_loc: (13,3)-(13,6) = "foo"
│ │ │ │ ├── closing_loc: (13,6)-(13,7) = "\""
Expand Down
2 changes: 1 addition & 1 deletion test/prism/snapshots/unparser/corpus/literal/send.txt
Expand Up @@ -1310,7 +1310,7 @@
│ │ └── @ AssocNode (location: (64,13)-(64,25))
│ │ ├── key:
│ │ │ @ StringNode (location: (64,13)-(64,18))
│ │ │ ├── flags:
│ │ │ ├── flags: frozen
│ │ │ ├── opening_loc: (64,13)-(64,14) = "\""
│ │ │ ├── content_loc: (64,14)-(64,17) = "baz"
│ │ │ ├── closing_loc: (64,17)-(64,18) = "\""
Expand Down

0 comments on commit 2e8cfca

Please sign in to comment.