8bitworkshop
8bitworkshop copied to clipboard
Move to WASI for tool binaries
We've been using Emscripten, but WASI is better-suited to headless command-line tools.
https://github.com/WebAssembly/wasi-sdk
Will have to rebuild everything, like this:
make CC="$WASISDK/bin/clang --sysroot=$WASISDK/share/wasi-sysroot -g" AR="$WASISDK/bin/ar" EXE_SUFFIX=.wasm cc65
Exceptions might not work yet, though. So have to stay w/ Emscripten for some tools for now.
Runtime: https://github.com/wasmerio/wasmer-js
Example
import { WASI } from "@wasmer/wasi"
import { WasmFs } from "@wasmer/wasmfs"
const wasmBindings = require("@wasmer/wasi/lib/bindings/node").default
var fs = require('fs')
var binary = fs.readFileSync('./cc65.wasm')
var mod = new WebAssembly.Module(binary);
function go() {
var wasmFs = new WasmFs();
wasmFs.fs.mkdirSync('/work');
wasmFs.fs.writeFileSync('/work/test.c', 'void main(void) { return; }')
var bindings = Object.create(wasmBindings);
bindings.exit = (code?: number) => { console.log('exit',code); return 0; }
bindings.fs = wasmFs.fs
let myWASIInstance = new WASI({
// OPTIONAL: The pre-opened dirctories
preopenDirectories: {'/work':'/work'},
// OPTIONAL: The environment vars
env: {},
// OPTIONAL: The arguments provided
args: ['cc65', '/work/test.c', '--verbose'],
// OPTIONAL: The environment bindings (fs, path),
// useful for using WASI in diferent environments
// such as Node.js, Browsers, ...
bindings: bindings,
//exit: (code?: number) => { console.log('exit',code); return 0; },
// kill: (pid: number, signal?: string | number) -> void
// randomFillSync: (buffer: Buffer, offset?: number, size?: number) -> Buffer
// isTTY: () -> bool
// fs: Filesystem (with similar API interface as Node 'fs' module)
// path: Path (with similar API Interface as Node 'path' module)
});
var inst = new WebAssembly.Instance(mod, myWASIInstance.getImports(mod));
var _exports = inst.exports;
console.log(inst);
try {
myWASIInstance.start(inst);
} catch (e) {
console.log('error',e); // maybe exit() was called?
}
console.log(wasmFs.fs.readFileSync('/work/test.s'));
}
go();