summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2023-12-15 13:44:31 -0500
committergit <svn-admin@ruby-lang.org>2023-12-15 20:55:13 +0000
commit2e8cfcac9129ed8680c4b916bc5b4c535ae6e8c8 (patch)
tree583aef3677b10f0547860a072ebba6ddcd2be657
parent9c9e6d5b91f23c15357d88036382d68ae3c77d97 (diff)
[ruby/prism] String literal hash keys should be frozen
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 ``` https://github.com/ruby/prism/commit/b14ae55385
-rw-r--r--prism/prism.c5
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/literal.txt12
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/send.txt2
3 files changed, 12 insertions, 7 deletions
diff --git a/prism/prism.c b/prism/prism.c
index a382a6b18c..ec319f2cac 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -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,
diff --git a/test/prism/snapshots/unparser/corpus/literal/literal.txt b/test/prism/snapshots/unparser/corpus/literal/literal.txt
index 21ae9f670b..a26b925196 100644
--- a/test/prism/snapshots/unparser/corpus/literal/literal.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/literal.txt
@@ -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) = "\""
@@ -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) = "\""
@@ -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) = "\""
@@ -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) = "\""
@@ -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) = "\""
@@ -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) = "\""
diff --git a/test/prism/snapshots/unparser/corpus/literal/send.txt b/test/prism/snapshots/unparser/corpus/literal/send.txt
index 673787f1f1..edfd0cc6ae 100644
--- a/test/prism/snapshots/unparser/corpus/literal/send.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/send.txt
@@ -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) = "\""