summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/hashes.nim23
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim
index 667f27e95..da72f2fab 100644
--- a/lib/pure/hashes.nim
+++ b/lib/pure/hashes.nim
@@ -195,10 +195,29 @@ else:
     ## Efficient hashing of integers.
     hashWangYi1(uint64(ord(x)))
 
+when defined(js):
+  proc asBigInt(x: float): int64 =
+    # result is a `BigInt` type in js, but we cheat the type system
+    # and say it is a `int64` type.
+    # TODO refactor it using bigInt once jsBigInt is ready, pending pr #1640
+    asm """
+    const buffer = new ArrayBuffer(8);
+    const floatBuffer = new Float64Array(buffer);
+    const uintBuffer = new BigUint64Array(buffer);
+    floatBuffer[0] = `x`;
+    `result` = uintBuffer[0];"""
+
 proc hash*(x: float): Hash {.inline.} =
   ## Efficient hashing of floats.
-  var y = x + 0.0 # for denormalization
-  result = hash(cast[ptr Hash](addr(y))[])
+  let y = x + 0.0 # for denormalization
+  when nimvm:
+    # workaround a JS VM bug: bug #16547
+    result = hashWangYi1(cast[int64](float64(y)))
+  else:
+    when not defined(js):
+      result = hashWangYi1(cast[Hash](y))
+    else:
+      result = hashWangYi1(asBigInt(y))
 
 # Forward declarations before methods that hash containers. This allows
 # containers to contain other containers