WebAssembly

WebAssembly

Zig supports building for WebAssembly out of the box.

Freestanding

For host environments like the web browser and nodejs, build as a dynamic library using the freestanding OS target. Here’s an example of running Zig code compiled to WebAssembly with nodejs.

math.zig

extern fn print(i32) void;

export fn add(a: i32, b: i32) void {
    print(a + b);
}
``` ```
$ zig build-lib math.zig -target wasm32-freestanding -dynamic

test.js

const fs = require('fs');
const source = fs.readFileSync("./math.wasm");
const typedArray = new Uint8Array(source);

WebAssembly.instantiate(typedArray, {
  env: {
    print: (result) => { console.log(`The result is ${result}`); }
  }}).then(result => {
  const add = result.instance.exports.add;
  add(1, 2);
});
``` ```
$ node test.js
The result is 3

WASI

Zig’s support for WebAssembly System Interface (WASI) is under active development. Example of using the standard library and reading command line arguments:

args.zig

const std = @import("std");

pub fn main() !void {
    var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
    const gpa = &general_purpose_allocator.allocator;
    const args = try std.process.argsAlloc(gpa);
    defer std.process.argsFree(gpa, args);

    for (args) |arg, i| {
        std.debug.print("{}: {s}\n", .{ i, arg });
    }
}
``` ```
$ zig build-exe args.zig -target wasm32-wasi
``` ```
$ wasmtime args.wasm 123 hello
0: args.wasm
1: 123
2: hello

A more interesting example would be extracting the list of preopens from the runtime. This is now supported in the standard library via std.fs.wasi.PreopenList:

preopens.zig

const std = @import("std");
const PreopenList = std.fs.wasi.PreopenList;

pub fn main() !void {
    var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
    const gpa = &general_purpose_allocator.allocator;

    var preopens = PreopenList.init(gpa);
    defer preopens.deinit();

    try preopens.populate();

    for (preopens.asSlice()) |preopen, i| {
        std.debug.print("{}: {}\n", .{ i, preopen });
    }
}
``` ```
$ zig build-exe preopens.zig -target wasm32-wasi
``` ```
$ wasmtime --dir=. preopens.wasm
0: Preopen{ .fd = 3, .type = PreopenType{ .Dir = '.' } }