Created
January 22, 2026 17:00
-
-
Save PhoenixIllusion/147f9247bb9cfde1f09d88d1aeee9905 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| export function ensureTableExported(wasm) { | |
| // --- minimal ULEB128 reader --- | |
| function readULEB(buf, o) { | |
| let v = 0, s = 0, p = o; | |
| while (true) { | |
| const b = buf[p++]; | |
| v |= (b & 0x7f) << s; | |
| if (!(b & 0x80)) | |
| break; | |
| s += 7; | |
| } | |
| return { v, n: p - o }; | |
| } | |
| // --- minimal ULEB128 writer --- | |
| function writeULEB(v) { | |
| const out = []; | |
| do { | |
| let b = v & 0x7f; | |
| v >>>= 7; | |
| if (v) | |
| b |= 0x80; | |
| out.push(b); | |
| } while (v); | |
| return Uint8Array.from(out); | |
| } | |
| let pos = 8; // skip wasm header | |
| let tableExists = false; | |
| let tableExported = false; | |
| let exportSecStart = -1; | |
| let exportPayloadStart = -1; | |
| let exportPayloadEnd = -1; | |
| let exportCount = 0; | |
| let exportCountLen = 0; | |
| // --- scan sections --- | |
| while (pos < wasm.length) { | |
| const id = wasm[pos]; | |
| const sizeInfo = readULEB(wasm, pos + 1); | |
| const size = sizeInfo.v; | |
| const payload = pos + 1 + sizeInfo.n; | |
| const end = payload + size; | |
| if (id === 4) { | |
| // table section | |
| const c = readULEB(wasm, payload).v; | |
| tableExists = c > 0; | |
| } | |
| if (id === 7) { | |
| // export section | |
| exportSecStart = pos; | |
| exportPayloadStart = payload; | |
| exportPayloadEnd = end; | |
| const cnt = readULEB(wasm, payload); | |
| exportCount = cnt.v; | |
| exportCountLen = cnt.n; | |
| let p = payload + cnt.n; | |
| for (let i = 0; i < exportCount; i++) { | |
| const nameLen = readULEB(wasm, p); | |
| p += nameLen.n + nameLen.v; | |
| const kind = wasm[p++]; | |
| const idx = readULEB(wasm, p); | |
| p += idx.n; | |
| if (kind === 1) | |
| tableExported = true; | |
| } | |
| } | |
| pos = end; | |
| } | |
| // nothing to do | |
| if (!tableExists || tableExported) | |
| return [wasm]; | |
| // --- build new export entry --- | |
| const name = "table"; | |
| const nameBytes = Uint8Array.from(name, c => c.charCodeAt(0)); | |
| const entry = [ | |
| writeULEB(nameBytes.length), | |
| nameBytes, | |
| Uint8Array.of(1), // kind = table | |
| writeULEB(0) // table index | |
| ]; | |
| // no export section → append one | |
| if (exportSecStart < 0) { | |
| const payload = [writeULEB(1), ...entry]; | |
| const plen = payload.reduce((a, b) => a + b.length, 0); | |
| return [ | |
| wasm, | |
| Uint8Array.of(7), | |
| writeULEB(plen), | |
| ...payload | |
| ]; | |
| } | |
| // --- patch existing export section --- | |
| const before = wasm.subarray(0, exportSecStart); | |
| const after = wasm.subarray(exportPayloadEnd); | |
| const newCount = writeULEB(exportCount + 1); | |
| const oldPayload = wasm.subarray(exportPayloadStart, exportPayloadEnd); | |
| const rest = oldPayload.subarray(exportCountLen); | |
| const newPayloadParts = [newCount, rest, ...entry]; | |
| const newPayloadLen = newPayloadParts.reduce((a, b) => a + b.length, 0); | |
| return [ | |
| before, | |
| Uint8Array.of(7), | |
| writeULEB(newPayloadLen), | |
| ...newPayloadParts, | |
| after | |
| ]; | |
| } |
This file contains hidden or 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
| export function ensureTableExported(wasm: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>[] { | |
| // --- minimal ULEB128 reader --- | |
| function readULEB(buf: Uint8Array, o: number) { | |
| let v = 0, s = 0, p = o; | |
| while (true) { | |
| const b = buf[p++]; | |
| v |= (b & 0x7f) << s; | |
| if (!(b & 0x80)) break; | |
| s += 7; | |
| } | |
| return { v, n: p - o }; | |
| } | |
| // --- minimal ULEB128 writer --- | |
| function writeULEB(v: number) { | |
| const out: number[] = []; | |
| do { | |
| let b = v & 0x7f; | |
| v >>>= 7; | |
| if (v) b |= 0x80; | |
| out.push(b); | |
| } while (v); | |
| return Uint8Array.from(out); | |
| } | |
| let pos = 8; // skip wasm header | |
| let tableExists = false; | |
| let tableExported = false; | |
| let exportSecStart = -1; | |
| let exportPayloadStart = -1; | |
| let exportPayloadEnd = -1; | |
| let exportCount = 0; | |
| let exportCountLen = 0; | |
| // --- scan sections --- | |
| while (pos < wasm.length) { | |
| const id = wasm[pos]; | |
| const sizeInfo = readULEB(wasm, pos + 1); | |
| const size = sizeInfo.v; | |
| const payload = pos + 1 + sizeInfo.n; | |
| const end = payload + size; | |
| if (id === 4) { | |
| // table section | |
| const c = readULEB(wasm, payload).v; | |
| tableExists = c > 0; | |
| } | |
| if (id === 7) { | |
| // export section | |
| exportSecStart = pos; | |
| exportPayloadStart = payload; | |
| exportPayloadEnd = end; | |
| const cnt = readULEB(wasm, payload); | |
| exportCount = cnt.v; | |
| exportCountLen = cnt.n; | |
| let p = payload + cnt.n; | |
| for (let i = 0; i < exportCount; i++) { | |
| const nameLen = readULEB(wasm, p); | |
| p += nameLen.n + nameLen.v; | |
| const kind = wasm[p++]; | |
| const idx = readULEB(wasm, p); | |
| p += idx.n; | |
| if (kind === 1) tableExported = true; | |
| } | |
| } | |
| pos = end; | |
| } | |
| // nothing to do | |
| if (!tableExists || tableExported) return [wasm]; | |
| // --- build new export entry --- | |
| const name = "table"; | |
| const nameBytes = Uint8Array.from(name, c => c.charCodeAt(0)); | |
| const entry = [ | |
| writeULEB(nameBytes.length), | |
| nameBytes, | |
| Uint8Array.of(1), // kind = table | |
| writeULEB(0) // table index | |
| ]; | |
| // no export section → append one | |
| if (exportSecStart < 0) { | |
| const payload = [writeULEB(1), ...entry]; | |
| const plen = payload.reduce((a, b) => a + b.length, 0); | |
| return [ | |
| wasm, | |
| Uint8Array.of(7), | |
| writeULEB(plen), | |
| ...payload | |
| ]; | |
| } | |
| // --- patch existing export section --- | |
| const before = wasm.subarray(0, exportSecStart); | |
| const after = wasm.subarray(exportPayloadEnd); | |
| const newCount = writeULEB(exportCount + 1); | |
| const oldPayload = wasm.subarray(exportPayloadStart, exportPayloadEnd); | |
| const rest = oldPayload.subarray(exportCountLen); | |
| const newPayloadParts = [newCount, rest, ...entry]; | |
| const newPayloadLen = newPayloadParts.reduce((a, b) => a + b.length, 0); | |
| return [ | |
| before, | |
| Uint8Array.of(7), | |
| writeULEB(newPayloadLen), | |
| ...newPayloadParts, | |
| after | |
| ]; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment