14
14
import com .oracle .truffle .api .frame .*;
15
15
import com .oracle .truffle .api .nodes .*;
16
16
import org .jruby .truffle .nodes .*;
17
+ import org .jruby .truffle .nodes .dispatch .DispatchHeadNode ;
17
18
import org .jruby .truffle .runtime .*;
18
19
import org .jruby .truffle .runtime .core .RubyHash ;
20
+ import org .jruby .truffle .runtime .core .RubyString ;
19
21
20
22
import java .util .LinkedHashMap ;
21
23
22
24
public abstract class HashLiteralNode extends RubyNode {
23
25
24
26
@ Children protected final RubyNode [] keyValues ;
27
+ @ Child protected DispatchHeadNode dupNode ;
28
+ @ Child protected DispatchHeadNode freezeNode ;
25
29
26
30
protected HashLiteralNode (RubyContext context , SourceSection sourceSection , RubyNode [] keyValues ) {
27
31
super (context , sourceSection );
28
32
assert keyValues .length % 2 == 0 ;
29
33
this .keyValues = keyValues ;
34
+ dupNode = new DispatchHeadNode (context );
35
+ freezeNode = new DispatchHeadNode (context );
30
36
}
31
37
32
38
public static HashLiteralNode create (RubyContext context , SourceSection sourceSection , RubyNode [] keyValues ) {
@@ -84,8 +90,16 @@ public SmallHashLiteralNode(RubyContext context, SourceSection sourceSection, Ru
84
90
public RubyHash executeRubyHash (VirtualFrame frame ) {
85
91
final Object [] storage = new Object [RubyContext .HASHES_SMALL * 2 ];
86
92
87
- for (int n = 0 ; n < keyValues .length ; n ++) {
88
- storage [n ] = keyValues [n ].execute (frame );
93
+ for (int n = 0 ; n < keyValues .length ; n += 2 ) {
94
+ Object key = keyValues [n ].execute (frame );
95
+ final Object value = keyValues [n + 1 ].execute (frame );
96
+
97
+ if (key instanceof RubyString ) {
98
+ key = freezeNode .call (frame , dupNode .call (frame , key , "dup" , null ), "freeze" , null );
99
+ }
100
+
101
+ storage [n ] = key ;
102
+ storage [n + 1 ] = value ;
89
103
}
90
104
91
105
return new RubyHash (getContext ().getCoreLibrary ().getHashClass (), null , storage , keyValues .length / 2 );
@@ -107,7 +121,14 @@ public RubyHash executeRubyHash(VirtualFrame frame) {
107
121
final LinkedHashMap <Object , Object > storage = new LinkedHashMap <>();
108
122
109
123
for (int n = 0 ; n < keyValues .length ; n += 2 ) {
110
- storage .put (keyValues [n ].execute (frame ), keyValues [n + 1 ].execute (frame ));
124
+ Object key = keyValues [n ].execute (frame );
125
+ final Object value = keyValues [n + 1 ].execute (frame );
126
+
127
+ if (key instanceof RubyString ) {
128
+ key = freezeNode .call (frame , dupNode .call (frame , key , "dup" , null ), "freeze" , null );
129
+ }
130
+
131
+ storage .put (key , value );
111
132
}
112
133
113
134
return new RubyHash (getContext ().getCoreLibrary ().getHashClass (), null , storage , 0 );
0 commit comments