aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/alg.go33
-rw-r--r--src/runtime/hash32.go2
-rw-r--r--src/runtime/hash64.go2
3 files changed, 25 insertions, 12 deletions
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index b956f9d05a..c5951dc20b 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -14,10 +14,23 @@ import (
)
const (
- c0 = uintptr((8-goarch.PtrSize)/4*2860486313 + (goarch.PtrSize-4)/4*33054211828000289)
- c1 = uintptr((8-goarch.PtrSize)/4*3267000013 + (goarch.PtrSize-4)/4*23344194077549503)
+ // We use 32-bit hash on Wasm, see hash32.go.
+ hashSize = (1-goarch.IsWasm)*goarch.PtrSize + goarch.IsWasm*4
+ c0 = uintptr((8-hashSize)/4*2860486313 + (hashSize-4)/4*33054211828000289)
+ c1 = uintptr((8-hashSize)/4*3267000013 + (hashSize-4)/4*23344194077549503)
)
+func trimHash(h uintptr) uintptr {
+ if goarch.IsWasm != 0 {
+ // On Wasm, we use 32-bit hash, despite that uintptr is 64-bit.
+ // memhash* always returns a uintptr with high 32-bit being 0
+ // (see hash32.go). We trim the hash in other places where we
+ // compute the hash manually, e.g. in interhash.
+ return uintptr(uint32(h))
+ }
+ return h
+}
+
func memhash0(p unsafe.Pointer, h uintptr) uintptr {
return h
}
@@ -100,9 +113,9 @@ func f32hash(p unsafe.Pointer, h uintptr) uintptr {
f := *(*float32)(p)
switch {
case f == 0:
- return c1 * (c0 ^ h) // +0, -0
+ return trimHash(c1 * (c0 ^ h)) // +0, -0
case f != f:
- return c1 * (c0 ^ h ^ uintptr(rand())) // any kind of NaN
+ return trimHash(c1 * (c0 ^ h ^ uintptr(rand()))) // any kind of NaN
default:
return memhash(p, h, 4)
}
@@ -112,9 +125,9 @@ func f64hash(p unsafe.Pointer, h uintptr) uintptr {
f := *(*float64)(p)
switch {
case f == 0:
- return c1 * (c0 ^ h) // +0, -0
+ return trimHash(c1 * (c0 ^ h)) // +0, -0
case f != f:
- return c1 * (c0 ^ h ^ uintptr(rand())) // any kind of NaN
+ return trimHash(c1 * (c0 ^ h ^ uintptr(rand()))) // any kind of NaN
default:
return memhash(p, h, 8)
}
@@ -145,9 +158,9 @@ func interhash(p unsafe.Pointer, h uintptr) uintptr {
panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if t.IsDirectIface() {
- return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
+ return trimHash(c1 * typehash(t, unsafe.Pointer(&a.data), h^c0))
} else {
- return c1 * typehash(t, a.data, h^c0)
+ return trimHash(c1 * typehash(t, a.data, h^c0))
}
}
@@ -172,9 +185,9 @@ func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if t.IsDirectIface() {
- return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
+ return trimHash(c1 * typehash(t, unsafe.Pointer(&a.data), h^c0))
} else {
- return c1 * typehash(t, a.data, h^c0)
+ return trimHash(c1 * typehash(t, a.data, h^c0))
}
}
diff --git a/src/runtime/hash32.go b/src/runtime/hash32.go
index 0616c7dd05..8589893127 100644
--- a/src/runtime/hash32.go
+++ b/src/runtime/hash32.go
@@ -5,7 +5,7 @@
// Hashing algorithm inspired by
// wyhash: https://github.com/wangyi-fudan/wyhash/blob/ceb019b530e2c1c14d70b79bfa2bc49de7d95bc1/Modern%20Non-Cryptographic%20Hash%20Function%20and%20Pseudorandom%20Number%20Generator.pdf
-//go:build 386 || arm || mips || mipsle
+//go:build 386 || arm || mips || mipsle || wasm
package runtime
diff --git a/src/runtime/hash64.go b/src/runtime/hash64.go
index 124bb7d77a..ac26e660c6 100644
--- a/src/runtime/hash64.go
+++ b/src/runtime/hash64.go
@@ -5,7 +5,7 @@
// Hashing algorithm inspired by
// wyhash: https://github.com/wangyi-fudan/wyhash
-//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
+//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x
package runtime