Lesson 1: Getting Started with Wasm

In this first lesson, we will cover the basics of getting started with WebAssembly. By the end of this lesson, you will be able to write a simple WebAssembly module in C or Rust, compile it to the Wasm binary format, and run it in JavaScript with Node.js.

Introduction to Wasm and its benefits

WebAssembly is a binary instruction format that allows you to run code on the web in a safe, efficient, and portable way. It is designed to be compatible with all major web browsers and provides a way for developers to write high-performance applications in languages other than JavaScript.

WebAssembly is beneficial for web development in many ways. Here are a few:

  • High performance: WebAssembly code is compiled to machine code, which means it can be executed much faster than interpreted JavaScript code.
  • Portability: WebAssembly modules can be compiled to run on any platform that supports the WebAssembly standard, including desktop and mobile devices.
  • Safety: WebAssembly runs in a sandboxed environment, which means it cannot access or modify resources outside of its allocated memory space.
  • Interoperability: WebAssembly modules can be written in any language that can compile to the WebAssembly binary format, making it easy to reuse existing code.

Setting up a development environment for Wasm

To get started with WebAssembly development, you will need a few tools. First, you will need a code editor. Visual Studio Code is a popular choice for WebAssembly development and can be downloaded for free from the official website.

Next, you will need a compiler that can generate WebAssembly code. Here are the steps to set up the development environment for C/C++ and Rust respectively:

C/C++ (Emscripten)

For C and C++, you can use Emscripten, which is a popular toolchain for compiling C and C++ to WebAssembly. Install Emscripten using unofficial packages is the easiest way to get started. Make sure the emcc command is in your PATH.

Rust

For Rust, you can use the Rust compiler (rustc) with the wasm32-unknown-unknown target. After installing Rust and Cargo by following the instructions at https://www.rust-lang.org/tools/install, add the new target by running the command: rustup target add wasm32-unknown-unknown.

Once you have a code editor and a compiler installed, you are ready to start writing WebAssembly code. In the next section, we will write a simple WebAssembly module in C or Rust.

Writing a simple Wasm module in C or Rust

Let’s write a simple add() function in C or Rust that we can compile to WebAssembly.

C (add.c)
int add(int a, int b) {
    return a + b;
}
Rust (add.rs)
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

Compiling the module to Wasm binary format

Now that we have our add() function in either C or Rust, we can compile it to the WebAssembly binary format using the appropriate compiler. Here are the commands for compiling to Wasm:

C
emcc add.c -s WASM=1 -s SIDE_MODULE=1 -O2 -o add.wasm
Rust
rustc --target wasm32-unknown-unknown -O --crate-type=cdylib add.rs

These commands will produce a minimal Wasm binary file as add.wasm that we can use in our web application or run with Node.js.

Running the module with Node.js

To run our WebAssembly module with Node.js, we can use the fs module to read the binary file and the WebAssembly global object to compile and instantiate the module. Here’s the code to load and execute our add() function:

const fs = require('fs');
 
(async () => {
    const buffer = fs.readFileSync('add.wasm');
    const module = await WebAssembly.compile(buffer);
    const instance = await WebAssembly.instantiate(module, {});
    console.log(instance.exports.add(2, 3)); // Output: 5
})();
Example result
$ node sample_add.js
5

This code reads the add.wasm file, compiles it, and then instantiates it. Finally, it calls the add() function with the parameters 2 and 3, and logs the result 5 to the console.

Wrap-up

Congratulations! You have successfully written a simple WebAssembly module, compiled it to the Wasm binary format, and executed it with Node.js. In the next lesson, we will dive deeper into the structure of WebAssembly modules and learn how to declare and export functions in WebAssembly code.

How did you find this lesson?