* Initialize a WebAssembly binary, given the * * @param {Buffer} bin - WebAssembly binary bytes * @throws If a binary is invalid
(bin)
| 536 | * @throws If a binary is invalid |
| 537 | */ |
| 538 | async function initWasm(bin) { |
| 539 | const eep = (name) => () => { |
| 540 | throw new Error( |
| 541 | `Internal error: unexpected call to "${name}" during Wasm verification`, |
| 542 | ); |
| 543 | }; |
| 544 | |
| 545 | let stderr = ''; |
| 546 | const wasmModule = await WebAssembly.compile(bin); |
| 547 | |
| 548 | const mockImports = { |
| 549 | wasi_snapshot_preview1: { |
| 550 | fd_write: function (fd, iovs, iovs_len, nwritten) { |
| 551 | if (fd !== 2) return 0; |
| 552 | const mem = new DataView(exports.memory.buffer); |
| 553 | let written = 0; |
| 554 | for (let i = 0; i < iovs_len; i++) { |
| 555 | const bufPtr = mem.getUint32(iovs + i * 8, true); |
| 556 | const bufLen = mem.getUint32(iovs + 4 + i * 8, true); |
| 557 | stderr += new TextDecoder().decode( |
| 558 | new Uint8Array(exports.memory.buffer, bufPtr, bufLen), |
| 559 | ); |
| 560 | written += bufLen; |
| 561 | } |
| 562 | mem.setUint32(nwritten, written, true); |
| 563 | return 1; |
| 564 | }, |
| 565 | }, |
| 566 | }; |
| 567 | |
| 568 | for (const { module, name } of WebAssembly.Module.imports(wasmModule)) { |
| 569 | mockImports[module] = mockImports[module] || {}; |
| 570 | if (!mockImports[module][name]) mockImports[module][name] = eep(name); |
| 571 | } |
| 572 | |
| 573 | const { exports } = await WebAssembly.instantiate(wasmModule, mockImports); |
| 574 | return { |
| 575 | exports, |
| 576 | getStderr() { |
| 577 | return stderr; |
| 578 | }, |
| 579 | }; |
| 580 | } |
| 581 | |
| 582 | /** |
| 583 | * Handle the output of `check_init()` |