@@ -23,18 +23,18 @@ export function hash(o) {
23
23
? cachedHashString ( o )
24
24
: hashString ( o ) ;
25
25
case 'object' :
26
- case 'function' :
27
26
if ( o === null ) {
28
27
return 0x42108422 ;
29
28
}
29
+ // falls through
30
+ case 'function' :
30
31
if ( typeof o . hashCode === 'function' ) {
31
32
// Drop any high bits from accidentally long hash codes.
32
33
return smi ( o . hashCode ( o ) ) ;
33
34
}
34
- if ( o . valueOf !== defaultValueOf && typeof o . valueOf === 'function' ) {
35
- o = o . valueOf ( o ) ;
36
- }
37
- return hashJSObj ( o ) ;
35
+ return hashJSObj ( asPrimitive ( o ) ) ;
36
+ case 'symbol' :
37
+ return hashSymbol ( asPrimitive ( o ) ) ;
38
38
case 'undefined' :
39
39
return 0x42108423 ;
40
40
default :
@@ -90,6 +90,19 @@ function hashString(string) {
90
90
return smi ( hashed ) ;
91
91
}
92
92
93
+ function hashSymbol ( sym ) {
94
+ let hashed = symbolMap [ sym ] ;
95
+ if ( hashed !== undefined ) {
96
+ return hashed ;
97
+ }
98
+
99
+ hashed = nextHash ( ) ;
100
+
101
+ symbolMap [ sym ] = hashed ;
102
+
103
+ return hashed ;
104
+ }
105
+
93
106
function hashJSObj ( obj ) {
94
107
let hashed ;
95
108
if ( usingWeakMap ) {
@@ -116,10 +129,7 @@ function hashJSObj(obj) {
116
129
}
117
130
}
118
131
119
- hashed = ++ objHashUID ;
120
- if ( objHashUID & 0x40000000 ) {
121
- objHashUID = 0 ;
122
- }
132
+ hashed = nextHash ( ) ;
123
133
124
134
if ( usingWeakMap ) {
125
135
weakMap . set ( obj , hashed ) ;
@@ -186,14 +196,32 @@ function getIENodeHash(node) {
186
196
}
187
197
}
188
198
199
+ function asPrimitive ( obj ) {
200
+ return (
201
+ obj . valueOf !== defaultValueOf && typeof obj . valueOf === 'function'
202
+ ? obj . valueOf ( obj )
203
+ : obj
204
+ ) ;
205
+ }
206
+
207
+ function nextHash ( ) {
208
+ const nextHash = ++ _objHashUID ;
209
+ if ( _objHashUID & 0x40000000 ) {
210
+ _objHashUID = 0 ;
211
+ }
212
+ return nextHash ;
213
+ }
214
+
189
215
// If possible, use a WeakMap.
190
216
const usingWeakMap = typeof WeakMap === 'function' ;
191
217
let weakMap ;
192
218
if ( usingWeakMap ) {
193
219
weakMap = new WeakMap ( ) ;
194
220
}
195
221
196
- let objHashUID = 0 ;
222
+ const symbolMap = Object . create ( null ) ;
223
+
224
+ let _objHashUID = 0 ;
197
225
198
226
let UID_HASH_KEY = '__immutablehash__' ;
199
227
if ( typeof Symbol === 'function' ) {
0 commit comments