15
15
import org .truffleruby .builtins .Primitive ;
16
16
import org .truffleruby .builtins .UnaryCoreMethodNode ;
17
17
import org .truffleruby .builtins .YieldingCoreMethodNode ;
18
- import org .truffleruby .collections .WeakValueCache ;
18
+ import org .truffleruby .collections .WeakValueCache . WeakMapEntry ;
19
19
import org .truffleruby .core .array .RubyArray ;
20
+ import org .truffleruby .core .hash .CompareByRubyIdentityWrapper ;
20
21
import org .truffleruby .core .klass .RubyClass ;
21
22
import org .truffleruby .core .proc .RubyProc ;
22
23
import org .truffleruby .language .Nil ;
27
28
import com .oracle .truffle .api .dsl .Specialization ;
28
29
import org .truffleruby .language .objects .AllocationTracing ;
29
30
31
+ import java .util .Collection ;
32
+
30
33
/** Note that WeakMap uses identity comparison semantics. See top comment in src/main/ruby/truffleruby/core/weakmap.rb
31
34
* for more information. */
32
35
@ CoreModule (value = "ObjectSpace::WeakMap" , isClass = true )
@@ -57,7 +60,7 @@ public abstract static class MemberNode extends CoreMethodArrayArgumentsNode {
57
60
58
61
@ Specialization
59
62
protected boolean isMember (RubyWeakMap map , Object key ) {
60
- return map .storage .get (key ) != null ;
63
+ return map .storage .get (new CompareByRubyIdentityWrapper ( key ) ) != null ;
61
64
}
62
65
}
63
66
@@ -66,7 +69,7 @@ public abstract static class GetIndexNode extends CoreMethodArrayArgumentsNode {
66
69
67
70
@ Specialization
68
71
protected Object get (RubyWeakMap map , Object key ) {
69
- Object value = map .storage .get (key );
72
+ Object value = map .storage .get (new CompareByRubyIdentityWrapper ( key ) );
70
73
return value == null ? nil : value ;
71
74
}
72
75
}
@@ -76,7 +79,7 @@ public abstract static class SetIndexNode extends CoreMethodArrayArgumentsNode {
76
79
77
80
@ Specialization
78
81
protected Object set (RubyWeakMap map , Object key , Object value ) {
79
- map .storage .put (key , value );
82
+ map .storage .put (new CompareByRubyIdentityWrapper ( key ) , value );
80
83
return value ;
81
84
}
82
85
}
@@ -144,8 +147,8 @@ protected RubyWeakMap each(RubyWeakMap map, Nil block) {
144
147
@ Specialization
145
148
protected RubyWeakMap each (RubyWeakMap map , RubyProc block ) {
146
149
147
- for (WeakValueCache . WeakMapEntry <?, ?> e : entries (map .storage )) {
148
- yield(block , e . getKey (), e . getValue () );
150
+ for (MapEntry entry : entries (map .storage )) {
151
+ yield (block , entry . key , entry . value );
149
152
}
150
153
151
154
return map ;
@@ -154,17 +157,39 @@ protected RubyWeakMap each(RubyWeakMap map, RubyProc block) {
154
157
155
158
@ TruffleBoundary
156
159
private static Object [] keys (WeakMapStorage storage ) {
157
- return storage .keys ().toArray ();
160
+ final Collection <CompareByRubyIdentityWrapper > keyWrappers = storage .keys ();
161
+ final Object [] keys = new Object [keyWrappers .size ()];
162
+ int i = 0 ;
163
+ for (CompareByRubyIdentityWrapper keyWrapper : keyWrappers ) {
164
+ keys [i ++] = keyWrapper .value ;
165
+ }
166
+ return keys ;
158
167
}
159
168
160
169
@ TruffleBoundary
161
170
private static Object [] values (WeakMapStorage storage ) {
162
171
return storage .values ().toArray ();
163
172
}
164
173
174
+ private static class MapEntry {
175
+ final Object key ;
176
+ final Object value ;
177
+
178
+ private MapEntry (Object key , Object value ) {
179
+ this .key = key ;
180
+ this .value = value ;
181
+ }
182
+ }
183
+
165
184
@ TruffleBoundary
166
- private static WeakValueCache .WeakMapEntry <?, ?>[] entries (WeakMapStorage storage ) {
167
- return storage .entries ().toArray (new WeakValueCache .WeakMapEntry <?, ?>[0 ]);
185
+ private static MapEntry [] entries (WeakMapStorage storage ) {
186
+ final Collection <WeakMapEntry <CompareByRubyIdentityWrapper , Object >> wrappedEntries = storage .entries ();
187
+ final MapEntry [] entries = new MapEntry [wrappedEntries .size ()];
188
+ int i = 0 ;
189
+ for (WeakMapEntry <CompareByRubyIdentityWrapper , Object > wrappedEntry : wrappedEntries ) {
190
+ entries [i ++] = new MapEntry (wrappedEntry .getKey ().value , wrappedEntry .getValue ());
191
+ }
192
+ return entries ;
168
193
}
169
194
170
195
private static RubyWeakMap eachNoBlockProvided (YieldingCoreMethodNode node , RubyWeakMap map ) {
0 commit comments