WebAssembly API?

I’ve been playing with Webassembly in other projects. I can get binary wasm files loaded into Observable quite easily, where I assign exported functions to a mutable,
but - especially as I am not familiar with the WebAssembly API - I wondered whether there is a better way of doing things?

https://beta.observablehq.com/@sdwfrost/webassembly-module-example

When compiling packages with Emscripten, there’s a lot of boilerplate added, such that it’s easier to load a single Javascript file e.g.

https://github.com/noamross/wassa/blob/master/inst/htmlwidgets/lib/emssa/emssa.js

So far, the tricks I’ve used to load modules don’t work here (despite defining WebAssembly = window.WebAssembly), so any tips in the more complex example would be appreciated.

1 Like

Alternatively, you can

  1. serialize the wasm binary to a base64 string
  2. create a node module wrapper which instantiates a new Buffer from the encoded string
  3. use the underlying byte buffer to instantiate a new wasm module instance using the APIs exposed via the WebAssembly global, providing module options and required memory
  4. export module APIs
  5. bundle the module using your favorite bundler
  6. load the bundle into Observable

The loaded bundle should behave as does any other imported module. If your wasm module requires environment-dependent instantiation (i.e., shared memory, etc), then step 4 will need to be amended to export the wasm module function. Once loaded into Observable, you can then instantiate a new wasm instance.

BTW: the Emscripten glue code assumes a particular file location for loading the wasm binary over network. You can recompile and modify to support your own or a custom endpoint or do something similar to what I outlined above.

You don’t need mutable for this—you just need promises. Here’s a simpler definition of add:

add = window.WebAssembly
  .instantiateStreaming(fetch("https://cdn.rawgit.com/mdn/webassembly-examples/master/understanding-text-format/add.wasm"))
  .then(object => object.instance.exports.add)

Or equivalently:

add = {
  const response = await fetch("https://cdn.rawgit.com/mdn/webassembly-examples/master/understanding-text-format/add.wasm");
  const object = await window.WebAssembly.instantiateStreaming(response);
  return object.instance.exports.add;
}