Last active
November 28, 2023 13:55
-
-
Save peterhellberg/6593423646b7c7094a02ca931d34341e to your computer and use it in GitHub Desktop.
Compiling Zig to WASI, then calling it from Go using Wazero (https://ziglang.org, https://go.dev, https://wazero.io)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
zig-cache | |
bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
export fn add(a: i64, b: i64) i64 { | |
return a + b; | |
} | |
test "add 1+2=3" { | |
try std.testing.expectEqual(add(1, 2), 3); | |
} | |
test "add 4+5=9" { | |
try std.testing.expectEqual(add(4, 5), 9); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
pub fn build(b: *std.Build) void { | |
const exe = b.addExecutable(.{ | |
.single_threaded = true, | |
.name = "add", | |
.root_source_file = .{ .path = "add.zig" }, | |
.target = .{ .cpu_arch = .wasm32, .os_tag = .wasi }, | |
.optimize = .ReleaseSmall, | |
}); | |
exe.entry = .disabled; | |
exe.export_table = true; | |
exe.export_symbol_names = &[_][]const u8{"add"}; | |
b.installArtifact(exe); | |
const unit_tests = b.addTest(.{ | |
.root_source_file = .{ .path = "add.zig" }, | |
.target = .{ .cpu_arch = .wasm32, .os_tag = .wasi }, | |
.optimize = .ReleaseSmall, | |
}); | |
const run_unit_tests = b.addRunArtifact(unit_tests); | |
const test_step = b.step("test", "Run unit tests"); | |
test_step.dependOn(&run_unit_tests.step); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module experiments/gists/go-zig-wasm-add | |
go 1.21.4 | |
require github.com/tetratelabs/wazero v1.5.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github.com/tetratelabs/wazero v1.5.0 h1:Yz3fZHivfDiZFUXnWMPUoiW7s8tC1sjdBtlJn08qYa0= | |
github.com/tetratelabs/wazero v1.5.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"flag" | |
"fmt" | |
"log" | |
"strconv" | |
_ "embed" | |
"github.com/tetratelabs/wazero" | |
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" | |
) | |
//go:generate zig build -p . --cache-dir /tmp/go-zig-wasm-add | |
// addWasm was generated by the following: | |
// | |
// go generate | |
// | |
// Run the Zig tests like this: | |
// | |
// zig build test -fwasmtime | |
// | |
//go:embed bin/add.wasm | |
var addWasm []byte | |
func main() { | |
flag.Parse() | |
ctx := context.Background() | |
r := wazero.NewRuntime(ctx) | |
defer r.Close(ctx) | |
wasi_snapshot_preview1.MustInstantiate(ctx, r) | |
mod, err := r.Instantiate(ctx, addWasm) | |
if err != nil { | |
log.Panicf("failed to instantiate module: %v", err) | |
} | |
x, y, err := readTwoArgs(flag.Arg(0), flag.Arg(1)) | |
if err != nil { | |
log.Panicf("failed to read arguments: %v", err) | |
} | |
add := mod.ExportedFunction("add") | |
results, err := add.Call(ctx, uint64(x), uint64(y)) | |
if err != nil { | |
log.Panicf("failed to call add: %v", err) | |
} | |
fmt.Printf("%d + %d = %d\n", x, y, int64(results[0])) | |
} | |
func readTwoArgs(xs, ys string) (int64, int64, error) { | |
if xs == "" || ys == "" { | |
return 0, 0, fmt.Errorf("must specify two command line arguments") | |
} | |
x, err := strconv.ParseInt(xs, 10, 64) | |
if err != nil { | |
return 0, 0, fmt.Errorf("argument X: %v", err) | |
} | |
y, err := strconv.ParseInt(ys, 10, 64) | |
if err != nil { | |
return 0, 0, fmt.Errorf("argument Y: %v", err) | |
} | |
return x, y, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment