import WASI from "./wasi";
import type { WASIConfig } from "./types";
import nodeBindings from "./bindings/node";
import fs from "fs";
import { readFile } from "fs/promises";
import debug from "debug";
const log = debug("wasi");
interface Options {
noWasi?: boolean;
env?: object;
dir?: string | null;
time?: boolean;
}
async function wasmImport(name: string, options: Options = {}): Promise<void> {
const pathToWasm = `${name}${name.endsWith(".wasm") ? "" : ".wasm"}`;
function getrandom(bufPtr, bufLen, _flags) {
nodeBindings.randomFillSync(
new Uint8Array(result.instance.exports.memory.buffer),
bufPtr,
bufLen
);
return bufLen;
}
const wasmOpts: any = {
env: new Proxy(
{ getrandom, ...options?.env },
{
get(target, key) {
if (key in target) {
return Reflect.get(target, key);
}
log("WARNING: creating stub for", key);
return (..._args) => {
return 0;
};
},
}
),
};
let wasi: any = undefined;
if (!options?.noWasi) {
const opts: WASIConfig = {
args: process.argv,
bindings: nodeBindings,
env: process.env,
};
if (options.dir === null) {
} else {
opts.bindings = {
...nodeBindings,
fs,
};
if (!options.dir) {
opts.preopens = { "/": "/" };
} else {
opts.preopens = { [options.dir]: options.dir };
}
}
wasi = new WASI(opts);
wasmOpts.wasi_snapshot_preview1 = wasi.wasiImport;
}
const source = await readFile(pathToWasm);
const typedArray = new Uint8Array(source);
const result = await WebAssembly.instantiate(typedArray, wasmOpts);
if (wasi != null) {
wasi.start(result.instance);
}
}
export async function run(name: string, options: Options = {}): Promise<void> {
await wasmImport(name, options);
}