Welcome to the first post in a series discussing post-MVP features coming to WebAssembly via the proposals process. There are some exciting things coming up and today we'll be looking at the ECMAScript Module Integration of WebAssembly Modules.
The proposal (Phase 2) adds support for importing and loading WebAssembly Modules declaratively with the familiar JavaScript import
statement or the <script type="module">
tag.
Currently WebAssembly Modules must be loaded via one of four methods:
const source = fetch('add.wasm');
// 1. Should be used only if the module needs to be
// compiled before instantiating.
// Returns a Promise<WebAssembly.Module>.
source
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.compile(bytes))
// 2. Otherwise just use this.
// Returns a Promise<ResultObject>.
source
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
// The previous two are nice and all but newer variants which
// begin compilation while the binary is still busy downloading
// are AWESOME and more efficient! โญ
// 5. Returns a Promise<WebAssembly.Module>.
WebAssembly.compileStreaming(source)
// 4. Returns a Promise<ResultObject>.
WebAssembly.instantiateStreaming(source)
The ResultObject
contains the compiled WebAssembly module
property for convenience which can be instantiated again or passed around, but also the instance
property. We can access any of the functions exported by the WebAssembly module via the instance.exports
object.
For example, let's say that the add
function was exported from add.wasm
above. We'd invoke it from the result object, say obj
, with obj.instance.exports.add(2, 3)
. But with the ES Modules Integration proposal, things would become far less cumbersome:
import { add } from './add.wasm';
console.log(add(2, 3));
Short and sweet.
Next time we'll be looking at the WebAssembly Threads proposal with new atomic memory instructions for safely accessing memory from multiple threads.
Comments