Learn WebAssembly
上QQ阅读APP看书,第一时间看更新

Loading a module and the WebAssembly namespace methods

The JavaScript API covers the various objects available on the global WebAssembly object in the browser. Before we discuss those, we'll start with the methods available on the WebAssembly object, with a brief overview of their intended purposes:

  • instantiate() is the primary API for compiling and instantiating WebAssembly code
  • instantiateStreaming() performs the same functionality as instantiate(), but it uses streaming to compile and instantiate the module, which eliminates an intermediate step
  • compile() only compiles a WebAssembly module, but doesn't instantiate it
  • compileStreaming() also only compiles a WebAssembly module, but it uses streaming similar to instantiateStreaming()
  • validate() checks the WebAssembly binary code to ensure the bytes are valid and returns true if valid or false if not valid

The instantiateStreaming() and compileStreaming() methods are currently only present in the Web API. In fact, these two methods comprise the entire specification. The methods available on the WebAssembly object are focused primarily on compiling and instantiating modules. With that in mind, let's discuss how to fetch and instantiate a Wasm module.

When you perform a fetch call to get a module, it returns a Promise that resolves with the raw bytes of that module, which need to be loaded into an ArrayBuffer and instantiated. Going forward, we will refer to this process as loading a module.

The following diagram demonstrates this process:

Fetching and loading a WebAssembly module

This process is actually quite simple using Promises. The following code demonstrates how a module is loaded. The importObj argument passes any data or functions to the Wasm module. You can disregard it for now, as we'll be discussing it in greater detail in Chapter 5, Creating and Loading a WebAssembly Module:

fetch('example.wasm')
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.instantiate(buffer, importObj))
.then(({ module, instance }) => {
// Do something with module or instance
});

The preceding example dictates the method for loading the module using the instantiate() method. The instantiateStreaming() method is a little different and simplifies the process even more by fetching, compiling, and instantiating a module in a single step. The following code achieves the same goal (loading a module) using this method:

WebAssembly.instantiateStreaming(fetch('example.wasm'), importObj)
.then(({ module, instance }) => {
// Do something with module or instance
});

The instantiation methods return a Promise that resolves with an object containing a compiled WebAssembly.Module (module) and WebAssembly.Instance (instance), both of which will be covered later in this section. In most cases, you will use one of these methods to load a Wasm module on your site. The instance contains all of the exported WebAssembly functions that you can call from your JavaScript code.

The compile() and compileStreaming() methods return a Promise that only resolves with a compiled WebAssembly.Module. This is useful if you want to compile a module and instantiate it at a later time. Mozilla Developer Network (MDN), the web docs site managed by Mozilla, provides an example in which the compiled module is passed to a Web Worker.

As far as the validate() method is concerned, its only purpose is to test whether the typed array or ArrayBuffer passed in as a parameter is valid. This would be called after the raw bytes of the response are loaded into an ArrayBuffer. This method wasn't included in the code examples because attempting to instantiate or compile an invalid Wasm module will throw either a TypeError or one of the Error objects present on the WebAssembly object. We will cover these Error objects later in this section.