dwyl / dwyl/learn-zig

ZigWasm : produce WASM from Zig code and run it

Open
#14 4 comments 5 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
4
Forks
1
PR merge metrics
No merged PRs in 30d

Description

WASM code can be used agnostically to the server or edge. It is memory-safe and sandboxed. It is "a computing machine".

We build a (_very_) simple WASM code with Zig and use it server-side and client-side. Recall WebAssembly only accepts numbers.

> NodeJS and the browser can use it natively.

> Elixir demands more work. The question of "long-running" external code remains unclear for me.

# Server-side

## Compile `Zig` code to `wasm`

We start with a simple function (recall that WASM accepts only numbers).

```zig
// ./src/add.zig

export fn add(n1: i32, n2: i32) i32 {
return n1 + n2;
}
```

The "build.zig" file:

> Zig doc on Build system:

```zig
// build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
const target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.os_tag = .freestanding,
});

const optimize = b.standardOptimizeOption(.{});

const lib = b.addStaticLibrary(.{
.name = "add",
.root_source_file = b.path("src/add.zig"),
.target = target,
.optimize = optimize,
});
// entry is NOT "main" thus disable
lib.entry = .disabled;
// assign dynamically the exported names
lib.rdynamic = true;

b.installArtifact(lib);
}
```

This will produce a `wasm` file in the folder "./zig-out/bin/".

```sh
zig build

ls zig-out/lib
# my-app.wasm
```

## Run the `wasm` server-side

### 1. with `NodeJS`

```js
const fs = require("fs");

const wasmBuffer = fs.readFileSync("./zig-out/bin/my-app.wasm");

WebAssembly.instantiate(wasmBuffer).then((wasmModule) => {
const three = wasmModule.instance.exports.add(1, 2)
console.log(three);
});
```

```sh
node index.js
# 3
```

### 2. with Elixir using `wasmex`

‼️‼️ You have the same problems/limitations of running long processes as with NIFs: the BEAM does not like it. [This issue describes very well the problem with plenty of references](https://github.com/extism/elixir-sdk/issues/15)

Disclaimer: so out call below works fine because the function I am calling is tiny, thus fast.

‼️ you need to have `Rust` installed ‼️

[Screenshot 2024-12-10 at 19 30 55](ZigWasmEx.hello)

```elixir
Mix.install([:wasmex])

bin = File.read!("my-app.wasm")
{:ok, pid} = Wasmex.start_link(%{binary: bin})
{:ok, res} = Wasmex.call_function(pid, "add", [1,2])
res

# 3
```

What about "long-running" tasks?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.