Skip to content

Commit 77da497

Browse files
committed
tweaks
1 parent f709bfb commit 77da497

File tree

3 files changed

+46
-48
lines changed

3 files changed

+46
-48
lines changed

src/utils/utf8-wasm-binary.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
1-
// Auto-generated by wasm/build.sh - do not edit manually
1+
// Auto-generated by wasm/build.sh - DO NOT EDIT MANUALLY
22
// Source: wasm/utf8.wat
33

4-
export const wasmBinary = "AGFzbQEAAAABNQhedwFgAW8Bf2ADb2QAfwF/YANkAH9/AWRvYAJvfwF/YAJ/ZAABf2ABfwFkAGADZAB/fwFvAl8DDndhc206anMtc3RyaW5nBmxlbmd0aAABDndhc206anMtc3RyaW5nEWludG9DaGFyQ29kZUFycmF5AAIOd2FzbTpqcy1zdHJpbmcRZnJvbUNoYXJDb2RlQXJyYXkAAwMGBQEEBQYHBQMBAAEHVAYGbWVtb3J5AgAJdXRmOENvdW50AAMKdXRmOEVuY29kZQAEEXV0ZjhEZWNvZGVUb0FycmF5AAUKYWxsb2NBcnJheQAGDWFycmF5VG9TdHJpbmcABwqZBgWEAQIEfwFkACAAEAAiBEUEQEEADwsgACAE+wcAIgVBABABGgNAIAEgBE9FBEAgBSAB+w0AIgNBgAFJBH8gAkEBagUgA0GAEEkEfyACQQJqBSADQf+3A00gA0GAsANPcQR/IAFBAWohASACQQRqBSACQQNqCwsLIQIgAUEBaiEBDAELCyACC7wCAgR/AWQAIAEhAiAAEAAiBUUEQEEADwsgACAF+wcAIgZBABABGgNAIAQgBU9FBEAgBiAE+w0AIgNBgAFJBH8gAiADOgAAIAJBAWoFIANBgBBJBH8gAiADQQZ2QcABcjoAACACQQFqIANBP3FBgAFyOgAAIAJBAmoFIANB/7cDTSADQYCwA09xBH8gAiADQQp0IAYgBEEBaiIE+w0AakGAuP8aayIDQRJ2QfABcjoAACACQQFqIANBDHZBP3FBgAFyOgAAIAJBAmogA0EGdkE/cUGAAXI6AAAgAkEDaiADQT9xQYABcjoAACACQQRqBSACIANBDHZB4AFyOgAAIAJBAWogA0EGdkE/cUGAAXI6AAAgAkECaiADQT9xQYABcjoAACACQQNqCwsLIQIgBEEBaiEEDAELCyACIAFrC78CAQN/A0AgACACSwRAIAItAAAiBEGAAXFFBEAgASADIAT7DgAgA0EBaiEDIAJBAWohAgwCCyAEQeABcUHAAUYEQCABIAMgAkEBai0AAEE/cSAEQR9xQQZ0cvsOACADQQFqIQMgAkECaiECDAILIARB8AFxQeABRgRAIAEgAyACQQJqLQAAQT9xIARBD3FBDHQgAkEBai0AAEE/cUEGdHJy+w4AIANBAWohAyACQQNqIQIMAgsgBEH4AXFB8AFGBEAgASADIAJBA2otAABBP3EgBEEHcUESdCACQQFqLQAAQT9xQQx0ciACQQJqLQAAQT9xQQZ0cnJBgIAEayIEQQp2QYCwA3L7DgAgASADQQFqIgMgBEH/B3FBgLgDcvsOACADQQFqIQMgAkEEaiECDAIFIAJBAWohAgwCCwALCyADCwcAIAD7BwALCgAgACABIAIQAgs=";
4+
export const wasmBinary = `
5+
AGFzbQEAAAABNQhedwFgAW8Bf2ADb2QAfwF/YANkAH9/AWRvYAJvfwF/YAJ/ZAABf2ABfwFkAGADZA
6+
B/fwFvAl8DDndhc206anMtc3RyaW5nBmxlbmd0aAABDndhc206anMtc3RyaW5nEWludG9DaGFyQ29k
7+
ZUFycmF5AAIOd2FzbTpqcy1zdHJpbmcRZnJvbUNoYXJDb2RlQXJyYXkAAwMGBQEEBQYHBQMBAAEHVA
8+
YGbWVtb3J5AgAJdXRmOENvdW50AAMKdXRmOEVuY29kZQAEEXV0ZjhEZWNvZGVUb0FycmF5AAUKYWxs
9+
b2NBcnJheQAGDWFycmF5VG9TdHJpbmcABwqZBgWEAQIEfwFkACAAEAAiBEUEQEEADwsgACAE+wcAIg
10+
VBABABGgNAIAEgBE9FBEAgBSAB+w0AIgNBgAFJBH8gAkEBagUgA0GAEEkEfyACQQJqBSADQf+3A00g
11+
A0GAsANPcQR/IAFBAWohASACQQRqBSACQQNqCwsLIQIgAUEBaiEBDAELCyACC7wCAgR/AWQAIAEhAi
12+
AAEAAiBUUEQEEADwsgACAF+wcAIgZBABABGgNAIAQgBU9FBEAgBiAE+w0AIgNBgAFJBH8gAiADOgAA
13+
IAJBAWoFIANBgBBJBH8gAiADQQZ2QcABcjoAACACQQFqIANBP3FBgAFyOgAAIAJBAmoFIANB/7cDTS
14+
ADQYCwA09xBH8gAiADQQp0IAYgBEEBaiIE+w0AakGAuP8aayIDQRJ2QfABcjoAACACQQFqIANBDHZB
15+
P3FBgAFyOgAAIAJBAmogA0EGdkE/cUGAAXI6AAAgAkEDaiADQT9xQYABcjoAACACQQRqBSACIANBDH
16+
ZB4AFyOgAAIAJBAWogA0EGdkE/cUGAAXI6AAAgAkECaiADQT9xQYABcjoAACACQQNqCwsLIQIgBEEB
17+
aiEEDAELCyACIAFrC78CAQN/A0AgACACSwRAIAItAAAiBEGAAXFFBEAgASADIAT7DgAgA0EBaiEDIA
18+
JBAWohAgwCCyAEQeABcUHAAUYEQCABIAMgAkEBai0AAEE/cSAEQR9xQQZ0cvsOACADQQFqIQMgAkEC
19+
aiECDAILIARB8AFxQeABRgRAIAEgAyACQQJqLQAAQT9xIARBD3FBDHQgAkEBai0AAEE/cUEGdHJy+w
20+
4AIANBAWohAyACQQNqIQIMAgsgBEH4AXFB8AFGBEAgASADIAJBA2otAABBP3EgBEEHcUESdCACQQFq
21+
LQAAQT9xQQx0ciACQQJqLQAAQT9xQQZ0cnJBgIAEayIEQQp2QYCwA3L7DgAgASADQQFqIgMgBEH/B3
22+
FBgLgDcvsOACADQQFqIQMgAkEEaiECDAIFIAJBAWohAgwCCwALCyADCwcAIAD7BwALCgAgACABIAIQ
23+
Ags=
24+
`;

src/utils/utf8-wasm.ts

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const WASM_MODE = getWasmMode();
4040
// GC array type (opaque reference)
4141
type I16Array = object;
4242

43-
interface WasmExports {
43+
interface WasmExports extends WebAssembly.Exports {
4444
memory: WebAssembly.Memory;
4545
utf8Count(str: string): number;
4646
utf8Encode(str: string, offset: number): number;
@@ -65,11 +65,7 @@ function base64ToBytes(base64: string): Uint8Array {
6565
return new Uint8Array(Buffer.from(base64, "base64"));
6666
}
6767

68-
function tryInitWasm(): void {
69-
if (wasmInstance !== null || wasmInitError !== null) {
70-
return; // Already initialized or failed
71-
}
72-
68+
function tryInitializeWasmInstance(): void {
7369
if (WASM_MODE === "never") {
7470
wasmInitError = new Error("MSGPACK_WASM=never: wasm disabled");
7571
return;
@@ -85,35 +81,28 @@ function tryInitWasm(): void {
8581
// Requires js-string builtins support (Node.js 24+ / Chrome 130+ / Firefox 134+)
8682
const module: WebAssembly.Module = new (WebAssembly.Module as any)(bytes, { builtins: ["js-string"] });
8783
const instance = new WebAssembly.Instance(module);
88-
wasmInstance = instance.exports as unknown as WasmExports;
84+
wasmInstance = instance.exports as WasmExports;
8985
} catch (e) {
9086
wasmInitError = e instanceof Error ? e : new Error(String(e));
9187

9288
if (WASM_MODE === "force") {
93-
throw new Error(`MSGPACK_WASM=force but wasm failed to load: ${wasmInitError.message}`);
89+
throw new Error(`MSGPACK_WASM=force but wasm failed to load: ${wasmInitError.message}`, { cause: wasmInitError });
9490
}
9591
}
9692
}
9793

98-
// Initialize on module load
99-
tryInitWasm();
94+
tryInitializeWasmInstance();
10095

10196
/**
10297
* Whether wasm is available and initialized.
10398
*/
10499
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
105100
export const WASM_AVAILABLE = wasmInstance !== null;
106101

107-
/**
108-
* Get the wasm initialization error, if any.
109-
*/
110102
export function getWasmError(): Error | null {
111103
return wasmInitError;
112104
}
113105

114-
/**
115-
* Get the raw wasm exports for advanced usage.
116-
*/
117106
export function getWasmExports(): WasmExports | null {
118107
return wasmInstance;
119108
}
@@ -122,39 +111,32 @@ export function getWasmExports(): WasmExports | null {
122111
* Count UTF-8 byte length of a string.
123112
*/
124113
export function utf8CountWasm(str: string): number {
125-
if (wasmInstance === null) {
126-
throw new Error("wasm not initialized");
127-
}
128-
return wasmInstance.utf8Count(str);
114+
return wasmInstance!.utf8Count(str);
129115
}
130116

131117
/**
132118
* Encode string to UTF-8 bytes in the provided buffer.
133119
* Returns the number of bytes written.
134120
*/
135121
export function utf8EncodeWasm(str: string, output: Uint8Array, outputOffset: number): number {
136-
if (wasmInstance === null) {
137-
throw new Error("wasm not initialized");
138-
}
139-
140122
// Estimate max byte length without a full pass over the string.
141123
// Each UTF-16 code unit can produce at most 3 UTF-8 bytes (BMP chars).
142124
// Surrogate pairs (2 code units) produce 4 bytes, so 3 bytes/code unit is safe.
143125
const maxByteLength = str.length * 3;
144126

145127
// Ensure wasm memory is large enough
146128
const requiredPages = Math.ceil(maxByteLength / 65536);
147-
const currentPages = wasmInstance.memory.buffer.byteLength / 65536;
129+
const currentPages = wasmInstance!.memory.buffer.byteLength / 65536;
148130

149131
if (requiredPages > currentPages) {
150-
wasmInstance.memory.grow(requiredPages - currentPages);
132+
wasmInstance!.memory.grow(requiredPages - currentPages);
151133
}
152134

153135
// Encode to wasm memory (uses intoCharCodeArray for bulk char extraction)
154-
const bytesWritten = wasmInstance.utf8Encode(str, 0);
136+
const bytesWritten = wasmInstance!.utf8Encode(str, 0);
155137

156138
// Copy from wasm memory to output buffer
157-
const wasmBytes = new Uint8Array(wasmInstance.memory.buffer, 0, bytesWritten);
139+
const wasmBytes = new Uint8Array(wasmInstance!.memory.buffer, 0, bytesWritten);
158140
output.set(wasmBytes, outputOffset);
159141

160142
return bytesWritten;
@@ -165,33 +147,29 @@ export function utf8EncodeWasm(str: string, output: Uint8Array, outputOffset: nu
165147
* Uses GC arrays with fromCharCodeArray for efficient string creation.
166148
*/
167149
export function utf8DecodeWasm(bytes: Uint8Array, inputOffset: number, byteLength: number): string {
168-
if (wasmInstance === null) {
169-
throw new Error("wasm not initialized");
170-
}
171-
172150
// Handle empty input
173151
if (byteLength === 0) {
174152
return "";
175153
}
176154

177155
// Ensure wasm memory is large enough for UTF-8 input
178156
const requiredPages = Math.ceil(byteLength / 65536);
179-
const currentPages = wasmInstance.memory.buffer.byteLength / 65536;
157+
const currentPages = wasmInstance!.memory.buffer.byteLength / 65536;
180158

181159
if (requiredPages > currentPages) {
182-
wasmInstance.memory.grow(requiredPages - currentPages);
160+
wasmInstance!.memory.grow(requiredPages - currentPages);
183161
}
184162

185163
// Copy UTF-8 bytes to wasm linear memory at offset 0
186-
const wasmBytes = new Uint8Array(wasmInstance.memory.buffer, 0, byteLength);
164+
const wasmBytes = new Uint8Array(wasmInstance!.memory.buffer, 0, byteLength);
187165
wasmBytes.set(bytes.subarray(inputOffset, inputOffset + byteLength));
188166

189167
// Allocate GC array for UTF-16 output (max size = byteLength for ASCII)
190-
const arr = wasmInstance.allocArray(byteLength);
168+
const arr = wasmInstance!.allocArray(byteLength);
191169

192170
// Decode UTF-8 to UTF-16 in GC array
193-
const codeUnits = wasmInstance.utf8DecodeToArray(byteLength, arr);
171+
const codeUnits = wasmInstance!.utf8DecodeToArray(byteLength, arr);
194172

195173
// Create string directly from GC array using fromCharCodeArray
196-
return wasmInstance.arrayToString(arr, 0, codeUnits);
174+
return wasmInstance!.arrayToString(arr, 0, codeUnits);
197175
}

wasm/build.sh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ wasm-opt --enable-gc --enable-strings --enable-reference-types -O4 utf8.wasm -o
1212
mv tmp.wasm utf8.wasm
1313

1414
echo "Generating base64 TypeScript module..."
15-
cat > ../src/utils/utf8-wasm-binary.ts << 'HEADER'
16-
// Auto-generated by wasm/build.sh - do not edit manually
17-
// Source: wasm/utf8.wat
1815

19-
HEADER
20-
21-
echo -n "export const wasmBinary = \"" >> ../src/utils/utf8-wasm-binary.ts
22-
base64 -i utf8.wasm | tr -d '\n' >> ../src/utils/utf8-wasm-binary.ts
23-
echo "\";" >> ../src/utils/utf8-wasm-binary.ts
16+
{
17+
echo "// Auto-generated by wasm/build.sh - DO NOT EDIT MANUALLY"
18+
echo "// Source: wasm/utf8.wat"
19+
echo ""
20+
echo "export const wasmBinary = \`"
21+
base64 -b 78 -i utf8.wasm
22+
echo "\`;"
23+
} > ../src/utils/utf8-wasm-binary.ts
2424

2525
echo "Done! Generated:"
2626
echo " - wasm/utf8.wasm ($(wc -c < utf8.wasm | tr -d ' ') bytes)"

0 commit comments

Comments
 (0)