Using WebAssembly in Deno

To run WebAssembly in Deno, all you need is a binary to run. WebAssembly is a binary data format. This means that .wasm files are not directly human readable, and not intended to be written by hand. Instead a compiler for a language like Rust, C++, or Go emits .wasm files.

The following binary exports a main function that just returns 42 upon invocation:

  1. const wasmCode = new Uint8Array([
  2. 0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127,
  3. 3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0,
  4. 5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145,
  5. 128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97,
  6. 105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0,
  7. 65, 42, 11
  8. ]);
  9. const wasmModule = new WebAssembly.Module(wasmCode);
  10. const wasmInstance = new WebAssembly.Instance(wasmModule);
  11. const main = wasmInstance.exports.main as CallableFunction;
  12. console.log(main().toString());

As the code above shows, the following steps need to be performed in order to load WebAssembly in a JavaScript program:

  1. Fetching the binary (usually in the form of a .wasm file, though we are using a simple byte array for now)
  2. Compiling the binary into a WebAssembly.Module object
  3. Instantiating the WebAssembly module

For more complex scenarios you will probably want to write in a programming language that compiles down to WebAssembly instead of hand writing instructions. A number of languages exist that can do this, such as Rust, Go or AssemblyScript. As an example, a Rust program that compiles to the aforementioned bytes would look something like this:

  1. pub fn main() -> u32 { // u32 stands for an unsigned integer using 32 bits of memory.
  2. 42
  3. }

Aside from the methods shown in the preceding example, it is also possible to use the streaming methods of the WebAssembly API, as will be shown on the next page.