The following code should work to test WebAssembly in various JS runtimes with minor modifications:
const bytes = /* read a .wasm file somehow */;
const mod = new WebAssembly.Module(bytes);
const instance = new WebAssembly.Instance(mod, { /* imports */ });
const { foo, bar } = instance.exports;
// call whichever functions you like
new WebAssembly.Module
and new WebAssembly.Instance
are synchronous, unlike WebAssembly.instantiateStreaming
and friends.
In the examples below, I show how to load a wasm file from disk, but you can of course hardcode the filename if you prefer.
To test wasm on V8, you can use either Node or V8's standalone shell "D8". To test on SpiderMonkey, you can use a shell-only build. I have no idea about JavaScriptCore (Safari).
My coworker recommends a tool called jsvu
for installing multiple JS runtimes without needing to build them: https://github.com/GoogleChromeLabs/jsvu. Doing so would require you to install Node first so it might not be totally worth it, but it could make things easier overall. Otherwise you can try following specific installation steps below.
Info: https://v8.dev/docs/d8. D8 will generally be more up-to-date than whatever version of V8 is in Node, but for Odin it probably doesn't matter.
// run_wasm_d8.js
const bytes = readbuffer(arguments[0]);
const mod = new WebAssembly.Module(bytes);
const instance = new WebAssembly.Instance(mod, { /* imports */ });
const { foo, bar } = instance.exports;
// call whichever functions you like
d8 run_wasm_d8.js -- mymodule.wasm
Local files can be read as binary using readbuffer
; arguments
is argv. Note that d8 requires a --
before any script arguments.
D8 should be installed automatically as part of a typical V8 install; I don't know how to do that on all platforms, but I think I just did brew install v8
on Mac, so maybe it's in your package manager of choice.
SpiderMonkey has a standalone Node-like shell which we typically use for testing.
// run_wasm_sm.js
const bytes = os.file.readFile(scriptArgs[0], "binary");
const mod = new WebAssembly.Module(bytes);
const instance = new WebAssembly.Instance(mod, { /* imports */ });
const { foo, bar } = instance.exports;
// call whichever functions you like
js run_wasm_sm.js mymodule.wasm
os.file.readFile
will synchronously read a file; scriptArgs
is argv.
SpiderMonkey shell builds can be downloaded from Mozilla's FTP server. Search for jsshell
: https://ftp.mozilla.org/pub/firefox/nightly/latest-mozilla-central/
The link above is for the latest nightly build, but you can also find official releases on the FTP server as well.
// run_wasm_node.js
const fs = require("fs");
const process = require("process");
const bytes = fs.readFileSync(process.argv[2]);
const mod = new WebAssembly.Module(bytes);
const instance = new WebAssembly.Instance(mod, { /* imports */ });
const { foo, bar } = instance.exports;
// call whichever functions you like
node run_wasm_node.js mymodule.wasm
Note that the interesting arguments to argv
start at 2 instead of 0 in Node-world.
I dunno, use a package manager or something?