The maintainer of this website has a Spotify Coding Playlist of their Lo-fi Hip Hop beats!

WebAssembly Logo

Wasm By Example

Language:

Passing High Level Data Types with wasm-bindgen

Overview

Using buffers and pointers, is a great way to get started with WebAssembly, and drill in its concepts while being productive. But once we start wanting to use higher level data structures efficiently and easily, is where things will get a little more complicated. Thankfully, the rust/wasm community built wasm-bindgen, which is part of the wasm-pack workflow we have been using throughout the examples. As mentioned before, wasm-bindgen abstracts away linear memory, and allows using higher-level data structures between Rust and JavaScript.

Let's kick things off! To show off how we can use wasm-bindgen, let's see how we can use strings in WebAssembly and share them with JavaScript:


Implementation

First, let's add the following to our src/lib.rs file:

// The wasm-pack uses wasm-bindgen to build and generate JavaScript binding file.
// Import the wasm-bindgen crate.
use wasm_bindgen::prelude::*;

// Our function to concatenate the string "Wasm by Example"
// to the input string. We are using .into(), to convert
// the rust types of str to a String.
#[wasm_bindgen]
pub fn add_wasm_by_example_to_string(input_string: String) -> String {
  let result = format!("{} {}", input_string, "Wasm by Example");
  return result.into();
}

Next, we can compile the module following the Hello World examples compilation process, replacing the appropriate file names.

Next, lets create an index.js file to load and run our wasm output. Now that we are using higher-level stata structures, we will have to leverage the named exports in our ./pkg/strings.js. The named exports generated by wasm-pack in our ./pkg/strings.js, are functions that wrap around our exported wasm functions to handle the data passing to facilitate passing high level data structures between WebAssembly and JavaScript. In our case, we can take a look at the supported wasm-bindgen String type. In the future, you can use this resource to see other supported types and usage as well. Let's dive into our resulting index.js:

// Here we are importing the default export from our
// Outputted wasm-bindgen ES Module. As well as importing
// the named exports that are individual wrapper functions
// to facilitate handle data passing between JS and Wasm.
import wasmInit, {
  add_wasm_by_example_to_string,
  test
} from "./pkg/strings.js";

const runWasm = async () => {
  // Instantiate our wasm module
  const rustWasm = await wasmInit("./pkg/strings_bg.wasm");

  // Call our exported function
  const helloString = add_wasm_by_example_to_string("Hello from ");

  // Log the result to the console
  console.log(helloString);
};
runWasm();

Lastly, lets load our ES6 Module, index.js Javascript file in our index.html. And you should get something similar to the demo (Source Code) below!


Demo


wasm-bindgen supports more than just strings, and has support for many different types! I'd highly reccomend taking a look at the wasm-bindgen book, and in particular, the section of the supported types by wasm-bindgen.

Feel free to fix, suggest, or contribute more examples for language features or communitty tools!