Created
October 31, 2024 17:08
-
-
Save kripken/7ebb963fae3d1c680dc02a8bdbcde669 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp | |
index 8ba6c10c4..e2bff86cd 100644 | |
--- a/src/passes/TypeSSA.cpp | |
+++ b/src/passes/TypeSSA.cpp | |
@@ -85,22 +85,26 @@ std::vector<HeapType> ensureTypesAreInNewRecGroup(RecGroup recGroup, | |
std::unordered_set<HeapType> existingSet(existing.begin(), existing.end()); | |
// Check for a collision with an existing rec group. Note that it is enough to | |
// check one of the types: either the entire rec group gets merged, so they | |
// are all merged, or not. | |
if (existingSet.count(types[0])) { | |
// Unfortunately there is a conflict. Handle it by adding a "hash" - a | |
// "random" extra item in the rec group that is so outlandish it will | |
// surely (?) never collide with anything. We must loop while doing so, | |
// until we find a hash that does not collide. | |
- auto hashSize = num + 10; | |
- size_t random = num; | |
+ // | |
+ // Note we use uint64_t here as these variables are used below to determine | |
+ // what "random" fields to emit, that is, these lead to observable things in | |
+ // the output, and must be the same on 32/64 bit. | |
+ uint64_t hashSize = num + 10; | |
+ uint64_t random = num; | |
while (1) { | |
// Make a builder and add a slot for the hash. | |
TypeBuilder builder(num + 1); | |
for (Index i = 0; i < num; i++) { | |
builder[i].copy(types[i]); | |
} | |
// Implement the hash as a struct with "random" fields, and add it. | |
Struct hashStruct; | |
for (Index i = 0; i < hashSize; i++) { | |
diff --git a/src/support/hash.h b/src/support/hash.h | |
index b99902616..254247afc 100644 | |
--- a/src/support/hash.h | |
+++ b/src/support/hash.h | |
@@ -15,46 +15,49 @@ | |
*/ | |
#ifndef wasm_support_hash_h | |
#define wasm_support_hash_h | |
#include <functional> | |
#include <stdint.h> | |
namespace wasm { | |
+// Explicitly use uint64_t rather than size_t to avoid differences on 32-bit. | |
+using wasm_hash_t = uint64_t; | |
+ | |
// Computes the digest of `value`. | |
-template<typename T> inline std::size_t hash(const T& value) { | |
+template<typename T> inline wasm_hash_t hash(const T& value) { | |
return std::hash<T>{}(value); | |
} | |
// Combines two digests into the first digest. Use instead of `rehash` if | |
-// `otherDigest` is another digest and not a `size_t` value. This is also useful | |
+// `otherDigest` is another digest and not a `wasm_hash_t`. This is also useful | |
// when you want deterministic behavior across systems, as this method does not | |
// call std::hash, so it does not depend on the behavior of the local machine's | |
// C++ standard library implementation. | |
-inline void hash_combine(std::size_t& digest, const std::size_t otherDigest) { | |
+inline void hash_combine(wasm_hash_t& digest, const wasm_hash_t otherDigest) { | |
// see: boost/container_hash/hash.hpp | |
// The constant is the N-bits reciprocal of the golden ratio: | |
// phi = (1 + sqrt(5)) / 2 | |
#if SIZE_MAX == UINT64_MAX | |
// trunc(2^64 / phi) = 0x9e3779b97f4a7c15 | |
digest ^= otherDigest + 0x9e3779b97f4a7c15 + (digest << 12) + (digest >> 4); | |
#else | |
// trunc(2^32 / phi) = 0x9e3779b9 | |
digest ^= otherDigest + 0x9e3779b9 + (digest << 6) + (digest >> 2); | |
#endif | |
} | |
// Hashes `value` and combines the resulting digest into the existing digest. | |
// Use instead of `hash_combine` if `value` is not another digest. | |
-template<typename T> inline void rehash(std::size_t& digest, const T& value) { | |
+template<typename T> inline void rehash(wasm_hash_t& digest, const T& value) { | |
hash_combine(digest, hash(value)); | |
} | |
} // namespace wasm | |
namespace std { | |
// Hashing pairs is often useful | |
template<typename T1, typename T2> struct hash<pair<T1, T2>> { | |
size_t operator()(const pair<T1, T2>& p) const { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment