Skip to content

Instantly share code, notes, and snippets.

@hoangpq
Forked from kanaka/addTwo.wast
Created November 26, 2018 08:44
Show Gist options
  • Select an option

  • Save hoangpq/b754cbb18fd024ea9bc3cdf17ba9ef48 to your computer and use it in GitHub Desktop.

Select an option

Save hoangpq/b754cbb18fd024ea9bc3cdf17ba9ef48 to your computer and use it in GitHub Desktop.
Run wast (WebAssembly) in node

Simple wabt + node WebAssembly Example

Prerequisites:

  • Install node 7.x (instructions). I've tested this with node 7.7.1

  • Download and build branch of wabt (binary_0xc) supporting same version of WebAssembly as node 7 (version 12):

    git clone --recursive https://github.com/WebAssembly/wabt/
    cd wabt
    git checkout binary_0xc
    make gcc-release

Compile and run:

  • Use wast2wasm from wabt to build WebAssembly binary object (wasm):

    wabt/out/gcc/Release/wast2wasm addTwo.wast -o addTwo.wasm
  • Use the runasm.js script to call the exported "addTwo" function:

    ./runwasm.js addTwo.wasm addTwo 2 3
(module
(func $addTwo (param i32 i32) (result i32)
(i32.add
(get_local 0)
(get_local 1)))
(export "addTwo" (func $addTwo)))
#!/usr/bin/node --expose-wasm
const fs = require('fs'),
assert = require('assert')
assert('WebAssembly' in global,
'WebAssembly global object not detected')
// Convert node Buffer to Uint8Array
function toUint8Array(buf) {
var u = new Uint8Array(buf.length)
for (var i = 0; i < buf.length; ++i) {
u[i] = buf[i]
}
return u
}
// Based on https://gist.github.com/kripken/59c67556dc03bb6d57052fedef1e61ab
// Loads a WebAssembly dynamic library, returns a promise.
// imports is an optional imports object
function loadWebAssembly(filename, imports) {
// Fetch the file and compile it
const buffer = toUint8Array(fs.readFileSync(filename))
return WebAssembly.compile(buffer)
.then(module => {
// Create the imports for the module, including the
// standard dynamic library imports
imports = imports || {}
imports.env = imports.env || {}
imports.env.memoryBase = imports.env.memoryBase || 0
imports.env.tableBase = imports.env.tableBase || 0
if (!imports.env.memory) {
imports.env.memory = new WebAssembly.Memory({ initial: 256 })
}
if (!imports.env.table) {
imports.env.table = new WebAssembly.Table({ initial: 0, element: 'anyfunc' })
}
// Create the instance.
return new WebAssembly.Instance(module, imports)
})
}
if (module.parent) {
module.exports.loadWebAssembly = loadWebAssembly
} else {
assert(process.argv.length >= 4,
'Usage: ./runwasm.js prog.wasm func INT_ARG...')
const wasm = process.argv[2],
func = process.argv[3],
// Convert args to either floats or ints
args = process.argv.slice(4).map(
x => x.match(/[.]/) ? parseFloat(x) : parseInt(x))
loadWebAssembly(wasm)
.then(instance => {
var exports = instance.exports
assert(exports, 'no exports found')
assert(func in exports, func + ' not found in wasm module exports')
//console.log('calling exports.'+func+'('+args+')')
console.log(exports[func](...args))
})
.catch(res => {
console.log(res)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment