Yesterday, I looked up whether node.js can run wasm files, and I found a Stack Overflow answer and post that showed how. I couldn’t get the C file to compile to wasm in a way that would run in node*, but compiling a WebAssembly Text file worked.
First, put this in a file called test.wat
:
(module
(func $addTwo (param i32 i32) (result i32)
(i32.add
(get_local 0)
(get_local 1)))
(export "addTwo" (func $addTwo)))
After you have the “wabbit” installed**, compile with:
$ wat2wasm test.wat -o test.wasm
Create an app.js
file with the code below:
const fs = require('fs');
const util = require('util');
const source = fs.readFileSync('./test.wasm');
const typedArray = new Uint8Array(source);
const env = {
memoryBase: 0,
tableBase: 0,
memory: new WebAssembly.Memory({
initial: 256
}),
table: new WebAssembly.Table({
initial: 0,
element: 'anyfunc'
})
};
WebAssembly.instantiate(typedArray, {
env: env
}).then(result => {
// console.log(util.inspect(result, true, 0));
// console.log('result.instance', result.instance);
// Run the WebAssembly function
console.log(result.instance.exports.addTwo(127, 1));
}).catch(e => {
console.log(e);
});
Then run it with:
$ node app
*I was getting errors like these when trying to run the C code, but I don’t know enough about how wasm works yet to debug it.
$ emcc test.c -Os -s WASM=1 -s SIDE_MODULE=1 -o test.wasm
$ node app
LinkError: WebAssembly Instantiation: Import #0 module="env" function="__memory_base" error: global import must be a number
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
at Function.Module.runMain (module.js:678:11)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
$ wasm2wat test.wasm
(module
(type (;0;) (func))
(import "env" "__memory_base" (global (;0;) i32))
(func (;0;) (type 0)
global.get 0
global.set 1
global.get 1
i32.const 5242880
i32.add
global.set 2)
(global (;1;) (mut i32) (i32.const 0))
(global (;2;) (mut i32) (i32.const 0))
(export "__post_instantiate" (func 0)))
**I installed wabt by cloning the repo, compiling it with the command below, and then putting the resulting executable files on my PATH.
$ make gcc-release