aboutsummaryrefslogtreecommitdiff
path: root/packages/bun-polyfills/lib
diff options
context:
space:
mode:
Diffstat (limited to 'packages/bun-polyfills/lib')
-rw-r--r--packages/bun-polyfills/lib/zighash/index.mjs95
-rw-r--r--packages/bun-polyfills/lib/zighash/package.json10
-rw-r--r--packages/bun-polyfills/lib/zighash/src/main.zig58
-rw-r--r--packages/bun-polyfills/lib/zighash/types.d.ts25
-rwxr-xr-xpackages/bun-polyfills/lib/zighash/zighash.wasmbin0 -> 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
new file mode 100755
index 000000000..1c8603f32
--- /dev/null
+++ b/packages/bun-polyfills/lib/zighash/zighash.wasm
Binary files differ