mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-29 07:04:09 +08:00
Mix weak-collection hashes in 64 bits on 32-bit targets
uintptr_t is 32 bits on wasm32, where the weak-collection hashes shifted it by 33 and 56 bits. The hashes now widen keys, owners and kinds to uint64_t before mixing; 64-bit targets compute the same values as before.
This commit is contained in:
@@ -16157,16 +16157,19 @@ typedef struct { void *key; ScrWeakEntry *head; } ScrWeakKeySlot;
|
||||
static SCR_TL ScrWeakKeySlot *scr_weak_keys;
|
||||
static SCR_TL size_t scr_weak_keys_mask, scr_weak_keys_used;
|
||||
|
||||
static inline size_t scr_weak_mix(uintptr_t bits) {
|
||||
/* Mixed in 64 bits on every target: uintptr_t is 32 bits on wasm32, where
|
||||
* these shifts would exceed its width. */
|
||||
static inline size_t scr_weak_mix(uint64_t bits) {
|
||||
bits ^= bits >> 33;
|
||||
bits *= 0xff51afd7ed558ccdull;
|
||||
bits *= UINT64_C(0xff51afd7ed558ccd);
|
||||
bits ^= bits >> 29;
|
||||
return (size_t)bits;
|
||||
}
|
||||
static inline size_t scr_weak_entry_hash(const ScrWeakMap *owner, const void *key, unsigned kind) {
|
||||
return scr_weak_mix((uintptr_t)key ^ ((uintptr_t)owner * 0x9E3779B97F4A7C15ull) ^ ((uintptr_t)kind << 56));
|
||||
return scr_weak_mix((uint64_t)(uintptr_t)key ^ ((uint64_t)(uintptr_t)owner * UINT64_C(0x9E3779B97F4A7C15)) ^
|
||||
((uint64_t)kind << 56));
|
||||
}
|
||||
static inline size_t scr_weak_key_hash(const void *key) { return scr_weak_mix((uintptr_t)key); }
|
||||
static inline size_t scr_weak_key_hash(const void *key) { return scr_weak_mix((uint64_t)(uintptr_t)key); }
|
||||
|
||||
static void scr_weak_index_put(ScrWeakEntry *entry) {
|
||||
size_t j = scr_weak_entry_hash(entry->owner, entry->key, entry->kind) & scr_weak_index_mask;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { execFile, execFileSync } from "node:child_process";
|
||||
import { mkdir } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
@@ -85,3 +85,32 @@ test("json runtime: parser, dyn, dynCheck failure path, stringify buffer", async
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
function zigOnPath(): boolean {
|
||||
try {
|
||||
execFileSync("zig", ["version"], { stdio: "ignore" });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 32-bit uintptr_t: the weak-collection hashes mix in 64 bits, so no shift
|
||||
// exceeds the width of its operand on wasm32.
|
||||
test.skipIf(!zigOnPath())("json runtime builds for wasm32 without oversized shifts", async () => {
|
||||
await execFileAsync("zig", [
|
||||
"cc",
|
||||
"-target",
|
||||
"wasm32-wasi",
|
||||
"-std=c11",
|
||||
"-O2",
|
||||
"-D_GNU_SOURCE",
|
||||
"-D_WASI_EMULATED_SIGNAL",
|
||||
"-D_WASI_EMULATED_PROCESS_CLOCKS",
|
||||
"-Werror=shift-count-overflow",
|
||||
"-c",
|
||||
"-o",
|
||||
join(testDir, "build", "scr_json.wasm32.o"),
|
||||
join(testDir, "../src/scr_json.c"),
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -313,6 +313,9 @@ describe.skipIf(!zigOnPath())("wasm32-wasi differential", () => {
|
||||
// ThreadSlots blocks and pages hold 32-bit pointers.
|
||||
"5727-thread-slots-basics.ts",
|
||||
"5729-thread-slots-values.ts",
|
||||
// Weak-collection hashes mix 32-bit pointers in 64 bits.
|
||||
"4591-weak-keys-union-records.ts",
|
||||
"7742-weak-collections-many-keys.ts",
|
||||
])("the LLVM target runs %s byte-identically to Node", async (fixture) => {
|
||||
const entry = join(repoRoot, "tests/corpus", fixture);
|
||||
const outDir = await mkdtemp("/tmp/scriptc-wasi-");
|
||||
|
||||
Reference in New Issue
Block a user