"use strict"; const fs = require("fs"); const {WASI} = require("wasi"); const separatorIndex = process.argv.indexOf("--"); const runWasmArgs = process.argv.slice(1, separatorIndex) const isWasm64 = runWasmArgs.includes("--wasm64"); const isPatioTest = runWasmArgs.includes("--patio-test"); const wasmExecutablePath = process.argv[separatorIndex + 1]; const createWasi = isWasm64 ? createWasiForWasm64 : createWasiForWasm32; function createWasiForWasm32() { return new WASI({ version: "preview1", args: process.argv.slice(2), env: process.env, returnOnExit: false, }); } function createWasiForWasm64() { // When using the builtin WASI with wasm64, nothing seems to get printed to // stdout. It's not clear whether the compiler makes an incorrect assumption // about what node thinks the API for fd_write is on wasm64, or whether WASI // isn't supported by node on wasm64, but given that (so far as I known) // WASI isn't really defined for wasm64, it seems reasonable to roll our own // implementation for now. let runningInstance = null; const wasiImport = { fd_write: (fd, iovsPtr, iovsLen, nwritten) => { iovsPtr = Number(iovsPtr); const memoryBuffer = runningInstance.exports.memory.buffer; const memoryDataView = new DataView(memoryBuffer); for (let iovsIndex = 0; iovsIndex < iovsLen; iovsIndex++) { const iovPtr = iovsPtr + iovsIndex * 16; const bufPtr = Number(memoryDataView.getBigUint64(iovPtr, true)); const bufLen = Number(memoryDataView.getBigUint64(iovPtr + 8, true)); const buf = Buffer.from(memoryBuffer, bufPtr, bufLen); // TODO: handle fd !== 1 process.stdout.write(buf); } // TODO: update nwritten }, proc_exit: (exitCode) => { process.exit(exitCode); }, }; const start = (instance) => { runningInstance = instance; instance.exports._start(); }; return {wasiImport, start}; } (async () => { const wasi = createWasi(); const importObject = { "wasi_snapshot_preview1": wasi.wasiImport, }; if (isPatioTest) { importObject["env"] = { patio__test__emit_int: (value) => { console.log(value.toString()); }, }; } const wasm = await WebAssembly.compile(fs.readFileSync(wasmExecutablePath)); const instance = await WebAssembly.instantiate(wasm, importObject); wasi.start(instance); })();