diff options
Diffstat (limited to 'packages/bun-polyfills/lib')
-rw-r--r-- | packages/bun-polyfills/lib/zighash/index.mjs | 95 | ||||
-rw-r--r-- | packages/bun-polyfills/lib/zighash/package.json | 10 | ||||
-rw-r--r-- | packages/bun-polyfills/lib/zighash/src/main.zig | 58 | ||||
-rw-r--r-- | packages/bun-polyfills/lib/zighash/types.d.ts | 25 | ||||
-rwxr-xr-x | packages/bun-polyfills/lib/zighash/zighash.wasm | bin | 0 -> 14943 bytes |
5 files changed, 188 insertions, 0 deletions
diff --git a/packages/bun-polyfills/lib/zighash/index.mjs b/packages/bun-polyfills/lib/zighash/index.mjs new file mode 100644 index 000000000..f92ffb6d0 --- /dev/null +++ b/packages/bun-polyfills/lib/zighash/index.mjs @@ -0,0 +1,95 @@ +// @ts-check +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const { instance } = /** @type {ZighashInstance} */( + await WebAssembly.instantiate( + fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), 'zighash.wasm')), + { + env: { + /** @param {any} x */ + print(x) { console.log(x); }, + }, + } + ) +); +const exports = instance.exports; +const mem = exports.memory; +const memview = { + get u8() { return new Uint8Array(mem.buffer); }, + get u16() { return new Uint16Array(mem.buffer); }, + get u32() { return new Uint32Array(mem.buffer); }, + get u64() { return new BigUint64Array(mem.buffer); }, + get i8() { return new Int8Array(mem.buffer); }, + get i16() { return new Int16Array(mem.buffer); }, + get i32() { return new Int32Array(mem.buffer); }, + get i64() { return new BigInt64Array(mem.buffer); }, + get f32() { return new Float32Array(mem.buffer); }, + get f64() { return new Float64Array(mem.buffer); }, +}; + +const nullptr = { ptr: -1, size: 0 }; +const encoder = new TextEncoder(); + +const allocBuffer = ( + /** @type {ArrayBufferView | ArrayBuffer | SharedArrayBuffer} */ buf, + /** @type {boolean=} */ nullTerminate = false, +) => { + const size = buf.byteLength + +nullTerminate; + if (size === 0) return nullptr; + const ptr = exports.alloc(size); + if (ptr === -1) throw new Error('WASM memory allocation failed'); + const u8heap = memview.u8; + u8heap.set(new Uint8Array(ArrayBuffer.isView(buf) ? buf.buffer : buf), ptr); + if (nullTerminate) u8heap[ptr + buf.byteLength] = 0; + return { ptr, size }; +}; +const allocString = ( + /** @type {string} */ str, + /** @type {boolean=} */ nullTerminate = true, +) => { + const strbuf = encoder.encode(str); + return allocBuffer(strbuf, nullTerminate); +}; + +/** @type {JSSeededHash64Function} */ +export function wyhash(input = '', seed = 0n) { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return BigInt.asUintN(64, exports.wyhash(ptr, size, seed)); +} +/** @type {JSHash32Function} */ +export function adler32(input = '') { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return exports.adler32(ptr, size) >>> 0; +} +/** @type {JSHash32Function} */ +export function crc32(input = '') { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return exports.crc32(ptr, size) >>> 0; +} +/** @type {JSHash32Function} */ +export function cityhash32(input = '') { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return exports.cityhash32(ptr, size) >>> 0; +} +/** @type {JSSeededHash64Function} */ +export function cityhash64(input = '', seed = 0n) { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return BigInt.asUintN(64, exports.cityhash64(ptr, size, seed)); +} +/** @type {JSSeededHash32Function} */ +export function murmur32v3(input = '', seed = 0) { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return exports.murmur32v3(ptr, size, seed); //! Bun doesn't unsigned-cast this one, likely unintended but for now we'll do the same +} +/** @type {JSSeededHash32Function} */ +export function murmur32v2(input = '', seed = 0) { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return exports.murmur32v2(ptr, size, seed); //! Bun doesn't unsigned-cast this one, likely unintended but for now we'll do the same +} +/** @type {JSSeededHash64Function} */ +export function murmur64v2(input = '', seed = 0n) { + const { ptr, size } = typeof input === 'string' ? allocString(input, false) : allocBuffer(input); + return BigInt.asUintN(64, exports.murmur64v2(ptr, size, seed)); +} diff --git a/packages/bun-polyfills/lib/zighash/package.json b/packages/bun-polyfills/lib/zighash/package.json new file mode 100644 index 000000000..cda5ce887 --- /dev/null +++ b/packages/bun-polyfills/lib/zighash/package.json @@ -0,0 +1,10 @@ +{ + "private": true, + "type": "module", + "name": "zighash-wasm", + "module": "index.mjs", + "scripts": { + "build": "bun run clean && zig build-lib src/main.zig --name zighash -target wasm32-freestanding -dynamic -rdynamic -OReleaseSmall", + "clean": "rm -f *.wasm *.o" + } +} diff --git a/packages/bun-polyfills/lib/zighash/src/main.zig b/packages/bun-polyfills/lib/zighash/src/main.zig new file mode 100644 index 000000000..820557b43 --- /dev/null +++ b/packages/bun-polyfills/lib/zighash/src/main.zig @@ -0,0 +1,58 @@ +const std = @import("std"); + +extern fn print(*const u8) void; + +comptime { + std.debug.assert(@alignOf(u16) >= 2); + std.debug.assert(@alignOf(u32) >= 4); + std.debug.assert(@alignOf(u64) >= 8); + std.debug.assert(@alignOf(i16) >= 2); + std.debug.assert(@alignOf(i32) >= 4); + std.debug.assert(@alignOf(i64) >= 8); +} + +export fn alloc(size: u32) [*]const u8 { + const slice = std.heap.wasm_allocator.alloc(u8, size) catch @panic("wasm failed to allocate memory"); + return slice.ptr; +} + +export fn wyhash(input_ptr: [*]const u8, input_size: u32, seed: u64) u64 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.Wyhash.hash(seed, input); +} +export fn adler32(input_ptr: [*]const u8, input_size: u32) u32 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.Adler32.hash(input); +} +export fn crc32(input_ptr: [*]const u8, input_size: u32) u32 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.Crc32.hash(input); +} +export fn cityhash32(input_ptr: [*]const u8, input_size: u32) u32 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.CityHash32.hash(input); +} +export fn cityhash64(input_ptr: [*]const u8, input_size: u32, seed: u64) u64 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.CityHash64.hashWithSeed(input, seed); +} +export fn murmur32v3(input_ptr: [*]const u8, input_size: u32, seed: u32) u32 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.Murmur3_32.hashWithSeed(input, seed); +} +export fn murmur32v2(input_ptr: [*]const u8, input_size: u32, seed: u32) u32 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.Murmur2_32.hashWithSeed(input, seed); +} +export fn murmur64v2(input_ptr: [*]const u8, input_size: u32, seed: u64) u64 { + const input: []const u8 = input_ptr[0..input_size]; + defer std.heap.wasm_allocator.free(input); + return std.hash.Murmur2_64.hashWithSeed(input, seed); +} diff --git a/packages/bun-polyfills/lib/zighash/types.d.ts b/packages/bun-polyfills/lib/zighash/types.d.ts new file mode 100644 index 000000000..f0704ac94 --- /dev/null +++ b/packages/bun-polyfills/lib/zighash/types.d.ts @@ -0,0 +1,25 @@ +type WasmHash32Function = (input_ptr: number, input_size: number) => number; +type WasmHash64Function = (input_ptr: number, input_size: number) => bigint; +type WasmSeededHash32Function = (input_ptr: number, input_size: number, seed: number) => number; +type WasmSeededHash64Function = (input_ptr: number, input_size: number, seed: bigint) => bigint; +type JSHash32Function = (input: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer) => number; +type JSHash64Function = (input: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer) => bigint; +type JSSeededHash32Function = (input: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: number) => number; +type JSSeededHash64Function = (input: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, seed?: bigint) => bigint; + +type ZighashInstance = WebAssembly.WebAssemblyInstantiatedSource & { + instance: { + exports: { + memory: WebAssembly.Memory, + alloc(size: number): number, + wyhash: WasmSeededHash64Function, + adler32: WasmHash32Function, + crc32: WasmHash32Function, + cityhash32: WasmHash32Function, + cityhash64: WasmSeededHash64Function, + murmur32v3: WasmSeededHash32Function, + murmur32v2: WasmSeededHash32Function, + murmur64v2: WasmSeededHash64Function, + }; + }; +} diff --git a/packages/bun-polyfills/lib/zighash/zighash.wasm b/packages/bun-polyfills/lib/zighash/zighash.wasm Binary files differnew file mode 100755 index 000000000..1c8603f32 --- /dev/null +++ b/packages/bun-polyfills/lib/zighash/zighash.wasm |