Load a WebAssembly Function Written in Rust and Invoke it from JavaScript

Nik Graf
InstructorNik Graf
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 6 years ago

In this lesson we are going to setup a project from scratch by introducing the JavaScript snippet to load a WebAssembly module. We demonstrate two different ways and showcase the benefit of the streaming solution. Once the module is loaded we can invoke a function previously exported from our Rust code.

Instructor: [00:00] Use Cargo.new to create a new project called utils. Use --lib to declare that it's going to be a library. Next, we need to change the create type to cdylib in Cargo.toml. This has an impact on how things are linked together during compilation.

[00:17] We're now ready to write our first lines of Rust code. Let's get right into it, and create a public function, addOne. The extern keyword is needed to create an interface so that this function can be invoked from other languages.

[00:32] The function accepts a value X, which is an unsigned integer, which is incremented by one and returned. In addition, we need to add a @nomangle annotation to tell the Rust compiler not to mangle the name of this function.

[00:48] Next up, we can use Cargo.build to compile our utils library, targeting WebAssembly. After that, we can run wasm.gc, and output it to utils.gc.wasm in the current directory. Next up, we need to load it somehow. Therefore, we're going to create an index.html file and open a script tag.

[01:10] To load a WebAssembly module, we can fetch it, convert the response to an array buffer, instantiate the result, and then use the WASM module. It has an instance with export, including our addOne function. We can invoke the function and append the result to the DOM.

[01:47] Let's give this a try. We start our web server running HTTP. Once we open a site in the browser, we can see the result. Awesome. Here, you can see that our addOne function printed out the result of adding two plus one.

[02:02] There is one more improvement, though. In the current implementation, we fetch the entire WASM file before we instantiate it. Using instantiate streaming instead, we can stream, compile, and instantiate a WebAssembly module in one go.

[02:17] Especially on slow connections, this can speed up the time to execution a lot. We reload and review the result. Worked like a charm. Be aware, instantiate streaming requires that our WASM file must be served through the content type, application/wasm. Fortunately, our HTTP server already does so.