From bed4959f6da8768c48cdc11dbfeb8107bb1aec6b Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Thu, 11 Aug 2022 11:31:06 +0300 Subject: [PATCH] Adds Zig example (#741) Signed-off-by: knqyf263 --- .github/workflows/examples.yaml | 3 + .gitignore | 3 + Makefile | 7 ++ examples/allocation/README.md | 5 +- examples/allocation/zig/README.md | 20 ++++ examples/allocation/zig/greet.go | 124 ++++++++++++++++++++ examples/allocation/zig/greet_test.go | 18 +++ examples/allocation/zig/testdata/build.zig | 13 ++ examples/allocation/zig/testdata/greet.wasm | Bin 0 -> 39111 bytes examples/allocation/zig/testdata/greet.zig | 65 ++++++++++ 10 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 examples/allocation/zig/README.md create mode 100644 examples/allocation/zig/greet.go create mode 100644 examples/allocation/zig/greet_test.go create mode 100644 examples/allocation/zig/testdata/build.zig create mode 100755 examples/allocation/zig/testdata/greet.wasm create mode 100644 examples/allocation/zig/testdata/greet.zig diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index 2be5c6e5..de715149 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -90,6 +90,9 @@ jobs: - name: Build Rust examples run: make build.examples.rust + - name: Build Zig examples + run: make build.examples.zig + - name: Build Emscripten examples run: | ./emsdk/emsdk activate ${{env.EMSDK_VERSION}} diff --git a/.gitignore b/.gitignore index 1b12d07f..59fdf45f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ package-lock.json /coverage.txt .vagrant + +zig-cache/ +zig-out/ diff --git a/Makefile b/Makefile index 7b1b4f6e..f4eaf134 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,13 @@ build.bench: build.examples.as: @cd ./examples/assemblyscript/testdata && npm install && npm run build +.PHONY: build.examples.zig +build.examples.zig: examples/allocation/zig/testdata/greet.wasm + +%.wasm: %.zig + @(cd $(@D); zig build) + @mv $(@D)/zig-out/lib/$(@F) $(@D) + tinygo_sources := $(wildcard examples/*/testdata/*.go examples/*/*/testdata/*.go examples/*/testdata/*/*.go) .PHONY: build.examples.tinygo build.examples.tinygo: $(tinygo_sources) diff --git a/examples/allocation/README.md b/examples/allocation/README.md index fae2ecfe..1f8059c1 100644 --- a/examples/allocation/README.md +++ b/examples/allocation/README.md @@ -14,11 +14,12 @@ for binary serialization. * [Rust](rust) - Calls Wasm built with `cargo build --release --target wasm32-unknown-unknown` * [TinyGo](tinygo) - Calls Wasm built with `tinygo build -o X.wasm -scheduler=none --no-debug -target=wasi X.go` +* [Zig](zig) - Calls Wasm built with `zig build` Note: Each of the above languages differ in both terms of exports and runtime behavior around allocation, because there is no WebAssembly specification for -it. For example, TinyGo exports allocation functions while Rust does not. Also, -Rust eagerly collects memory before returning from a Wasm function while TinyGo +it. For example, TinyGo exports allocation functions while Rust and Zig don't. +Also, Rust eagerly collects memory before returning from a Wasm function while TinyGo does not. We still try to keep the examples as close to the same as possible, and diff --git a/examples/allocation/zig/README.md b/examples/allocation/zig/README.md new file mode 100644 index 00000000..0d3f2a6c --- /dev/null +++ b/examples/allocation/zig/README.md @@ -0,0 +1,20 @@ +## Zig allocation example + +This example shows how to pass strings in and out of a Wasm function defined in Zig, built with `zig build`. + +Ex. +```bash +$ go run greet.go wazero +wasm >> Hello, wazero! +go >> Hello, wazero! +``` + +Under the covers, [greet.zig](testdata/greet.zig) does a few things of interest: +* Uses `@ptrToInt` to change a Zig pointer to a numeric type +* Uses `[*]u8` as an argument to take a pointer and slices it to build back a string + +The Zig code exports "malloc" and "free", which we use for that purpose. + +Note: This example uses `@panic()` rather than `unreachable` to handle errors +since `unreachable` emits a call to panic only in `Debug` and `ReleaseSafe` mode. +In `ReleaseFast` and `ReleaseSmall` mode, it would lead into undefined behavior. diff --git a/examples/allocation/zig/greet.go b/examples/allocation/zig/greet.go new file mode 100644 index 00000000..ac50652f --- /dev/null +++ b/examples/allocation/zig/greet.go @@ -0,0 +1,124 @@ +package main + +import ( + "context" + _ "embed" + "errors" + "fmt" + "log" + "os" + + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/api" +) + +// greetWasm was compiled using `zig build` +// +//go:embed testdata/greet.wasm +var greetWasm []byte + +// main shows how to interact with a WebAssembly function that was compiled from Zig. +// +// See README.md for a full description. +func main() { + if err := run(); err != nil { + log.Panicln(err) + } +} + +func run() error { + // Choose the context to use for function calls. + ctx := context.Background() + + // Create a new WebAssembly Runtime. + r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig(). + // Enable WebAssembly 2.0 support. + WithWasmCore2(), + ) + defer r.Close(ctx) // This closes everything this Runtime created. + + // Instantiate a Go-defined module named "env" that exports a function to + // log to the console. + _, err := r.NewModuleBuilder("env"). + ExportFunction("log", logString). + Instantiate(ctx, r) + if err != nil { + return err + } + + // Instantiate a WebAssembly module that imports the "log" function defined + // in "env" and exports "memory" and functions we'll use in this example. + compiled, err := r.CompileModule(ctx, greetWasm, wazero.NewCompileConfig()) + if err != nil { + return err + } + + mod, err := r.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithStdout(os.Stdout).WithStderr(os.Stderr)) + if err != nil { + return err + } + + // Get references to WebAssembly functions we'll use in this example. + greet := mod.ExportedFunction("greet") + greeting := mod.ExportedFunction("greeting") + + malloc := mod.ExportedFunction("malloc") + free := mod.ExportedFunction("free") + + // Let's use the argument to this main function in Wasm. + name := os.Args[1] + nameSize := uint64(len(name)) + + // Instead of an arbitrary memory offset, use Zig's allocator. Notice + // there is nothing string-specific in this allocation function. The same + // function could be used to pass binary serialized data to Wasm. + results, err := malloc.Call(ctx, nameSize) + if err != nil { + return err + } + namePtr := results[0] + if namePtr == 0 { + return errors.New("malloc failed") + } + // We have to free this pointer when finished. + defer free.Call(ctx, namePtr, nameSize) + + // The pointer is a linear memory offset, which is where we write the name. + if !mod.Memory().Write(ctx, uint32(namePtr), []byte(name)) { + return fmt.Errorf("Memory.Write(%d, %d) out of range of memory size %d", + namePtr, nameSize, mod.Memory().Size(ctx)) + } + + // Now, we can call "greet", which reads the string we wrote to memory! + _, err = greet.Call(ctx, namePtr, nameSize) + if err != nil { + return err + } + + // Finally, we get the greeting message "greet" printed. This shows how to + // read-back something allocated by Zig. + ptrSize, err := greeting.Call(ctx, namePtr, nameSize) + if err != nil { + return err + } + + greetingPtr := uint32(ptrSize[0] >> 32) + greetingSize := uint32(ptrSize[0]) + // The pointer is a linear memory offset, which is where we write the name. + if bytes, ok := mod.Memory().Read(ctx, greetingPtr, greetingSize); !ok { + return fmt.Errorf("Memory.Read(%d, %d) out of range of memory size %d", + greetingPtr, greetingSize, mod.Memory().Size(ctx)) + } else { + fmt.Println("go >>", string(bytes)) + } + + return nil +} + +func logString(ctx context.Context, m api.Module, offset, byteCount uint32) { + buf, ok := m.Memory().Read(ctx, offset, byteCount) + if !ok { + log.Panicf("Memory.Read(%d, %d) out of range", offset, byteCount) + } + fmt.Println(string(buf)) +} diff --git a/examples/allocation/zig/greet_test.go b/examples/allocation/zig/greet_test.go new file mode 100644 index 00000000..4a944c86 --- /dev/null +++ b/examples/allocation/zig/greet_test.go @@ -0,0 +1,18 @@ +package main + +import ( + "testing" + + "github.com/tetratelabs/wazero/internal/testing/maintester" + "github.com/tetratelabs/wazero/internal/testing/require" +) + +// Test_main ensures the following will work: +// +// go run greet.go wazero +func Test_main(t *testing.T) { + stdout, _ := maintester.TestMain(t, main, "greet", "wazero") + require.Equal(t, `wasm >> Hello, wazero! +go >> Hello, wazero! +`, stdout) +} diff --git a/examples/allocation/zig/testdata/build.zig b/examples/allocation/zig/testdata/build.zig new file mode 100644 index 00000000..2afa5141 --- /dev/null +++ b/examples/allocation/zig/testdata/build.zig @@ -0,0 +1,13 @@ +const std = @import("std"); +const CrossTarget = std.zig.CrossTarget; + +pub fn build(b: *std.build.Builder) void { + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const mode = b.standardReleaseOptions(); + + const lib = b.addSharedLibrary("greet", "greet.zig", .unversioned); + lib.setTarget(CrossTarget{ .cpu_arch = .wasm32, .os_tag = .freestanding }); + lib.setBuildMode(mode); + lib.install(); +} diff --git a/examples/allocation/zig/testdata/greet.wasm b/examples/allocation/zig/testdata/greet.wasm new file mode 100755 index 0000000000000000000000000000000000000000..0f5ce483084115761f59491a93092d88f3589e47 GIT binary patch literal 39111 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 literal 0 HcmV?d00001 diff --git a/examples/allocation/zig/testdata/greet.zig b/examples/allocation/zig/testdata/greet.zig new file mode 100644 index 00000000..f164037d --- /dev/null +++ b/examples/allocation/zig/testdata/greet.zig @@ -0,0 +1,65 @@ +const std = @import("std"); +const allocator = std.heap.page_allocator; + +extern "env" fn log(ptr: [*]const u8, size: u32) void; + +// _log prints a message to the console using log. +pub fn _log(message: []const u8) void { + log(message.ptr, message.len); +} + +pub export fn malloc(length: usize) ?[*]u8 { + const buff = allocator.alloc(u8, length) catch return null; + return buff.ptr; +} + +pub export fn free(buf: [*]u8, length: usize) void { + allocator.free(buf[0..length]); +} + +pub fn _greeting(name: []const u8) ![]u8 { + return try std.fmt.allocPrint( + allocator, + "Hello, {s}!", + .{name}, + ); +} + +// _greet prints a greeting to the console. +pub fn _greet(name: []const u8) !void { + const s = try std.fmt.allocPrint( + allocator, + "wasm >> {s}", + .{name}, + ); + _log(s); +} + +// greet is a WebAssembly export that accepts a string pointer (linear memory offset) and calls greet. +pub export fn greet(message: [*]const u8, size: u32) void { + const name = _greeting(message[0..size]) catch |err| @panic(switch (err) { + error.OutOfMemory => "out of memory", + else => "unexpected error", + }); + _greet(name) catch |err| @panic(switch (err) { + error.OutOfMemory => "out of memory", + else => "unexpected error", + }); +} + +// greeting is a WebAssembly export that accepts a string pointer (linear memory +// offset) and returns a pointer/size pair packed into a uint64. +// +// Note: This uses a uint64 instead of two result values for compatibility with +// WebAssembly 1.0. +pub export fn greeting(message: [*]const u8, size: u32) u64 { + const g = _greeting(message[0..size]) catch return 0; + return stringToPtr(g); +} + +// stringToPtr returns a pointer and size pair for the given string in a way +// compatible with WebAssembly numeric types. +pub fn stringToPtr(s: []const u8) u64 { + const p: u64 = @ptrToInt(s.ptr); + return p << 32 | s.len; +}