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

Run wast (WebAssembly) in node

This is a simple example of compiling and running the WebAssembly textual format (wast) in Node.js. This does not cover compiling from a higher level language to WebAssembly (for that you probably want Emscripten). But if all you want to do is play around directly with the wast textual format, this should get you going quickly.

Prerequisites

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

  • You need a wast to wasm compiler. There are two fairly straightfoward options: wabt (wabbit) and the official WebAssembly interpreter.

    • Option #1: wabt

      • You'll need a standard gcc toolchain to build wabt

      • Download and build a branch of wabt (binary_0xc) supporting the 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
  • Option #2: spec interpreter

    • You'll need an Ocaml compiler version 4.02 or later (ocaml-nox on Ubuntu)

    • Download and build a branch of the spec interpreter (binary-0xc) supporting the same version of WebAssembly as node 7 (version 12):

git clone https://github.com/WebAssembly/spec
cd spec/interpreter
git checkout binary-0xc
make opt 

Compile and Run Wast Code

Compile a wast to wasm (binary module):

  • Option #1: using wast2wasm from wabt:
wabt/out/gcc/Release/wast2wasm addTwo.wast -o addTwo.wasm
  • Option #2: using spec interpreter:
spec/interpreter/wasm.opt addTwo.wast -o addTwo.wasm

Run an exported function in the wasm binary module using the runasm.js script:

./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