├── .gitignore ├── LICENSE ├── README.md ├── build.zig ├── build.zig.zon ├── examples ├── assets │ └── qjs.wasm ├── imports-exports.zig ├── instance.zig ├── memory.zig ├── memory2.zig └── wasi.zig ├── reference ├── wasm.h └── wasmer.h └── src ├── wasi.zig ├── wasm.zig └── wasmer.zig /.gitignore: -------------------------------------------------------------------------------- 1 | /.zig-cache 2 | /zig-cache 3 | /zig-out 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Andrey | Afirium 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wasmer-zig-api 2 | 3 | Zig bindings for the [Wasmer](https://github.com/wasmerio/wasmer/tree/main/lib/c-api) WebAssembly runtime. 4 | 5 | This module is based on the zigwasm/wasmer-zig fork. The old API does not work with newer versions of zig, and the main goal of this project is to continue to support the module for newer versions of zig. 6 | 7 | All WASI APIs are also implemented. 8 | 9 | All tests from the "wasmer" lib C repository are also reimplemented on zig. You can learn more about the API of this module through rich examples. 10 | 11 | The current module works with Zig 0.14.0+. 12 | 13 | ## Wasmer C API test examples [WIP] 14 | 15 | - [ ] early-exit.c 16 | - [ ] exports-function.c 17 | - [ ] exports-global.c 18 | - [ ] features.c 19 | - [x] imports-exports.c 20 | - [x] instance.c 21 | - [x] memory.c 22 | - [x] memory2.c 23 | - [x] wasi.c 24 | 25 | ## Running tests and examples 26 | 27 | The `WASMER_DIR` environment variable is used to determine the presence and location of the Wasmer library. Ensure this variable is set correctly to avoid issues with library detection. 28 | 29 | - Run library unit tests: 30 | ```bash 31 | zig build test 32 | ``` 33 | 34 | - Build and run examples: 35 | ```bash 36 | zig build run -Dexamples=true 37 | ``` 38 | 39 | ## Using it 40 | 41 | In your zig project folder (where build.zig is located), run: 42 | 43 | ```bash 44 | zig fetch --save "git+https://github.com/Afirium/wasmer-zig-api#v0.3.0" 45 | ``` 46 | 47 | Then, in your `build.zig`'s `build` function, add the following before 48 | `b.installArtifact(exe)`: 49 | 50 | ```zig 51 | const wasmerZigAPI= b.dependency("wasmer_zig_api", .{ 52 | .target = target, 53 | .optimize = optimize, 54 | }); 55 | exe.root_module.addImport("wasmer", wasmerZigAPI.module("wasmer")); 56 | exe.linkLibC(); 57 | exe.addLibraryPath(.{ .cwd_relative = "/home/path_to_your_wasmer/.wasmer/lib" }); 58 | exe.linkSystemLibrary("wasmer"); 59 | ``` 60 | 61 | ## Status 62 | 63 | | Refname | Wasmer runtime version | Zig `0.12.x` | Zig `0.13.x` | Zig `0.14.x` | Zig `0.15.0-dev` | 64 | |:----------|:-----------------------|:------------:|:------------:|:------------:|:----------------:| 65 | | `v0.3.0` | `v4.0.0+`, `v5.0.0+` | ❌ | ❌ | ✅ | ✅ | 66 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.Build) !void { 4 | const target = b.standardTargetOptions(.{}); 5 | const optimize = b.standardOptimizeOption(.{}); 6 | const wasmer_dir_path = try std.process.getEnvVarOwned(b.allocator, "WASMER_DIR"); 7 | const wasmer_lib_dir_path = b.pathJoin(&.{ wasmer_dir_path, "lib" }); 8 | 9 | const build_examples_option = b.option(bool, "examples", "Build example files") orelse false; 10 | 11 | const run_step = b.step("run", "Run the app"); 12 | 13 | const wasmer_module = b.addModule("wasmer", .{ 14 | .root_source_file = b.path("src/wasmer.zig"), 15 | .target = target, 16 | .optimize = optimize, 17 | }); 18 | const wasmer_lib = b.addStaticLibrary(.{ 19 | .name = "wasmer", 20 | .root_source_file = b.path("src/wasmer.zig"), 21 | .target = target, 22 | .optimize = optimize, 23 | }); 24 | 25 | if (build_examples_option) { 26 | var examples_dir = try std.fs.cwd().openDir("examples", .{ .iterate = true }); 27 | defer examples_dir.close(); 28 | 29 | var examples_dir_iter = examples_dir.iterate(); 30 | 31 | while (try examples_dir_iter.next()) |entry| { 32 | if (entry.kind == .file and std.mem.endsWith(u8, entry.name, ".zig")) { 33 | var buffer_exe_path = std.ArrayList(u8).init(b.allocator); 34 | const exe_name = entry.name[0 .. entry.name.len - 4]; 35 | 36 | try buffer_exe_path.appendSlice("examples/"); 37 | try buffer_exe_path.appendSlice(entry.name); 38 | 39 | const exe_path = try buffer_exe_path.toOwnedSlice(); 40 | 41 | const example_exe = b.addExecutable(.{ 42 | .name = exe_name, 43 | .root_source_file = b.path(exe_path), 44 | .target = target, 45 | .optimize = optimize, 46 | .link_libc = true, 47 | }); 48 | 49 | example_exe.root_module.addImport("wasmer", wasmer_module); 50 | example_exe.root_module.addLibraryPath(.{ .cwd_relative = wasmer_lib_dir_path }); 51 | example_exe.root_module.linkSystemLibrary("wasmer", .{}); 52 | 53 | b.installArtifact(example_exe); 54 | const run_example_cmd = b.addRunArtifact(example_exe); 55 | run_example_cmd.step.dependOn(b.getInstallStep()); 56 | 57 | run_step.dependOn(&run_example_cmd.step); 58 | } 59 | } 60 | } 61 | 62 | // Creates a step for unit testing. This only builds the test executable 63 | // but does not run it. 64 | const wasmer_unit_tests = b.addTest(.{ 65 | .root_source_file = b.path("src/wasmer.zig"), 66 | .target = target, 67 | .optimize = optimize, 68 | }); 69 | 70 | wasmer_unit_tests.linkLibC(); 71 | wasmer_unit_tests.addLibraryPath(.{ .cwd_relative = wasmer_lib_dir_path }); 72 | wasmer_unit_tests.linkSystemLibrary("wasmer"); 73 | 74 | const run_wasmer_unit_tests = b.addRunArtifact(wasmer_unit_tests); 75 | 76 | // Similar to creating the run step earlier, this exposes a `test` step to 77 | // the `zig build --help` menu, providing a way for the user to request 78 | // running the unit tests. 79 | const test_step = b.step("test", "Run unit tests"); 80 | test_step.dependOn(&run_wasmer_unit_tests.step); 81 | 82 | // Build docs 83 | const docs_step = b.step("docs", "Emit docs"); 84 | const docs = b.addInstallDirectory(.{ 85 | .source_dir = wasmer_lib.getEmittedDocs(), 86 | .install_dir = .prefix, 87 | .install_subdir = "docs", 88 | }); 89 | docs_step.dependOn(&docs.step); 90 | } 91 | -------------------------------------------------------------------------------- /build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .fingerprint = 0xadae4aecca466a13, 3 | .name = .wasmer_zig_api, 4 | .version = "0.3.0", 5 | .minimum_zig_version = "0.14.0", 6 | .paths = .{ 7 | "build.zig", 8 | "build.zig.zon", 9 | "src", 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /examples/assets/qjs.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zig-wasm/wasmer-zig-api/542fc841bd457dc022d00c185f46fcd1299e30cf/examples/assets/qjs.wasm -------------------------------------------------------------------------------- /examples/imports-exports.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const wasmer = @import("wasmer"); 3 | const assert = std.debug.assert; 4 | 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const allocator = gpa.allocator(); 7 | 8 | const wat = 9 | \\(module 10 | \\ (func $host_function (import "" "host_function")) 11 | \\ ;; (global $host_global (import "env" "host_global") i32) 12 | \\ (func $function (export "guest_function") (result i32) (global.get $global)) 13 | \\ (global $global (export "guest_global") i32 (i32.const 42)) 14 | \\ (table $table (export "guest_table") 1 1 funcref) 15 | \\ (memory $memory (export "guest_memory") 1) 16 | \\) 17 | ; 18 | 19 | fn host_func_callback() void { 20 | std.log.info("Calling back...\n> ", .{}); 21 | } 22 | 23 | pub fn main() !void { 24 | run() catch |err| { 25 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 26 | defer std.heap.c_allocator.free(err_msg); 27 | 28 | std.log.err("{s}", .{err_msg}); 29 | 30 | return err; 31 | }; 32 | } 33 | 34 | pub fn run() !void { 35 | var wasm_bytes = try wasmer.watToWasm(wat); 36 | defer wasm_bytes.deinit(); 37 | 38 | std.log.info("creating the store...", .{}); 39 | 40 | const engine = try wasmer.Engine.init(); 41 | defer engine.deinit(); 42 | const store = try wasmer.Store.init(engine); 43 | defer store.deinit(); 44 | 45 | std.log.info("compiling module...", .{}); 46 | 47 | const module = try wasmer.Module.init(store, wasm_bytes.toSlice()); 48 | defer module.deinit(); 49 | 50 | std.log.info("creating the imported function...", .{}); 51 | 52 | const host_func = try wasmer.Func.init(store, host_func_callback); 53 | // defer host_func.deinit(); 54 | 55 | // std.log.info("Creating the imported global...", .{}); 56 | 57 | std.log.info("instantiating module...", .{}); 58 | 59 | const instance = try wasmer.Instance.init(store, module, &.{host_func}); 60 | defer instance.deinit(); 61 | 62 | std.log.info("retrieving exports...", .{}); 63 | 64 | const guest_function = instance.getExportFunc(module, "guest_function") orelse { 65 | std.log.err("failed to retrieve \"guest_function\" export from instance", .{}); 66 | return error.ExportNotFound; 67 | }; 68 | defer guest_function.deinit(); 69 | 70 | const memory = instance.getExportMem(module, "guest_memory") orelse { 71 | std.log.err("failed to retrieve \"guest_memory\" export from instance", .{}); 72 | return error.ExportNotFound; 73 | }; 74 | defer memory.deinit(); 75 | } 76 | -------------------------------------------------------------------------------- /examples/instance.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const wasmer = @import("wasmer"); 3 | const assert = std.debug.assert; 4 | 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const allocator = gpa.allocator(); 7 | 8 | const wat = 9 | \\(module 10 | \\ (type $add_one_t (func (param i32) (result i32))) 11 | \\ (func $add_one_f (type $add_one_t) (param $value i32) (result i32) 12 | \\ local.get $value 13 | \\ i32.const 1 14 | \\ i32.add) 15 | \\ (export "add_one" (func $add_one_f))) 16 | ; 17 | 18 | pub fn main() !void { 19 | run() catch |err| { 20 | // const err_msg = try wasmer.lastError(std.heap.c_allocator); 21 | // defer std.heap.c_allocator.free(err_msg); 22 | 23 | // std.log.err("{s}", .{err_msg}); 24 | 25 | return err; 26 | }; 27 | } 28 | 29 | fn run() !void { 30 | var wasm_bytes = try wasmer.watToWasm(wat); 31 | defer wasm_bytes.deinit(); 32 | 33 | std.log.info("creating the store...", .{}); 34 | 35 | const engine = try wasmer.Engine.init(); 36 | defer engine.deinit(); 37 | const store = try wasmer.Store.init(engine); 38 | defer store.deinit(); 39 | 40 | std.log.info("compiling module...", .{}); 41 | 42 | const module = try wasmer.Module.init(store, wasm_bytes.toSlice()); 43 | 44 | defer module.deinit(); 45 | 46 | std.log.info("instantiating module...", .{}); 47 | 48 | const instance = try wasmer.Instance.init(store, module, &.{}); 49 | defer instance.deinit(); 50 | 51 | std.log.info("retrieving exports...", .{}); 52 | 53 | const add_one = instance.getExportFunc(module, "add_one") orelse { 54 | std.log.err("failed to retrieve \"add_one\" export from instance", .{}); 55 | return error.ExportNotFound; 56 | }; 57 | defer add_one.deinit(); 58 | 59 | std.log.info("calling \"add_one\" export fn...", .{}); 60 | 61 | const res = try add_one.call(i32, .{@as(i32, 1)}); 62 | assert(res == 2); 63 | 64 | std.log.info("result of \"add_one(1)\" = {}", .{res}); 65 | } 66 | -------------------------------------------------------------------------------- /examples/memory.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const wasmer = @import("wasmer"); 3 | const assert = std.debug.assert; 4 | 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const allocator = gpa.allocator(); 7 | 8 | const wat = 9 | \\(module 10 | \\ (type $mem_size_t (func (result i32))) 11 | \\ (type $get_at_t (func (param i32) (result i32))) 12 | \\ (type $set_at_t (func (param i32) (param i32))) 13 | \\ (memory $mem 1) 14 | \\ (func $get_at (type $get_at_t) (param $idx i32) (result i32) 15 | \\ (i32.load (local.get $idx))) 16 | \\ (func $set_at (type $set_at_t) (param $idx i32) (param $val i32) 17 | \\ (i32.store (local.get $idx) (local.get $val))) 18 | \\ (func $mem_size (type $mem_size_t) (result i32) 19 | \\ (memory.size)) 20 | \\ (export "get_at" (func $get_at)) 21 | \\ (export "set_at" (func $set_at)) 22 | \\ (export "mem_size" (func $mem_size)) 23 | \\ (export "memory" (memory $mem))) 24 | ; 25 | 26 | pub fn main() !void { 27 | run() catch |err| { 28 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 29 | defer std.heap.c_allocator.free(err_msg); 30 | 31 | std.log.err("{s}", .{err_msg}); 32 | 33 | return err; 34 | }; 35 | } 36 | 37 | pub fn run() !void { 38 | var wasm_bytes = try wasmer.watToWasm(wat); 39 | defer wasm_bytes.deinit(); 40 | 41 | std.log.info("creating the store...", .{}); 42 | 43 | const engine = try wasmer.Engine.init(); 44 | defer engine.deinit(); 45 | const store = try wasmer.Store.init(engine); 46 | defer store.deinit(); 47 | 48 | std.log.info("compiling module...", .{}); 49 | 50 | const module = try wasmer.Module.init(store, wasm_bytes.toSlice()); 51 | defer module.deinit(); 52 | 53 | std.log.info("instantiating module...", .{}); 54 | 55 | const instance = try wasmer.Instance.init(store, module, &.{}); 56 | defer instance.deinit(); 57 | 58 | std.log.info("retrieving exports...", .{}); 59 | 60 | const get_at = instance.getExportFunc(module, "get_at") orelse { 61 | std.log.err("failed to retrieve \"get_at\" export from instance", .{}); 62 | return error.ExportNotFound; 63 | }; 64 | defer get_at.deinit(); 65 | const set_at = instance.getExportFunc(module, "set_at") orelse { 66 | std.log.err("failed to retrieve \"set_at\" export from instance", .{}); 67 | return error.ExportNotFound; 68 | }; 69 | defer set_at.deinit(); 70 | const mem_size = instance.getExportFunc(module, "mem_size") orelse { 71 | std.log.err("failed to retrieve \"mem_size\" export from instance", .{}); 72 | return error.ExportNotFound; 73 | }; 74 | defer mem_size.deinit(); 75 | 76 | const memory = instance.getExportMem(module, "memory") orelse { 77 | std.log.err("failed to retrieve \"memory\" export from instance", .{}); 78 | return error.ExportNotFound; 79 | }; 80 | defer memory.deinit(); 81 | 82 | memory.grow(2) catch |err| { 83 | std.log.err("Error growing memory!", .{}); 84 | return err; 85 | }; 86 | 87 | const new_pages = memory.pages(); 88 | const new_size = memory.size(); 89 | std.log.info("New memory size (byted)/(pages): {d}/{d}", .{ new_size, new_pages }); 90 | 91 | const mem_addr: i32 = 0x2220; 92 | const val: i32 = 0xFEFEFFE; 93 | 94 | set_at.call(void, .{ mem_addr, val }) catch |err| { 95 | std.log.err("Failed to call \"set_at\": {any}", .{err}); 96 | return err; 97 | }; 98 | 99 | const result = get_at.call(i32, .{mem_addr}) catch |err| { 100 | std.log.err("Failed to call \"get_at\": {any}", .{err}); 101 | return err; 102 | }; 103 | 104 | std.log.info("Value at 0x{x:0>4}: {d}", .{ mem_addr, result }); 105 | } 106 | -------------------------------------------------------------------------------- /examples/memory2.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const wasmer = @import("wasmer"); 3 | const assert = std.debug.assert; 4 | 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const allocator = gpa.allocator(); 7 | 8 | pub fn main() !void { 9 | std.log.info("Initializing...", .{}); 10 | 11 | const engine = try wasmer.Engine.init(); 12 | defer engine.deinit(); 13 | const store = try wasmer.Store.init(engine); 14 | defer store.deinit(); 15 | 16 | const memory_type_1 = try wasmer.MemoryType.init(.{ .min = 0, .max = 0x7FFFFFFF }); 17 | defer memory_type_1.deinit(); 18 | _ = wasmer.Memory.init(store, memory_type_1) catch { 19 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 20 | defer std.heap.c_allocator.free(err_msg); 21 | 22 | std.log.err("{s}", .{err_msg}); 23 | }; 24 | 25 | const memory_type_2 = try wasmer.MemoryType.init(.{ .min = 15, .max = 25 }); 26 | defer memory_type_2.deinit(); 27 | const memory_2 = try wasmer.Memory.init(store, memory_type_2); 28 | defer memory_2.deinit(); 29 | 30 | const memory_type_3 = try wasmer.MemoryType.init(.{ .min = 15, .max = 0xFFFFFFFF }); 31 | defer memory_type_3.deinit(); 32 | const memory_3 = try wasmer.Memory.init(store, memory_type_3); 33 | defer memory_3.deinit(); 34 | 35 | std.log.info("Memory size: {any}", .{memory_3.size()}); 36 | 37 | // Error: the minimum requested memory is greater than the maximum allowed memory 38 | const memory_type_4 = try wasmer.MemoryType.init(.{ .min = 0x7FFFFFFF, .max = 0x7FFFFFFF }); 39 | defer memory_type_4.deinit(); 40 | _ = wasmer.Memory.init(store, memory_type_4) catch { 41 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 42 | defer std.heap.c_allocator.free(err_msg); 43 | 44 | std.log.err("{s}", .{err_msg}); 45 | }; 46 | 47 | // Error: the minimum requested memory is greater than the maximum allowed memory 48 | const memory_type_5 = try wasmer.MemoryType.init(.{ .min = 0x7FFFFFFF, .max = 0x0FFFFFFF }); 49 | defer memory_type_5.deinit(); 50 | _ = wasmer.Memory.init(store, memory_type_5) catch { 51 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 52 | defer std.heap.c_allocator.free(err_msg); 53 | 54 | std.log.err("{s}", .{err_msg}); 55 | }; 56 | 57 | // Error: the memory is invalid because the maximum is less than the minium 58 | const memory_type_6 = try wasmer.MemoryType.init(.{ .min = 15, .max = 10 }); 59 | defer memory_type_6.deinit(); 60 | _ = wasmer.Memory.init(store, memory_type_6) catch { 61 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 62 | defer std.heap.c_allocator.free(err_msg); 63 | 64 | std.log.err("{s}", .{err_msg}); 65 | }; 66 | 67 | // Error: the minimum requested memory is greater than the maximum allowed memory 68 | const memory_type_7 = try wasmer.MemoryType.init(.{ .min = 0x7FFFFFFF, .max = 10 }); 69 | defer memory_type_7.deinit(); 70 | _ = wasmer.Memory.init(store, memory_type_7) catch { 71 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 72 | defer std.heap.c_allocator.free(err_msg); 73 | 74 | std.log.err("{s}", .{err_msg}); 75 | }; 76 | 77 | std.log.info("Done.", .{}); 78 | } 79 | -------------------------------------------------------------------------------- /examples/wasi.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const wasmer = @import("wasmer"); 3 | const assert = std.debug.assert; 4 | 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const allocator = gpa.allocator(); 7 | 8 | const wat = 9 | \\(module 10 | \\ (type $mem_size_t (func (result i32))) 11 | \\ (type $get_at_t (func (param i32) (result i32))) 12 | \\ (type $set_at_t (func (param i32) (param i32))) 13 | \\ (memory $mem 1) 14 | \\ (func $get_at (type $get_at_t) (param $idx i32) (result i32) 15 | \\ (i32.load (local.get $idx))) 16 | \\ (func $set_at (type $set_at_t) (param $idx i32) (param $val i32) 17 | \\ (i32.store (local.get $idx) (local.get $val))) 18 | \\ (func $mem_size (type $mem_size_t) (result i32) 19 | \\ (memory.size)) 20 | \\ (export "get_at" (func $get_at)) 21 | \\ (export "set_at" (func $set_at)) 22 | \\ (export "mem_size" (func $mem_size)) 23 | \\ (export "memory" (memory $mem))) 24 | ; 25 | 26 | pub fn main() !void { 27 | run() catch |err| { 28 | const err_msg = try wasmer.lastError(std.heap.c_allocator); 29 | defer std.heap.c_allocator.free(err_msg); 30 | 31 | std.log.err("{s}", .{err_msg}); 32 | 33 | return err; 34 | }; 35 | } 36 | 37 | pub fn run() !void { 38 | std.log.info("creating the store...", .{}); 39 | 40 | const engine = try wasmer.Engine.init(); 41 | defer engine.deinit(); 42 | const store = try wasmer.Store.init(engine); 43 | defer store.deinit(); 44 | 45 | std.log.info("setting up WASI...", .{}); 46 | 47 | const wasi_config = try wasmer.WasiConfig.init(); 48 | 49 | const js_string = 50 | \\function greet(name) { 51 | \\ return JSON.stringify('Hello, ' + name); 52 | \\}; 53 | \\ 54 | \\print(greet('World')); 55 | ; 56 | 57 | wasi_config.setArg("--eval"); 58 | wasi_config.setArg(js_string); 59 | 60 | std.log.info("loading binary...", .{}); 61 | 62 | const file_content = @embedFile("assets/qjs.wasm"); 63 | 64 | var binary = wasmer.ByteVec.fromSlice(file_content); 65 | defer binary.deinit(); 66 | 67 | std.log.info("compiling module...", .{}); 68 | 69 | const module = try wasmer.Module.init(store, binary.toSlice()); 70 | defer module.deinit(); 71 | 72 | const wasi_env = try wasmer.WasiEnv.init(store, wasi_config); 73 | defer wasi_env.deinit(); 74 | 75 | std.log.info("instantiating module...", .{}); 76 | 77 | var imports = try wasmer.getImports(store, wasi_env, module); 78 | imports = try wasmer.getImports(store, wasi_env, module); 79 | defer imports.deinit(); 80 | 81 | const instance = try wasmer.Instance.initFromImports(store, module, &imports); 82 | defer instance.deinit(); 83 | 84 | try wasi_env.initializeInstance(store, instance); 85 | 86 | std.log.info("extracting exports...", .{}); 87 | 88 | const run_func = try wasmer.getStartFunction(instance); 89 | defer run_func.deinit(); 90 | 91 | std.log.info("calling export...", .{}); 92 | 93 | run_func.call(void, .{}) catch |err| { 94 | std.log.err("Failed to call \"run_func\": {any}", .{err}); 95 | return err; 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /reference/wasm.h: -------------------------------------------------------------------------------- 1 | // WebAssembly C API 2 | 3 | #ifndef WASM_H 4 | #define WASM_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #ifndef WASM_API_EXTERN 13 | #if defined(_WIN32) && !defined(__MINGW32__) && !defined(LIBWASM_STATIC) 14 | #define WASM_API_EXTERN __declspec(dllimport) 15 | #else 16 | #define WASM_API_EXTERN 17 | #endif 18 | #endif 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | // Auxiliaries 26 | 27 | // Machine types 28 | 29 | inline void assertions() { 30 | static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type"); 31 | static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type"); 32 | static_assert(sizeof(intptr_t) == sizeof(uint32_t) || 33 | sizeof(intptr_t) == sizeof(uint64_t), 34 | "incompatible pointer type"); 35 | } 36 | 37 | typedef char byte_t; 38 | typedef float float32_t; 39 | typedef double float64_t; 40 | 41 | 42 | // Ownership 43 | 44 | #define own 45 | 46 | // The qualifier `own` is used to indicate ownership of data in this API. 47 | // It is intended to be interpreted similar to a `const` qualifier: 48 | // 49 | // - `own wasm_xxx_t*` owns the pointed-to data 50 | // - `own wasm_xxx_t` distributes to all fields of a struct or union `xxx` 51 | // - `own wasm_xxx_vec_t` owns the vector as well as its elements(!) 52 | // - an `own` function parameter passes ownership from caller to callee 53 | // - an `own` function result passes ownership from callee to caller 54 | // - an exception are `own` pointer parameters named `out`, which are copy-back 55 | // output parameters passing back ownership from callee to caller 56 | // 57 | // Own data is created by `wasm_xxx_new` functions and some others. 58 | // It must be released with the corresponding `wasm_xxx_delete` function. 59 | // 60 | // Deleting a reference does not necessarily delete the underlying object, 61 | // it merely indicates that this owner no longer uses it. 62 | // 63 | // For vectors, `const wasm_xxx_vec_t` is used informally to indicate that 64 | // neither the vector nor its elements should be modified. 65 | // TODO: introduce proper `wasm_xxx_const_vec_t`? 66 | 67 | 68 | #define WASM_DECLARE_OWN(name) \ 69 | typedef struct wasm_##name##_t wasm_##name##_t; \ 70 | \ 71 | WASM_API_EXTERN void wasm_##name##_delete(own wasm_##name##_t*); 72 | 73 | 74 | // Vectors 75 | 76 | #define WASM_DECLARE_VEC(name, ptr_or_none) \ 77 | typedef struct wasm_##name##_vec_t { \ 78 | size_t size; \ 79 | wasm_##name##_t ptr_or_none* data; \ 80 | } wasm_##name##_vec_t; \ 81 | \ 82 | WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \ 83 | WASM_API_EXTERN void wasm_##name##_vec_new_uninitialized( \ 84 | own wasm_##name##_vec_t* out, size_t); \ 85 | WASM_API_EXTERN void wasm_##name##_vec_new( \ 86 | own wasm_##name##_vec_t* out, \ 87 | size_t, own wasm_##name##_t ptr_or_none const[]); \ 88 | WASM_API_EXTERN void wasm_##name##_vec_copy( \ 89 | own wasm_##name##_vec_t* out, const wasm_##name##_vec_t*); \ 90 | WASM_API_EXTERN void wasm_##name##_vec_delete(own wasm_##name##_vec_t*); 91 | 92 | 93 | // Byte vectors 94 | 95 | typedef byte_t wasm_byte_t; 96 | WASM_DECLARE_VEC(byte, ) 97 | 98 | typedef wasm_byte_vec_t wasm_name_t; 99 | 100 | #define wasm_name wasm_byte_vec 101 | #define wasm_name_new wasm_byte_vec_new 102 | #define wasm_name_new_empty wasm_byte_vec_new_empty 103 | #define wasm_name_new_new_uninitialized wasm_byte_vec_new_uninitialized 104 | #define wasm_name_copy wasm_byte_vec_copy 105 | #define wasm_name_delete wasm_byte_vec_delete 106 | 107 | static inline void wasm_name_new_from_string( 108 | own wasm_name_t* out, own const char* s 109 | ) { 110 | wasm_name_new(out, strlen(s), s); 111 | } 112 | 113 | static inline void wasm_name_new_from_string_nt( 114 | own wasm_name_t* out, own const char* s 115 | ) { 116 | wasm_name_new(out, strlen(s) + 1, s); 117 | } 118 | 119 | 120 | /////////////////////////////////////////////////////////////////////////////// 121 | // Runtime Environment 122 | 123 | // Configuration 124 | 125 | WASM_DECLARE_OWN(config) 126 | 127 | WASM_API_EXTERN own wasm_config_t* wasm_config_new(); 128 | 129 | // Embedders may provide custom functions for manipulating configs. 130 | 131 | 132 | // Engine 133 | 134 | WASM_DECLARE_OWN(engine) 135 | 136 | // During testing, we use a custom implementation of wasm_engine_new 137 | #if defined(TEST_WASM) || defined(TEST_WASMER) 138 | wasm_engine_t* wasm_engine_new(); 139 | #else 140 | WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(); 141 | #endif 142 | WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*); 143 | 144 | 145 | // Store 146 | 147 | WASM_DECLARE_OWN(store) 148 | 149 | WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*); 150 | 151 | /////////////////////////////////////////////////////////////////////////////// 152 | // Type Representations 153 | 154 | // Type attributes 155 | 156 | typedef uint8_t wasm_mutability_t; 157 | enum wasm_mutability_enum { 158 | WASM_CONST, 159 | WASM_VAR, 160 | }; 161 | 162 | typedef struct wasm_limits_t { 163 | uint32_t min; 164 | uint32_t max; 165 | } wasm_limits_t; 166 | 167 | static const uint32_t wasm_limits_max_default = 0xffffffff; 168 | 169 | 170 | // Generic 171 | 172 | #define WASM_DECLARE_TYPE(name) \ 173 | WASM_DECLARE_OWN(name) \ 174 | WASM_DECLARE_VEC(name, *) \ 175 | \ 176 | WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t*); 177 | 178 | 179 | // Value Types 180 | 181 | WASM_DECLARE_TYPE(valtype) 182 | 183 | typedef uint8_t wasm_valkind_t; 184 | enum wasm_valkind_enum { 185 | WASM_I32, 186 | WASM_I64, 187 | WASM_F32, 188 | WASM_F64, 189 | WASM_ANYREF = 128, 190 | WASM_FUNCREF, 191 | }; 192 | 193 | WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t); 194 | 195 | WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*); 196 | 197 | static inline bool wasm_valkind_is_num(wasm_valkind_t k) { 198 | return k < WASM_ANYREF; 199 | } 200 | static inline bool wasm_valkind_is_ref(wasm_valkind_t k) { 201 | return k >= WASM_ANYREF; 202 | } 203 | 204 | static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) { 205 | return wasm_valkind_is_num(wasm_valtype_kind(t)); 206 | } 207 | static inline bool wasm_valtype_is_ref(const wasm_valtype_t* t) { 208 | return wasm_valkind_is_ref(wasm_valtype_kind(t)); 209 | } 210 | 211 | 212 | // Function Types 213 | 214 | WASM_DECLARE_TYPE(functype) 215 | 216 | WASM_API_EXTERN own wasm_functype_t* wasm_functype_new( 217 | own wasm_valtype_vec_t* params, own wasm_valtype_vec_t* results); 218 | 219 | WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*); 220 | WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*); 221 | 222 | 223 | // Global Types 224 | 225 | WASM_DECLARE_TYPE(globaltype) 226 | 227 | WASM_API_EXTERN own wasm_globaltype_t* wasm_globaltype_new( 228 | own wasm_valtype_t*, wasm_mutability_t); 229 | 230 | WASM_API_EXTERN const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t*); 231 | WASM_API_EXTERN wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t*); 232 | 233 | 234 | // Table Types 235 | 236 | WASM_DECLARE_TYPE(tabletype) 237 | 238 | WASM_API_EXTERN own wasm_tabletype_t* wasm_tabletype_new( 239 | own wasm_valtype_t*, const wasm_limits_t*); 240 | 241 | WASM_API_EXTERN const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t*); 242 | WASM_API_EXTERN const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t*); 243 | 244 | 245 | // Memory Types 246 | 247 | WASM_DECLARE_TYPE(memorytype) 248 | 249 | WASM_API_EXTERN own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*); 250 | 251 | WASM_API_EXTERN const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*); 252 | 253 | 254 | // Extern Types 255 | 256 | WASM_DECLARE_TYPE(externtype) 257 | 258 | typedef uint8_t wasm_externkind_t; 259 | enum wasm_externkind_enum { 260 | WASM_EXTERN_FUNC, 261 | WASM_EXTERN_GLOBAL, 262 | WASM_EXTERN_TABLE, 263 | WASM_EXTERN_MEMORY, 264 | }; 265 | 266 | WASM_API_EXTERN wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*); 267 | 268 | WASM_API_EXTERN wasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t*); 269 | WASM_API_EXTERN wasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t*); 270 | WASM_API_EXTERN wasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t*); 271 | WASM_API_EXTERN wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t*); 272 | 273 | WASM_API_EXTERN wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*); 274 | WASM_API_EXTERN wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*); 275 | WASM_API_EXTERN wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*); 276 | WASM_API_EXTERN wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*); 277 | 278 | WASM_API_EXTERN const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*); 279 | WASM_API_EXTERN const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*); 280 | WASM_API_EXTERN const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*); 281 | WASM_API_EXTERN const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*); 282 | 283 | WASM_API_EXTERN const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*); 284 | WASM_API_EXTERN const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*); 285 | WASM_API_EXTERN const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*); 286 | WASM_API_EXTERN const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*); 287 | 288 | 289 | // Import Types 290 | 291 | WASM_DECLARE_TYPE(importtype) 292 | 293 | WASM_API_EXTERN own wasm_importtype_t* wasm_importtype_new( 294 | own wasm_name_t* module, own wasm_name_t* name, own wasm_externtype_t*); 295 | 296 | WASM_API_EXTERN const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*); 297 | WASM_API_EXTERN const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*); 298 | WASM_API_EXTERN const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*); 299 | 300 | 301 | // Export Types 302 | 303 | WASM_DECLARE_TYPE(exporttype) 304 | 305 | WASM_API_EXTERN own wasm_exporttype_t* wasm_exporttype_new( 306 | own wasm_name_t*, own wasm_externtype_t*); 307 | 308 | WASM_API_EXTERN const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*); 309 | WASM_API_EXTERN const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*); 310 | 311 | 312 | /////////////////////////////////////////////////////////////////////////////// 313 | // Runtime Objects 314 | 315 | // Values 316 | 317 | struct wasm_ref_t; 318 | 319 | typedef struct wasm_val_t { 320 | wasm_valkind_t kind; 321 | union { 322 | int32_t i32; 323 | int64_t i64; 324 | float32_t f32; 325 | float64_t f64; 326 | struct wasm_ref_t* ref; 327 | } of; 328 | } wasm_val_t; 329 | 330 | WASM_API_EXTERN void wasm_val_delete(own wasm_val_t* v); 331 | WASM_API_EXTERN void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*); 332 | 333 | WASM_DECLARE_VEC(val, ) 334 | 335 | 336 | // References 337 | 338 | #define WASM_DECLARE_REF_BASE(name) \ 339 | WASM_DECLARE_OWN(name) \ 340 | \ 341 | WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \ 342 | WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \ 343 | \ 344 | WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \ 345 | WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \ 346 | WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \ 347 | wasm_##name##_t*, void*, void (*)(void*)); 348 | 349 | #define WASM_DECLARE_REF(name) \ 350 | WASM_DECLARE_REF_BASE(name) \ 351 | \ 352 | WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \ 353 | WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \ 354 | WASM_API_EXTERN const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \ 355 | WASM_API_EXTERN const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*); 356 | 357 | #define WASM_DECLARE_SHARABLE_REF(name) \ 358 | WASM_DECLARE_REF(name) \ 359 | WASM_DECLARE_OWN(shared_##name) \ 360 | \ 361 | WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \ 362 | WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*); 363 | 364 | 365 | WASM_DECLARE_REF_BASE(ref) 366 | 367 | 368 | // Frames 369 | 370 | WASM_DECLARE_OWN(frame) 371 | WASM_DECLARE_VEC(frame, *) 372 | WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*); 373 | 374 | WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*); 375 | WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*); 376 | WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*); 377 | WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*); 378 | 379 | 380 | // Traps 381 | 382 | typedef wasm_name_t wasm_message_t; // null terminated 383 | 384 | WASM_DECLARE_REF(trap) 385 | 386 | WASM_API_EXTERN own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*); 387 | 388 | WASM_API_EXTERN void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out); 389 | WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*); 390 | WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out); 391 | 392 | 393 | // Foreign Objects 394 | 395 | WASM_DECLARE_REF(foreign) 396 | 397 | WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*); 398 | 399 | 400 | // Modules 401 | 402 | WASM_DECLARE_SHARABLE_REF(module) 403 | 404 | WASM_API_EXTERN own wasm_module_t* wasm_module_new( 405 | wasm_store_t*, const wasm_byte_vec_t* binary); 406 | 407 | WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary); 408 | 409 | WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out); 410 | WASM_API_EXTERN void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out); 411 | 412 | WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out); 413 | WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*); 414 | 415 | 416 | // Function Instances 417 | 418 | WASM_DECLARE_REF(func) 419 | 420 | typedef own wasm_trap_t* (*wasm_func_callback_t)( 421 | const wasm_val_vec_t* args, own wasm_val_vec_t* results); 422 | typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)( 423 | void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results); 424 | 425 | WASM_API_EXTERN own wasm_func_t* wasm_func_new( 426 | wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t); 427 | WASM_API_EXTERN own wasm_func_t* wasm_func_new_with_env( 428 | wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t, 429 | void* env, void (*finalizer)(void*)); 430 | 431 | WASM_API_EXTERN own wasm_functype_t* wasm_func_type(const wasm_func_t*); 432 | WASM_API_EXTERN size_t wasm_func_param_arity(const wasm_func_t*); 433 | WASM_API_EXTERN size_t wasm_func_result_arity(const wasm_func_t*); 434 | 435 | WASM_API_EXTERN own wasm_trap_t* wasm_func_call( 436 | const wasm_func_t*, const wasm_val_vec_t* args, wasm_val_vec_t* results); 437 | 438 | 439 | // Global Instances 440 | 441 | WASM_DECLARE_REF(global) 442 | 443 | WASM_API_EXTERN own wasm_global_t* wasm_global_new( 444 | wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*); 445 | 446 | WASM_API_EXTERN own wasm_globaltype_t* wasm_global_type(const wasm_global_t*); 447 | 448 | WASM_API_EXTERN void wasm_global_get(const wasm_global_t*, own wasm_val_t* out); 449 | WASM_API_EXTERN void wasm_global_set(wasm_global_t*, const wasm_val_t*); 450 | 451 | 452 | // Table Instances 453 | 454 | WASM_DECLARE_REF(table) 455 | 456 | typedef uint32_t wasm_table_size_t; 457 | 458 | WASM_API_EXTERN own wasm_table_t* wasm_table_new( 459 | wasm_store_t*, const wasm_tabletype_t*, wasm_ref_t* init); 460 | 461 | WASM_API_EXTERN own wasm_tabletype_t* wasm_table_type(const wasm_table_t*); 462 | 463 | WASM_API_EXTERN own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index); 464 | WASM_API_EXTERN bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*); 465 | 466 | WASM_API_EXTERN wasm_table_size_t wasm_table_size(const wasm_table_t*); 467 | WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init); 468 | 469 | 470 | // Memory Instances 471 | 472 | WASM_DECLARE_REF(memory) 473 | 474 | typedef uint32_t wasm_memory_pages_t; 475 | 476 | static const size_t MEMORY_PAGE_SIZE = 0x10000; 477 | 478 | WASM_API_EXTERN own wasm_memory_t* wasm_memory_new(wasm_store_t*, const wasm_memorytype_t*); 479 | 480 | WASM_API_EXTERN own wasm_memorytype_t* wasm_memory_type(const wasm_memory_t*); 481 | 482 | WASM_API_EXTERN byte_t* wasm_memory_data(wasm_memory_t*); 483 | WASM_API_EXTERN size_t wasm_memory_data_size(const wasm_memory_t*); 484 | 485 | WASM_API_EXTERN wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*); 486 | WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta); 487 | 488 | 489 | // Externals 490 | 491 | WASM_DECLARE_REF(extern) 492 | WASM_DECLARE_VEC(extern, *) 493 | 494 | WASM_API_EXTERN wasm_externkind_t wasm_extern_kind(const wasm_extern_t*); 495 | WASM_API_EXTERN own wasm_externtype_t* wasm_extern_type(const wasm_extern_t*); 496 | 497 | WASM_API_EXTERN wasm_extern_t* wasm_func_as_extern(wasm_func_t*); 498 | WASM_API_EXTERN wasm_extern_t* wasm_global_as_extern(wasm_global_t*); 499 | WASM_API_EXTERN wasm_extern_t* wasm_table_as_extern(wasm_table_t*); 500 | WASM_API_EXTERN wasm_extern_t* wasm_memory_as_extern(wasm_memory_t*); 501 | 502 | WASM_API_EXTERN wasm_func_t* wasm_extern_as_func(wasm_extern_t*); 503 | WASM_API_EXTERN wasm_global_t* wasm_extern_as_global(wasm_extern_t*); 504 | WASM_API_EXTERN wasm_table_t* wasm_extern_as_table(wasm_extern_t*); 505 | WASM_API_EXTERN wasm_memory_t* wasm_extern_as_memory(wasm_extern_t*); 506 | 507 | WASM_API_EXTERN const wasm_extern_t* wasm_func_as_extern_const(const wasm_func_t*); 508 | WASM_API_EXTERN const wasm_extern_t* wasm_global_as_extern_const(const wasm_global_t*); 509 | WASM_API_EXTERN const wasm_extern_t* wasm_table_as_extern_const(const wasm_table_t*); 510 | WASM_API_EXTERN const wasm_extern_t* wasm_memory_as_extern_const(const wasm_memory_t*); 511 | 512 | WASM_API_EXTERN const wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t*); 513 | WASM_API_EXTERN const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t*); 514 | WASM_API_EXTERN const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t*); 515 | WASM_API_EXTERN const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t*); 516 | 517 | 518 | // Module Instances 519 | 520 | WASM_DECLARE_REF(instance) 521 | 522 | WASM_API_EXTERN own wasm_instance_t* wasm_instance_new( 523 | wasm_store_t*, const wasm_module_t*, const wasm_extern_vec_t* imports, 524 | own wasm_trap_t** 525 | ); 526 | 527 | WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out); 528 | 529 | 530 | /////////////////////////////////////////////////////////////////////////////// 531 | // Convenience 532 | 533 | // Vectors 534 | 535 | #define WASM_EMPTY_VEC {0, NULL} 536 | #define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array} 537 | 538 | 539 | // Value Type construction short-hands 540 | 541 | static inline own wasm_valtype_t* wasm_valtype_new_i32() { 542 | return wasm_valtype_new(WASM_I32); 543 | } 544 | static inline own wasm_valtype_t* wasm_valtype_new_i64() { 545 | return wasm_valtype_new(WASM_I64); 546 | } 547 | static inline own wasm_valtype_t* wasm_valtype_new_f32() { 548 | return wasm_valtype_new(WASM_F32); 549 | } 550 | static inline own wasm_valtype_t* wasm_valtype_new_f64() { 551 | return wasm_valtype_new(WASM_F64); 552 | } 553 | 554 | static inline own wasm_valtype_t* wasm_valtype_new_anyref() { 555 | return wasm_valtype_new(WASM_ANYREF); 556 | } 557 | static inline own wasm_valtype_t* wasm_valtype_new_funcref() { 558 | return wasm_valtype_new(WASM_FUNCREF); 559 | } 560 | 561 | 562 | // Function Types construction short-hands 563 | 564 | static inline own wasm_functype_t* wasm_functype_new_0_0() { 565 | wasm_valtype_vec_t params, results; 566 | wasm_valtype_vec_new_empty(¶ms); 567 | wasm_valtype_vec_new_empty(&results); 568 | return wasm_functype_new(¶ms, &results); 569 | } 570 | 571 | static inline own wasm_functype_t* wasm_functype_new_1_0( 572 | own wasm_valtype_t* p 573 | ) { 574 | wasm_valtype_t* ps[1] = {p}; 575 | wasm_valtype_vec_t params, results; 576 | wasm_valtype_vec_new(¶ms, 1, ps); 577 | wasm_valtype_vec_new_empty(&results); 578 | return wasm_functype_new(¶ms, &results); 579 | } 580 | 581 | static inline own wasm_functype_t* wasm_functype_new_2_0( 582 | own wasm_valtype_t* p1, own wasm_valtype_t* p2 583 | ) { 584 | wasm_valtype_t* ps[2] = {p1, p2}; 585 | wasm_valtype_vec_t params, results; 586 | wasm_valtype_vec_new(¶ms, 2, ps); 587 | wasm_valtype_vec_new_empty(&results); 588 | return wasm_functype_new(¶ms, &results); 589 | } 590 | 591 | static inline own wasm_functype_t* wasm_functype_new_3_0( 592 | own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3 593 | ) { 594 | wasm_valtype_t* ps[3] = {p1, p2, p3}; 595 | wasm_valtype_vec_t params, results; 596 | wasm_valtype_vec_new(¶ms, 3, ps); 597 | wasm_valtype_vec_new_empty(&results); 598 | return wasm_functype_new(¶ms, &results); 599 | } 600 | 601 | static inline own wasm_functype_t* wasm_functype_new_0_1( 602 | own wasm_valtype_t* r 603 | ) { 604 | wasm_valtype_t* rs[1] = {r}; 605 | wasm_valtype_vec_t params, results; 606 | wasm_valtype_vec_new_empty(¶ms); 607 | wasm_valtype_vec_new(&results, 1, rs); 608 | return wasm_functype_new(¶ms, &results); 609 | } 610 | 611 | static inline own wasm_functype_t* wasm_functype_new_1_1( 612 | own wasm_valtype_t* p, own wasm_valtype_t* r 613 | ) { 614 | wasm_valtype_t* ps[1] = {p}; 615 | wasm_valtype_t* rs[1] = {r}; 616 | wasm_valtype_vec_t params, results; 617 | wasm_valtype_vec_new(¶ms, 1, ps); 618 | wasm_valtype_vec_new(&results, 1, rs); 619 | return wasm_functype_new(¶ms, &results); 620 | } 621 | 622 | static inline own wasm_functype_t* wasm_functype_new_2_1( 623 | own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* r 624 | ) { 625 | wasm_valtype_t* ps[2] = {p1, p2}; 626 | wasm_valtype_t* rs[1] = {r}; 627 | wasm_valtype_vec_t params, results; 628 | wasm_valtype_vec_new(¶ms, 2, ps); 629 | wasm_valtype_vec_new(&results, 1, rs); 630 | return wasm_functype_new(¶ms, &results); 631 | } 632 | 633 | static inline own wasm_functype_t* wasm_functype_new_3_1( 634 | own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3, 635 | own wasm_valtype_t* r 636 | ) { 637 | wasm_valtype_t* ps[3] = {p1, p2, p3}; 638 | wasm_valtype_t* rs[1] = {r}; 639 | wasm_valtype_vec_t params, results; 640 | wasm_valtype_vec_new(¶ms, 3, ps); 641 | wasm_valtype_vec_new(&results, 1, rs); 642 | return wasm_functype_new(¶ms, &results); 643 | } 644 | 645 | static inline own wasm_functype_t* wasm_functype_new_0_2( 646 | own wasm_valtype_t* r1, own wasm_valtype_t* r2 647 | ) { 648 | wasm_valtype_t* rs[2] = {r1, r2}; 649 | wasm_valtype_vec_t params, results; 650 | wasm_valtype_vec_new_empty(¶ms); 651 | wasm_valtype_vec_new(&results, 2, rs); 652 | return wasm_functype_new(¶ms, &results); 653 | } 654 | 655 | static inline own wasm_functype_t* wasm_functype_new_1_2( 656 | own wasm_valtype_t* p, own wasm_valtype_t* r1, own wasm_valtype_t* r2 657 | ) { 658 | wasm_valtype_t* ps[1] = {p}; 659 | wasm_valtype_t* rs[2] = {r1, r2}; 660 | wasm_valtype_vec_t params, results; 661 | wasm_valtype_vec_new(¶ms, 1, ps); 662 | wasm_valtype_vec_new(&results, 2, rs); 663 | return wasm_functype_new(¶ms, &results); 664 | } 665 | 666 | static inline own wasm_functype_t* wasm_functype_new_2_2( 667 | own wasm_valtype_t* p1, own wasm_valtype_t* p2, 668 | own wasm_valtype_t* r1, own wasm_valtype_t* r2 669 | ) { 670 | wasm_valtype_t* ps[2] = {p1, p2}; 671 | wasm_valtype_t* rs[2] = {r1, r2}; 672 | wasm_valtype_vec_t params, results; 673 | wasm_valtype_vec_new(¶ms, 2, ps); 674 | wasm_valtype_vec_new(&results, 2, rs); 675 | return wasm_functype_new(¶ms, &results); 676 | } 677 | 678 | static inline own wasm_functype_t* wasm_functype_new_3_2( 679 | own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3, 680 | own wasm_valtype_t* r1, own wasm_valtype_t* r2 681 | ) { 682 | wasm_valtype_t* ps[3] = {p1, p2, p3}; 683 | wasm_valtype_t* rs[2] = {r1, r2}; 684 | wasm_valtype_vec_t params, results; 685 | wasm_valtype_vec_new(¶ms, 3, ps); 686 | wasm_valtype_vec_new(&results, 2, rs); 687 | return wasm_functype_new(¶ms, &results); 688 | } 689 | 690 | 691 | // Value construction short-hands 692 | 693 | static inline void wasm_val_init_ptr(own wasm_val_t* out, void* p) { 694 | #if UINTPTR_MAX == UINT32_MAX 695 | out->kind = WASM_I32; 696 | out->of.i32 = (intptr_t)p; 697 | #elif UINTPTR_MAX == UINT64_MAX 698 | out->kind = WASM_I64; 699 | out->of.i64 = (intptr_t)p; 700 | #endif 701 | } 702 | 703 | static inline void* wasm_val_ptr(const wasm_val_t* val) { 704 | #if UINTPTR_MAX == UINT32_MAX 705 | return (void*)(intptr_t)val->of.i32; 706 | #elif UINTPTR_MAX == UINT64_MAX 707 | return (void*)(intptr_t)val->of.i64; 708 | #endif 709 | } 710 | 711 | #define WASM_I32_VAL(i) {.kind = WASM_I32, .of = {.i32 = i}} 712 | #define WASM_I64_VAL(i) {.kind = WASM_I64, .of = {.i64 = i}} 713 | #define WASM_F32_VAL(z) {.kind = WASM_F32, .of = {.f32 = z}} 714 | #define WASM_F64_VAL(z) {.kind = WASM_F64, .of = {.f64 = z}} 715 | #define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}} 716 | #define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}} 717 | 718 | 719 | /////////////////////////////////////////////////////////////////////////////// 720 | 721 | #undef own 722 | 723 | #ifdef __cplusplus 724 | } // extern "C" 725 | #endif 726 | 727 | #endif // #ifdef WASM_H -------------------------------------------------------------------------------- /reference/wasmer.h: -------------------------------------------------------------------------------- 1 | // The Wasmer C/C++ header file compatible with the [`wasm-c-api`] 2 | // standard API, as `wasm.h` (included here). 3 | // 4 | // This file is automatically generated by `lib/c-api/build.rs` of the 5 | // [`wasmer-c-api`] Rust crate. 6 | // 7 | // # Stability 8 | // 9 | // The [`wasm-c-api`] standard API is a _living_ standard. There is no 10 | // commitment for stability yet. We (Wasmer) will try our best to keep 11 | // backward compatibility as much as possible. Nonetheless, some 12 | // necessary API aren't yet standardized, and as such, we provide a 13 | // custom API, e.g. `wasi_*` types and functions. 14 | // 15 | // The documentation makes it clear whether a function is unstable. 16 | // 17 | // When a type or a function will be deprecated, it will be marked as 18 | // such with the appropriated compiler warning, and will be removed at 19 | // the next release round. 20 | // 21 | // # Documentation 22 | // 23 | // At the time of writing, the [`wasm-c-api`] standard has no 24 | // documentation. This file also does not include inline 25 | // documentation. However, we have made (and we continue to make) an 26 | // important effort to document everything. [See the documentation 27 | // online][documentation]. Please refer to this page for the real 28 | // canonical documentation. It also contains numerous examples. 29 | // 30 | // To generate the documentation locally, run `cargo doc --open` from 31 | // within the [`wasmer-c-api`] Rust crate. 32 | // 33 | // [`wasm-c-api`]: https://github.com/WebAssembly/wasm-c-api 34 | // [`wasmer-c-api`]: https://github.com/wasmerio/wasmer/tree/main/lib/c-api 35 | // [documentation]: https://wasmerio.github.io/wasmer/crates/wasmer_c_api/ 36 | 37 | #if !defined(WASMER_H_PRELUDE) 38 | 39 | #define WASMER_H_PRELUDE 40 | 41 | // Define the `ARCH_X86_X64` constant. 42 | #if defined(MSVC) && defined(_M_AMD64) 43 | # define ARCH_X86_64 44 | #elif (defined(GCC) || defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__) 45 | # define ARCH_X86_64 46 | #endif 47 | 48 | // Compatibility with non-Clang compilers. 49 | #if !defined(__has_attribute) 50 | # define __has_attribute(x) 0 51 | #endif 52 | 53 | // Compatibility with non-Clang compilers. 54 | #if !defined(__has_declspec_attribute) 55 | # define __has_declspec_attribute(x) 0 56 | #endif 57 | 58 | // Define the `DEPRECATED` macro. 59 | #if defined(GCC) || defined(__GNUC__) || __has_attribute(deprecated) 60 | # define DEPRECATED(message) __attribute__((deprecated(message))) 61 | #elif defined(MSVC) || __has_declspec_attribute(deprecated) 62 | # define DEPRECATED(message) __declspec(deprecated(message)) 63 | #endif 64 | 65 | // The `compiler` feature has been enabled for this build. 66 | #define WASMER_UNIVERSAL_ENABLED 67 | 68 | // The `compiler` feature has been enabled for this build. 69 | #define WASMER_COMPILER_ENABLED 70 | 71 | // The `wasi` feature has been enabled for this build. 72 | #define WASMER_WASI_ENABLED 73 | 74 | // The `middlewares` feature has been enabled for this build. 75 | #define WASMER_MIDDLEWARES_ENABLED 76 | 77 | // This file corresponds to the following Wasmer version. 78 | #define WASMER_VERSION "4.3.0" 79 | #define WASMER_VERSION_MAJOR 4 80 | #define WASMER_VERSION_MINOR 3 81 | #define WASMER_VERSION_PATCH 0 82 | #define WASMER_VERSION_PRE "" 83 | 84 | #endif // WASMER_H_PRELUDE 85 | 86 | 87 | // 88 | // OK, here we go. The code below is automatically generated. 89 | // 90 | 91 | 92 | #ifndef WASMER_H 93 | #define WASMER_H 94 | 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include "wasm.h" 100 | 101 | #if defined(WASMER_WASI_ENABLED) 102 | typedef enum wasi_version_t { 103 | #if defined(WASMER_WASI_ENABLED) 104 | INVALID_VERSION = -1, 105 | #endif 106 | #if defined(WASMER_WASI_ENABLED) 107 | LATEST = 0, 108 | #endif 109 | #if defined(WASMER_WASI_ENABLED) 110 | SNAPSHOT0 = 1, 111 | #endif 112 | #if defined(WASMER_WASI_ENABLED) 113 | SNAPSHOT1 = 2, 114 | #endif 115 | #if defined(WASMER_WASI_ENABLED) 116 | WASIX32V1 = 3, 117 | #endif 118 | #if defined(WASMER_WASI_ENABLED) 119 | WASIX64V1 = 4, 120 | #endif 121 | } wasi_version_t; 122 | #endif 123 | 124 | #if defined(WASMER_COMPILER_ENABLED) 125 | typedef enum wasmer_compiler_t { 126 | CRANELIFT = 0, 127 | LLVM = 1, 128 | SINGLEPASS = 2, 129 | } wasmer_compiler_t; 130 | #endif 131 | 132 | typedef enum wasmer_engine_t { 133 | UNIVERSAL = 0, 134 | } wasmer_engine_t; 135 | 136 | #if defined(WASMER_COMPILER_ENABLED) 137 | typedef enum wasmer_parser_operator_t { 138 | #if defined(WASMER_COMPILER_ENABLED) 139 | Unreachable, 140 | #endif 141 | #if defined(WASMER_COMPILER_ENABLED) 142 | Nop, 143 | #endif 144 | #if defined(WASMER_COMPILER_ENABLED) 145 | Block, 146 | #endif 147 | #if defined(WASMER_COMPILER_ENABLED) 148 | Loop, 149 | #endif 150 | #if defined(WASMER_COMPILER_ENABLED) 151 | If, 152 | #endif 153 | #if defined(WASMER_COMPILER_ENABLED) 154 | Else, 155 | #endif 156 | #if defined(WASMER_COMPILER_ENABLED) 157 | Try, 158 | #endif 159 | #if defined(WASMER_COMPILER_ENABLED) 160 | Catch, 161 | #endif 162 | #if defined(WASMER_COMPILER_ENABLED) 163 | CatchAll, 164 | #endif 165 | #if defined(WASMER_COMPILER_ENABLED) 166 | Delegate, 167 | #endif 168 | #if defined(WASMER_COMPILER_ENABLED) 169 | Throw, 170 | #endif 171 | #if defined(WASMER_COMPILER_ENABLED) 172 | Rethrow, 173 | #endif 174 | #if defined(WASMER_COMPILER_ENABLED) 175 | Unwind, 176 | #endif 177 | #if defined(WASMER_COMPILER_ENABLED) 178 | End, 179 | #endif 180 | #if defined(WASMER_COMPILER_ENABLED) 181 | Br, 182 | #endif 183 | #if defined(WASMER_COMPILER_ENABLED) 184 | BrIf, 185 | #endif 186 | #if defined(WASMER_COMPILER_ENABLED) 187 | BrTable, 188 | #endif 189 | #if defined(WASMER_COMPILER_ENABLED) 190 | Return, 191 | #endif 192 | #if defined(WASMER_COMPILER_ENABLED) 193 | Call, 194 | #endif 195 | #if defined(WASMER_COMPILER_ENABLED) 196 | CallIndirect, 197 | #endif 198 | #if defined(WASMER_COMPILER_ENABLED) 199 | ReturnCall, 200 | #endif 201 | #if defined(WASMER_COMPILER_ENABLED) 202 | ReturnCallIndirect, 203 | #endif 204 | #if defined(WASMER_COMPILER_ENABLED) 205 | Drop, 206 | #endif 207 | #if defined(WASMER_COMPILER_ENABLED) 208 | Select, 209 | #endif 210 | #if defined(WASMER_COMPILER_ENABLED) 211 | TypedSelect, 212 | #endif 213 | #if defined(WASMER_COMPILER_ENABLED) 214 | LocalGet, 215 | #endif 216 | #if defined(WASMER_COMPILER_ENABLED) 217 | LocalSet, 218 | #endif 219 | #if defined(WASMER_COMPILER_ENABLED) 220 | LocalTee, 221 | #endif 222 | #if defined(WASMER_COMPILER_ENABLED) 223 | GlobalGet, 224 | #endif 225 | #if defined(WASMER_COMPILER_ENABLED) 226 | GlobalSet, 227 | #endif 228 | #if defined(WASMER_COMPILER_ENABLED) 229 | I32Load, 230 | #endif 231 | #if defined(WASMER_COMPILER_ENABLED) 232 | I64Load, 233 | #endif 234 | #if defined(WASMER_COMPILER_ENABLED) 235 | F32Load, 236 | #endif 237 | #if defined(WASMER_COMPILER_ENABLED) 238 | F64Load, 239 | #endif 240 | #if defined(WASMER_COMPILER_ENABLED) 241 | I32Load8S, 242 | #endif 243 | #if defined(WASMER_COMPILER_ENABLED) 244 | I32Load8U, 245 | #endif 246 | #if defined(WASMER_COMPILER_ENABLED) 247 | I32Load16S, 248 | #endif 249 | #if defined(WASMER_COMPILER_ENABLED) 250 | I32Load16U, 251 | #endif 252 | #if defined(WASMER_COMPILER_ENABLED) 253 | I64Load8S, 254 | #endif 255 | #if defined(WASMER_COMPILER_ENABLED) 256 | I64Load8U, 257 | #endif 258 | #if defined(WASMER_COMPILER_ENABLED) 259 | I64Load16S, 260 | #endif 261 | #if defined(WASMER_COMPILER_ENABLED) 262 | I64Load16U, 263 | #endif 264 | #if defined(WASMER_COMPILER_ENABLED) 265 | I64Load32S, 266 | #endif 267 | #if defined(WASMER_COMPILER_ENABLED) 268 | I64Load32U, 269 | #endif 270 | #if defined(WASMER_COMPILER_ENABLED) 271 | I32Store, 272 | #endif 273 | #if defined(WASMER_COMPILER_ENABLED) 274 | I64Store, 275 | #endif 276 | #if defined(WASMER_COMPILER_ENABLED) 277 | F32Store, 278 | #endif 279 | #if defined(WASMER_COMPILER_ENABLED) 280 | F64Store, 281 | #endif 282 | #if defined(WASMER_COMPILER_ENABLED) 283 | I32Store8, 284 | #endif 285 | #if defined(WASMER_COMPILER_ENABLED) 286 | I32Store16, 287 | #endif 288 | #if defined(WASMER_COMPILER_ENABLED) 289 | I64Store8, 290 | #endif 291 | #if defined(WASMER_COMPILER_ENABLED) 292 | I64Store16, 293 | #endif 294 | #if defined(WASMER_COMPILER_ENABLED) 295 | I64Store32, 296 | #endif 297 | #if defined(WASMER_COMPILER_ENABLED) 298 | MemorySize, 299 | #endif 300 | #if defined(WASMER_COMPILER_ENABLED) 301 | MemoryGrow, 302 | #endif 303 | #if defined(WASMER_COMPILER_ENABLED) 304 | I32Const, 305 | #endif 306 | #if defined(WASMER_COMPILER_ENABLED) 307 | I64Const, 308 | #endif 309 | #if defined(WASMER_COMPILER_ENABLED) 310 | F32Const, 311 | #endif 312 | #if defined(WASMER_COMPILER_ENABLED) 313 | F64Const, 314 | #endif 315 | #if defined(WASMER_COMPILER_ENABLED) 316 | RefNull, 317 | #endif 318 | #if defined(WASMER_COMPILER_ENABLED) 319 | RefIsNull, 320 | #endif 321 | #if defined(WASMER_COMPILER_ENABLED) 322 | RefFunc, 323 | #endif 324 | #if defined(WASMER_COMPILER_ENABLED) 325 | I32Eqz, 326 | #endif 327 | #if defined(WASMER_COMPILER_ENABLED) 328 | I32Eq, 329 | #endif 330 | #if defined(WASMER_COMPILER_ENABLED) 331 | I32Ne, 332 | #endif 333 | #if defined(WASMER_COMPILER_ENABLED) 334 | I32LtS, 335 | #endif 336 | #if defined(WASMER_COMPILER_ENABLED) 337 | I32LtU, 338 | #endif 339 | #if defined(WASMER_COMPILER_ENABLED) 340 | I32GtS, 341 | #endif 342 | #if defined(WASMER_COMPILER_ENABLED) 343 | I32GtU, 344 | #endif 345 | #if defined(WASMER_COMPILER_ENABLED) 346 | I32LeS, 347 | #endif 348 | #if defined(WASMER_COMPILER_ENABLED) 349 | I32LeU, 350 | #endif 351 | #if defined(WASMER_COMPILER_ENABLED) 352 | I32GeS, 353 | #endif 354 | #if defined(WASMER_COMPILER_ENABLED) 355 | I32GeU, 356 | #endif 357 | #if defined(WASMER_COMPILER_ENABLED) 358 | I64Eqz, 359 | #endif 360 | #if defined(WASMER_COMPILER_ENABLED) 361 | I64Eq, 362 | #endif 363 | #if defined(WASMER_COMPILER_ENABLED) 364 | I64Ne, 365 | #endif 366 | #if defined(WASMER_COMPILER_ENABLED) 367 | I64LtS, 368 | #endif 369 | #if defined(WASMER_COMPILER_ENABLED) 370 | I64LtU, 371 | #endif 372 | #if defined(WASMER_COMPILER_ENABLED) 373 | I64GtS, 374 | #endif 375 | #if defined(WASMER_COMPILER_ENABLED) 376 | I64GtU, 377 | #endif 378 | #if defined(WASMER_COMPILER_ENABLED) 379 | I64LeS, 380 | #endif 381 | #if defined(WASMER_COMPILER_ENABLED) 382 | I64LeU, 383 | #endif 384 | #if defined(WASMER_COMPILER_ENABLED) 385 | I64GeS, 386 | #endif 387 | #if defined(WASMER_COMPILER_ENABLED) 388 | I64GeU, 389 | #endif 390 | #if defined(WASMER_COMPILER_ENABLED) 391 | F32Eq, 392 | #endif 393 | #if defined(WASMER_COMPILER_ENABLED) 394 | F32Ne, 395 | #endif 396 | #if defined(WASMER_COMPILER_ENABLED) 397 | F32Lt, 398 | #endif 399 | #if defined(WASMER_COMPILER_ENABLED) 400 | F32Gt, 401 | #endif 402 | #if defined(WASMER_COMPILER_ENABLED) 403 | F32Le, 404 | #endif 405 | #if defined(WASMER_COMPILER_ENABLED) 406 | F32Ge, 407 | #endif 408 | #if defined(WASMER_COMPILER_ENABLED) 409 | F64Eq, 410 | #endif 411 | #if defined(WASMER_COMPILER_ENABLED) 412 | F64Ne, 413 | #endif 414 | #if defined(WASMER_COMPILER_ENABLED) 415 | F64Lt, 416 | #endif 417 | #if defined(WASMER_COMPILER_ENABLED) 418 | F64Gt, 419 | #endif 420 | #if defined(WASMER_COMPILER_ENABLED) 421 | F64Le, 422 | #endif 423 | #if defined(WASMER_COMPILER_ENABLED) 424 | F64Ge, 425 | #endif 426 | #if defined(WASMER_COMPILER_ENABLED) 427 | I32Clz, 428 | #endif 429 | #if defined(WASMER_COMPILER_ENABLED) 430 | I32Ctz, 431 | #endif 432 | #if defined(WASMER_COMPILER_ENABLED) 433 | I32Popcnt, 434 | #endif 435 | #if defined(WASMER_COMPILER_ENABLED) 436 | I32Add, 437 | #endif 438 | #if defined(WASMER_COMPILER_ENABLED) 439 | I32Sub, 440 | #endif 441 | #if defined(WASMER_COMPILER_ENABLED) 442 | I32Mul, 443 | #endif 444 | #if defined(WASMER_COMPILER_ENABLED) 445 | I32DivS, 446 | #endif 447 | #if defined(WASMER_COMPILER_ENABLED) 448 | I32DivU, 449 | #endif 450 | #if defined(WASMER_COMPILER_ENABLED) 451 | I32RemS, 452 | #endif 453 | #if defined(WASMER_COMPILER_ENABLED) 454 | I32RemU, 455 | #endif 456 | #if defined(WASMER_COMPILER_ENABLED) 457 | I32And, 458 | #endif 459 | #if defined(WASMER_COMPILER_ENABLED) 460 | I32Or, 461 | #endif 462 | #if defined(WASMER_COMPILER_ENABLED) 463 | I32Xor, 464 | #endif 465 | #if defined(WASMER_COMPILER_ENABLED) 466 | I32Shl, 467 | #endif 468 | #if defined(WASMER_COMPILER_ENABLED) 469 | I32ShrS, 470 | #endif 471 | #if defined(WASMER_COMPILER_ENABLED) 472 | I32ShrU, 473 | #endif 474 | #if defined(WASMER_COMPILER_ENABLED) 475 | I32Rotl, 476 | #endif 477 | #if defined(WASMER_COMPILER_ENABLED) 478 | I32Rotr, 479 | #endif 480 | #if defined(WASMER_COMPILER_ENABLED) 481 | I64Clz, 482 | #endif 483 | #if defined(WASMER_COMPILER_ENABLED) 484 | I64Ctz, 485 | #endif 486 | #if defined(WASMER_COMPILER_ENABLED) 487 | I64Popcnt, 488 | #endif 489 | #if defined(WASMER_COMPILER_ENABLED) 490 | I64Add, 491 | #endif 492 | #if defined(WASMER_COMPILER_ENABLED) 493 | I64Sub, 494 | #endif 495 | #if defined(WASMER_COMPILER_ENABLED) 496 | I64Mul, 497 | #endif 498 | #if defined(WASMER_COMPILER_ENABLED) 499 | I64DivS, 500 | #endif 501 | #if defined(WASMER_COMPILER_ENABLED) 502 | I64DivU, 503 | #endif 504 | #if defined(WASMER_COMPILER_ENABLED) 505 | I64RemS, 506 | #endif 507 | #if defined(WASMER_COMPILER_ENABLED) 508 | I64RemU, 509 | #endif 510 | #if defined(WASMER_COMPILER_ENABLED) 511 | I64And, 512 | #endif 513 | #if defined(WASMER_COMPILER_ENABLED) 514 | I64Or, 515 | #endif 516 | #if defined(WASMER_COMPILER_ENABLED) 517 | I64Xor, 518 | #endif 519 | #if defined(WASMER_COMPILER_ENABLED) 520 | I64Shl, 521 | #endif 522 | #if defined(WASMER_COMPILER_ENABLED) 523 | I64ShrS, 524 | #endif 525 | #if defined(WASMER_COMPILER_ENABLED) 526 | I64ShrU, 527 | #endif 528 | #if defined(WASMER_COMPILER_ENABLED) 529 | I64Rotl, 530 | #endif 531 | #if defined(WASMER_COMPILER_ENABLED) 532 | I64Rotr, 533 | #endif 534 | #if defined(WASMER_COMPILER_ENABLED) 535 | F32Abs, 536 | #endif 537 | #if defined(WASMER_COMPILER_ENABLED) 538 | F32Neg, 539 | #endif 540 | #if defined(WASMER_COMPILER_ENABLED) 541 | F32Ceil, 542 | #endif 543 | #if defined(WASMER_COMPILER_ENABLED) 544 | F32Floor, 545 | #endif 546 | #if defined(WASMER_COMPILER_ENABLED) 547 | F32Trunc, 548 | #endif 549 | #if defined(WASMER_COMPILER_ENABLED) 550 | F32Nearest, 551 | #endif 552 | #if defined(WASMER_COMPILER_ENABLED) 553 | F32Sqrt, 554 | #endif 555 | #if defined(WASMER_COMPILER_ENABLED) 556 | F32Add, 557 | #endif 558 | #if defined(WASMER_COMPILER_ENABLED) 559 | F32Sub, 560 | #endif 561 | #if defined(WASMER_COMPILER_ENABLED) 562 | F32Mul, 563 | #endif 564 | #if defined(WASMER_COMPILER_ENABLED) 565 | F32Div, 566 | #endif 567 | #if defined(WASMER_COMPILER_ENABLED) 568 | F32Min, 569 | #endif 570 | #if defined(WASMER_COMPILER_ENABLED) 571 | F32Max, 572 | #endif 573 | #if defined(WASMER_COMPILER_ENABLED) 574 | F32Copysign, 575 | #endif 576 | #if defined(WASMER_COMPILER_ENABLED) 577 | F64Abs, 578 | #endif 579 | #if defined(WASMER_COMPILER_ENABLED) 580 | F64Neg, 581 | #endif 582 | #if defined(WASMER_COMPILER_ENABLED) 583 | F64Ceil, 584 | #endif 585 | #if defined(WASMER_COMPILER_ENABLED) 586 | F64Floor, 587 | #endif 588 | #if defined(WASMER_COMPILER_ENABLED) 589 | F64Trunc, 590 | #endif 591 | #if defined(WASMER_COMPILER_ENABLED) 592 | F64Nearest, 593 | #endif 594 | #if defined(WASMER_COMPILER_ENABLED) 595 | F64Sqrt, 596 | #endif 597 | #if defined(WASMER_COMPILER_ENABLED) 598 | F64Add, 599 | #endif 600 | #if defined(WASMER_COMPILER_ENABLED) 601 | F64Sub, 602 | #endif 603 | #if defined(WASMER_COMPILER_ENABLED) 604 | F64Mul, 605 | #endif 606 | #if defined(WASMER_COMPILER_ENABLED) 607 | F64Div, 608 | #endif 609 | #if defined(WASMER_COMPILER_ENABLED) 610 | F64Min, 611 | #endif 612 | #if defined(WASMER_COMPILER_ENABLED) 613 | F64Max, 614 | #endif 615 | #if defined(WASMER_COMPILER_ENABLED) 616 | F64Copysign, 617 | #endif 618 | #if defined(WASMER_COMPILER_ENABLED) 619 | I32WrapI64, 620 | #endif 621 | #if defined(WASMER_COMPILER_ENABLED) 622 | I32TruncF32S, 623 | #endif 624 | #if defined(WASMER_COMPILER_ENABLED) 625 | I32TruncF32U, 626 | #endif 627 | #if defined(WASMER_COMPILER_ENABLED) 628 | I32TruncF64S, 629 | #endif 630 | #if defined(WASMER_COMPILER_ENABLED) 631 | I32TruncF64U, 632 | #endif 633 | #if defined(WASMER_COMPILER_ENABLED) 634 | I64ExtendI32S, 635 | #endif 636 | #if defined(WASMER_COMPILER_ENABLED) 637 | I64ExtendI32U, 638 | #endif 639 | #if defined(WASMER_COMPILER_ENABLED) 640 | I64TruncF32S, 641 | #endif 642 | #if defined(WASMER_COMPILER_ENABLED) 643 | I64TruncF32U, 644 | #endif 645 | #if defined(WASMER_COMPILER_ENABLED) 646 | I64TruncF64S, 647 | #endif 648 | #if defined(WASMER_COMPILER_ENABLED) 649 | I64TruncF64U, 650 | #endif 651 | #if defined(WASMER_COMPILER_ENABLED) 652 | F32ConvertI32S, 653 | #endif 654 | #if defined(WASMER_COMPILER_ENABLED) 655 | F32ConvertI32U, 656 | #endif 657 | #if defined(WASMER_COMPILER_ENABLED) 658 | F32ConvertI64S, 659 | #endif 660 | #if defined(WASMER_COMPILER_ENABLED) 661 | F32ConvertI64U, 662 | #endif 663 | #if defined(WASMER_COMPILER_ENABLED) 664 | F32DemoteF64, 665 | #endif 666 | #if defined(WASMER_COMPILER_ENABLED) 667 | F64ConvertI32S, 668 | #endif 669 | #if defined(WASMER_COMPILER_ENABLED) 670 | F64ConvertI32U, 671 | #endif 672 | #if defined(WASMER_COMPILER_ENABLED) 673 | F64ConvertI64S, 674 | #endif 675 | #if defined(WASMER_COMPILER_ENABLED) 676 | F64ConvertI64U, 677 | #endif 678 | #if defined(WASMER_COMPILER_ENABLED) 679 | F64PromoteF32, 680 | #endif 681 | #if defined(WASMER_COMPILER_ENABLED) 682 | I32ReinterpretF32, 683 | #endif 684 | #if defined(WASMER_COMPILER_ENABLED) 685 | I64ReinterpretF64, 686 | #endif 687 | #if defined(WASMER_COMPILER_ENABLED) 688 | F32ReinterpretI32, 689 | #endif 690 | #if defined(WASMER_COMPILER_ENABLED) 691 | F64ReinterpretI64, 692 | #endif 693 | #if defined(WASMER_COMPILER_ENABLED) 694 | I32Extend8S, 695 | #endif 696 | #if defined(WASMER_COMPILER_ENABLED) 697 | I32Extend16S, 698 | #endif 699 | #if defined(WASMER_COMPILER_ENABLED) 700 | I64Extend8S, 701 | #endif 702 | #if defined(WASMER_COMPILER_ENABLED) 703 | I64Extend16S, 704 | #endif 705 | #if defined(WASMER_COMPILER_ENABLED) 706 | I64Extend32S, 707 | #endif 708 | #if defined(WASMER_COMPILER_ENABLED) 709 | I32TruncSatF32S, 710 | #endif 711 | #if defined(WASMER_COMPILER_ENABLED) 712 | I32TruncSatF32U, 713 | #endif 714 | #if defined(WASMER_COMPILER_ENABLED) 715 | I32TruncSatF64S, 716 | #endif 717 | #if defined(WASMER_COMPILER_ENABLED) 718 | I32TruncSatF64U, 719 | #endif 720 | #if defined(WASMER_COMPILER_ENABLED) 721 | I64TruncSatF32S, 722 | #endif 723 | #if defined(WASMER_COMPILER_ENABLED) 724 | I64TruncSatF32U, 725 | #endif 726 | #if defined(WASMER_COMPILER_ENABLED) 727 | I64TruncSatF64S, 728 | #endif 729 | #if defined(WASMER_COMPILER_ENABLED) 730 | I64TruncSatF64U, 731 | #endif 732 | #if defined(WASMER_COMPILER_ENABLED) 733 | MemoryInit, 734 | #endif 735 | #if defined(WASMER_COMPILER_ENABLED) 736 | DataDrop, 737 | #endif 738 | #if defined(WASMER_COMPILER_ENABLED) 739 | MemoryCopy, 740 | #endif 741 | #if defined(WASMER_COMPILER_ENABLED) 742 | MemoryFill, 743 | #endif 744 | #if defined(WASMER_COMPILER_ENABLED) 745 | TableInit, 746 | #endif 747 | #if defined(WASMER_COMPILER_ENABLED) 748 | ElemDrop, 749 | #endif 750 | #if defined(WASMER_COMPILER_ENABLED) 751 | TableCopy, 752 | #endif 753 | #if defined(WASMER_COMPILER_ENABLED) 754 | TableFill, 755 | #endif 756 | #if defined(WASMER_COMPILER_ENABLED) 757 | TableGet, 758 | #endif 759 | #if defined(WASMER_COMPILER_ENABLED) 760 | TableSet, 761 | #endif 762 | #if defined(WASMER_COMPILER_ENABLED) 763 | TableGrow, 764 | #endif 765 | #if defined(WASMER_COMPILER_ENABLED) 766 | TableSize, 767 | #endif 768 | #if defined(WASMER_COMPILER_ENABLED) 769 | MemoryAtomicNotify, 770 | #endif 771 | #if defined(WASMER_COMPILER_ENABLED) 772 | MemoryAtomicWait32, 773 | #endif 774 | #if defined(WASMER_COMPILER_ENABLED) 775 | MemoryAtomicWait64, 776 | #endif 777 | #if defined(WASMER_COMPILER_ENABLED) 778 | AtomicFence, 779 | #endif 780 | #if defined(WASMER_COMPILER_ENABLED) 781 | I32AtomicLoad, 782 | #endif 783 | #if defined(WASMER_COMPILER_ENABLED) 784 | I64AtomicLoad, 785 | #endif 786 | #if defined(WASMER_COMPILER_ENABLED) 787 | I32AtomicLoad8U, 788 | #endif 789 | #if defined(WASMER_COMPILER_ENABLED) 790 | I32AtomicLoad16U, 791 | #endif 792 | #if defined(WASMER_COMPILER_ENABLED) 793 | I64AtomicLoad8U, 794 | #endif 795 | #if defined(WASMER_COMPILER_ENABLED) 796 | I64AtomicLoad16U, 797 | #endif 798 | #if defined(WASMER_COMPILER_ENABLED) 799 | I64AtomicLoad32U, 800 | #endif 801 | #if defined(WASMER_COMPILER_ENABLED) 802 | I32AtomicStore, 803 | #endif 804 | #if defined(WASMER_COMPILER_ENABLED) 805 | I64AtomicStore, 806 | #endif 807 | #if defined(WASMER_COMPILER_ENABLED) 808 | I32AtomicStore8, 809 | #endif 810 | #if defined(WASMER_COMPILER_ENABLED) 811 | I32AtomicStore16, 812 | #endif 813 | #if defined(WASMER_COMPILER_ENABLED) 814 | I64AtomicStore8, 815 | #endif 816 | #if defined(WASMER_COMPILER_ENABLED) 817 | I64AtomicStore16, 818 | #endif 819 | #if defined(WASMER_COMPILER_ENABLED) 820 | I64AtomicStore32, 821 | #endif 822 | #if defined(WASMER_COMPILER_ENABLED) 823 | I32AtomicRmwAdd, 824 | #endif 825 | #if defined(WASMER_COMPILER_ENABLED) 826 | I64AtomicRmwAdd, 827 | #endif 828 | #if defined(WASMER_COMPILER_ENABLED) 829 | I32AtomicRmw8AddU, 830 | #endif 831 | #if defined(WASMER_COMPILER_ENABLED) 832 | I32AtomicRmw16AddU, 833 | #endif 834 | #if defined(WASMER_COMPILER_ENABLED) 835 | I64AtomicRmw8AddU, 836 | #endif 837 | #if defined(WASMER_COMPILER_ENABLED) 838 | I64AtomicRmw16AddU, 839 | #endif 840 | #if defined(WASMER_COMPILER_ENABLED) 841 | I64AtomicRmw32AddU, 842 | #endif 843 | #if defined(WASMER_COMPILER_ENABLED) 844 | I32AtomicRmwSub, 845 | #endif 846 | #if defined(WASMER_COMPILER_ENABLED) 847 | I64AtomicRmwSub, 848 | #endif 849 | #if defined(WASMER_COMPILER_ENABLED) 850 | I32AtomicRmw8SubU, 851 | #endif 852 | #if defined(WASMER_COMPILER_ENABLED) 853 | I32AtomicRmw16SubU, 854 | #endif 855 | #if defined(WASMER_COMPILER_ENABLED) 856 | I64AtomicRmw8SubU, 857 | #endif 858 | #if defined(WASMER_COMPILER_ENABLED) 859 | I64AtomicRmw16SubU, 860 | #endif 861 | #if defined(WASMER_COMPILER_ENABLED) 862 | I64AtomicRmw32SubU, 863 | #endif 864 | #if defined(WASMER_COMPILER_ENABLED) 865 | I32AtomicRmwAnd, 866 | #endif 867 | #if defined(WASMER_COMPILER_ENABLED) 868 | I64AtomicRmwAnd, 869 | #endif 870 | #if defined(WASMER_COMPILER_ENABLED) 871 | I32AtomicRmw8AndU, 872 | #endif 873 | #if defined(WASMER_COMPILER_ENABLED) 874 | I32AtomicRmw16AndU, 875 | #endif 876 | #if defined(WASMER_COMPILER_ENABLED) 877 | I64AtomicRmw8AndU, 878 | #endif 879 | #if defined(WASMER_COMPILER_ENABLED) 880 | I64AtomicRmw16AndU, 881 | #endif 882 | #if defined(WASMER_COMPILER_ENABLED) 883 | I64AtomicRmw32AndU, 884 | #endif 885 | #if defined(WASMER_COMPILER_ENABLED) 886 | I32AtomicRmwOr, 887 | #endif 888 | #if defined(WASMER_COMPILER_ENABLED) 889 | I64AtomicRmwOr, 890 | #endif 891 | #if defined(WASMER_COMPILER_ENABLED) 892 | I32AtomicRmw8OrU, 893 | #endif 894 | #if defined(WASMER_COMPILER_ENABLED) 895 | I32AtomicRmw16OrU, 896 | #endif 897 | #if defined(WASMER_COMPILER_ENABLED) 898 | I64AtomicRmw8OrU, 899 | #endif 900 | #if defined(WASMER_COMPILER_ENABLED) 901 | I64AtomicRmw16OrU, 902 | #endif 903 | #if defined(WASMER_COMPILER_ENABLED) 904 | I64AtomicRmw32OrU, 905 | #endif 906 | #if defined(WASMER_COMPILER_ENABLED) 907 | I32AtomicRmwXor, 908 | #endif 909 | #if defined(WASMER_COMPILER_ENABLED) 910 | I64AtomicRmwXor, 911 | #endif 912 | #if defined(WASMER_COMPILER_ENABLED) 913 | I32AtomicRmw8XorU, 914 | #endif 915 | #if defined(WASMER_COMPILER_ENABLED) 916 | I32AtomicRmw16XorU, 917 | #endif 918 | #if defined(WASMER_COMPILER_ENABLED) 919 | I64AtomicRmw8XorU, 920 | #endif 921 | #if defined(WASMER_COMPILER_ENABLED) 922 | I64AtomicRmw16XorU, 923 | #endif 924 | #if defined(WASMER_COMPILER_ENABLED) 925 | I64AtomicRmw32XorU, 926 | #endif 927 | #if defined(WASMER_COMPILER_ENABLED) 928 | I32AtomicRmwXchg, 929 | #endif 930 | #if defined(WASMER_COMPILER_ENABLED) 931 | I64AtomicRmwXchg, 932 | #endif 933 | #if defined(WASMER_COMPILER_ENABLED) 934 | I32AtomicRmw8XchgU, 935 | #endif 936 | #if defined(WASMER_COMPILER_ENABLED) 937 | I32AtomicRmw16XchgU, 938 | #endif 939 | #if defined(WASMER_COMPILER_ENABLED) 940 | I64AtomicRmw8XchgU, 941 | #endif 942 | #if defined(WASMER_COMPILER_ENABLED) 943 | I64AtomicRmw16XchgU, 944 | #endif 945 | #if defined(WASMER_COMPILER_ENABLED) 946 | I64AtomicRmw32XchgU, 947 | #endif 948 | #if defined(WASMER_COMPILER_ENABLED) 949 | I32AtomicRmwCmpxchg, 950 | #endif 951 | #if defined(WASMER_COMPILER_ENABLED) 952 | I64AtomicRmwCmpxchg, 953 | #endif 954 | #if defined(WASMER_COMPILER_ENABLED) 955 | I32AtomicRmw8CmpxchgU, 956 | #endif 957 | #if defined(WASMER_COMPILER_ENABLED) 958 | I32AtomicRmw16CmpxchgU, 959 | #endif 960 | #if defined(WASMER_COMPILER_ENABLED) 961 | I64AtomicRmw8CmpxchgU, 962 | #endif 963 | #if defined(WASMER_COMPILER_ENABLED) 964 | I64AtomicRmw16CmpxchgU, 965 | #endif 966 | #if defined(WASMER_COMPILER_ENABLED) 967 | I64AtomicRmw32CmpxchgU, 968 | #endif 969 | #if defined(WASMER_COMPILER_ENABLED) 970 | V128Load, 971 | #endif 972 | #if defined(WASMER_COMPILER_ENABLED) 973 | V128Store, 974 | #endif 975 | #if defined(WASMER_COMPILER_ENABLED) 976 | V128Const, 977 | #endif 978 | #if defined(WASMER_COMPILER_ENABLED) 979 | I8x16Splat, 980 | #endif 981 | #if defined(WASMER_COMPILER_ENABLED) 982 | I8x16ExtractLaneS, 983 | #endif 984 | #if defined(WASMER_COMPILER_ENABLED) 985 | I8x16ExtractLaneU, 986 | #endif 987 | #if defined(WASMER_COMPILER_ENABLED) 988 | I8x16ReplaceLane, 989 | #endif 990 | #if defined(WASMER_COMPILER_ENABLED) 991 | I16x8Splat, 992 | #endif 993 | #if defined(WASMER_COMPILER_ENABLED) 994 | I16x8ExtractLaneS, 995 | #endif 996 | #if defined(WASMER_COMPILER_ENABLED) 997 | I16x8ExtractLaneU, 998 | #endif 999 | #if defined(WASMER_COMPILER_ENABLED) 1000 | I16x8ReplaceLane, 1001 | #endif 1002 | #if defined(WASMER_COMPILER_ENABLED) 1003 | I32x4Splat, 1004 | #endif 1005 | #if defined(WASMER_COMPILER_ENABLED) 1006 | I32x4ExtractLane, 1007 | #endif 1008 | #if defined(WASMER_COMPILER_ENABLED) 1009 | I32x4ReplaceLane, 1010 | #endif 1011 | #if defined(WASMER_COMPILER_ENABLED) 1012 | I64x2Splat, 1013 | #endif 1014 | #if defined(WASMER_COMPILER_ENABLED) 1015 | I64x2ExtractLane, 1016 | #endif 1017 | #if defined(WASMER_COMPILER_ENABLED) 1018 | I64x2ReplaceLane, 1019 | #endif 1020 | #if defined(WASMER_COMPILER_ENABLED) 1021 | F32x4Splat, 1022 | #endif 1023 | #if defined(WASMER_COMPILER_ENABLED) 1024 | F32x4ExtractLane, 1025 | #endif 1026 | #if defined(WASMER_COMPILER_ENABLED) 1027 | F32x4ReplaceLane, 1028 | #endif 1029 | #if defined(WASMER_COMPILER_ENABLED) 1030 | F64x2Splat, 1031 | #endif 1032 | #if defined(WASMER_COMPILER_ENABLED) 1033 | F64x2ExtractLane, 1034 | #endif 1035 | #if defined(WASMER_COMPILER_ENABLED) 1036 | F64x2ReplaceLane, 1037 | #endif 1038 | #if defined(WASMER_COMPILER_ENABLED) 1039 | I8x16Eq, 1040 | #endif 1041 | #if defined(WASMER_COMPILER_ENABLED) 1042 | I8x16Ne, 1043 | #endif 1044 | #if defined(WASMER_COMPILER_ENABLED) 1045 | I8x16LtS, 1046 | #endif 1047 | #if defined(WASMER_COMPILER_ENABLED) 1048 | I8x16LtU, 1049 | #endif 1050 | #if defined(WASMER_COMPILER_ENABLED) 1051 | I8x16GtS, 1052 | #endif 1053 | #if defined(WASMER_COMPILER_ENABLED) 1054 | I8x16GtU, 1055 | #endif 1056 | #if defined(WASMER_COMPILER_ENABLED) 1057 | I8x16LeS, 1058 | #endif 1059 | #if defined(WASMER_COMPILER_ENABLED) 1060 | I8x16LeU, 1061 | #endif 1062 | #if defined(WASMER_COMPILER_ENABLED) 1063 | I8x16GeS, 1064 | #endif 1065 | #if defined(WASMER_COMPILER_ENABLED) 1066 | I8x16GeU, 1067 | #endif 1068 | #if defined(WASMER_COMPILER_ENABLED) 1069 | I16x8Eq, 1070 | #endif 1071 | #if defined(WASMER_COMPILER_ENABLED) 1072 | I16x8Ne, 1073 | #endif 1074 | #if defined(WASMER_COMPILER_ENABLED) 1075 | I16x8LtS, 1076 | #endif 1077 | #if defined(WASMER_COMPILER_ENABLED) 1078 | I16x8LtU, 1079 | #endif 1080 | #if defined(WASMER_COMPILER_ENABLED) 1081 | I16x8GtS, 1082 | #endif 1083 | #if defined(WASMER_COMPILER_ENABLED) 1084 | I16x8GtU, 1085 | #endif 1086 | #if defined(WASMER_COMPILER_ENABLED) 1087 | I16x8LeS, 1088 | #endif 1089 | #if defined(WASMER_COMPILER_ENABLED) 1090 | I16x8LeU, 1091 | #endif 1092 | #if defined(WASMER_COMPILER_ENABLED) 1093 | I16x8GeS, 1094 | #endif 1095 | #if defined(WASMER_COMPILER_ENABLED) 1096 | I16x8GeU, 1097 | #endif 1098 | #if defined(WASMER_COMPILER_ENABLED) 1099 | I32x4Eq, 1100 | #endif 1101 | #if defined(WASMER_COMPILER_ENABLED) 1102 | I32x4Ne, 1103 | #endif 1104 | #if defined(WASMER_COMPILER_ENABLED) 1105 | I32x4LtS, 1106 | #endif 1107 | #if defined(WASMER_COMPILER_ENABLED) 1108 | I32x4LtU, 1109 | #endif 1110 | #if defined(WASMER_COMPILER_ENABLED) 1111 | I32x4GtS, 1112 | #endif 1113 | #if defined(WASMER_COMPILER_ENABLED) 1114 | I32x4GtU, 1115 | #endif 1116 | #if defined(WASMER_COMPILER_ENABLED) 1117 | I32x4LeS, 1118 | #endif 1119 | #if defined(WASMER_COMPILER_ENABLED) 1120 | I32x4LeU, 1121 | #endif 1122 | #if defined(WASMER_COMPILER_ENABLED) 1123 | I32x4GeS, 1124 | #endif 1125 | #if defined(WASMER_COMPILER_ENABLED) 1126 | I32x4GeU, 1127 | #endif 1128 | #if defined(WASMER_COMPILER_ENABLED) 1129 | I64x2Eq, 1130 | #endif 1131 | #if defined(WASMER_COMPILER_ENABLED) 1132 | I64x2Ne, 1133 | #endif 1134 | #if defined(WASMER_COMPILER_ENABLED) 1135 | I64x2LtS, 1136 | #endif 1137 | #if defined(WASMER_COMPILER_ENABLED) 1138 | I64x2GtS, 1139 | #endif 1140 | #if defined(WASMER_COMPILER_ENABLED) 1141 | I64x2LeS, 1142 | #endif 1143 | #if defined(WASMER_COMPILER_ENABLED) 1144 | I64x2GeS, 1145 | #endif 1146 | #if defined(WASMER_COMPILER_ENABLED) 1147 | F32x4Eq, 1148 | #endif 1149 | #if defined(WASMER_COMPILER_ENABLED) 1150 | F32x4Ne, 1151 | #endif 1152 | #if defined(WASMER_COMPILER_ENABLED) 1153 | F32x4Lt, 1154 | #endif 1155 | #if defined(WASMER_COMPILER_ENABLED) 1156 | F32x4Gt, 1157 | #endif 1158 | #if defined(WASMER_COMPILER_ENABLED) 1159 | F32x4Le, 1160 | #endif 1161 | #if defined(WASMER_COMPILER_ENABLED) 1162 | F32x4Ge, 1163 | #endif 1164 | #if defined(WASMER_COMPILER_ENABLED) 1165 | F64x2Eq, 1166 | #endif 1167 | #if defined(WASMER_COMPILER_ENABLED) 1168 | F64x2Ne, 1169 | #endif 1170 | #if defined(WASMER_COMPILER_ENABLED) 1171 | F64x2Lt, 1172 | #endif 1173 | #if defined(WASMER_COMPILER_ENABLED) 1174 | F64x2Gt, 1175 | #endif 1176 | #if defined(WASMER_COMPILER_ENABLED) 1177 | F64x2Le, 1178 | #endif 1179 | #if defined(WASMER_COMPILER_ENABLED) 1180 | F64x2Ge, 1181 | #endif 1182 | #if defined(WASMER_COMPILER_ENABLED) 1183 | V128Not, 1184 | #endif 1185 | #if defined(WASMER_COMPILER_ENABLED) 1186 | V128And, 1187 | #endif 1188 | #if defined(WASMER_COMPILER_ENABLED) 1189 | V128AndNot, 1190 | #endif 1191 | #if defined(WASMER_COMPILER_ENABLED) 1192 | V128Or, 1193 | #endif 1194 | #if defined(WASMER_COMPILER_ENABLED) 1195 | V128Xor, 1196 | #endif 1197 | #if defined(WASMER_COMPILER_ENABLED) 1198 | V128Bitselect, 1199 | #endif 1200 | #if defined(WASMER_COMPILER_ENABLED) 1201 | V128AnyTrue, 1202 | #endif 1203 | #if defined(WASMER_COMPILER_ENABLED) 1204 | I8x16Abs, 1205 | #endif 1206 | #if defined(WASMER_COMPILER_ENABLED) 1207 | I8x16Neg, 1208 | #endif 1209 | #if defined(WASMER_COMPILER_ENABLED) 1210 | I8x16AllTrue, 1211 | #endif 1212 | #if defined(WASMER_COMPILER_ENABLED) 1213 | I8x16Bitmask, 1214 | #endif 1215 | #if defined(WASMER_COMPILER_ENABLED) 1216 | I8x16Shl, 1217 | #endif 1218 | #if defined(WASMER_COMPILER_ENABLED) 1219 | I8x16ShrS, 1220 | #endif 1221 | #if defined(WASMER_COMPILER_ENABLED) 1222 | I8x16ShrU, 1223 | #endif 1224 | #if defined(WASMER_COMPILER_ENABLED) 1225 | I8x16Add, 1226 | #endif 1227 | #if defined(WASMER_COMPILER_ENABLED) 1228 | I8x16AddSatS, 1229 | #endif 1230 | #if defined(WASMER_COMPILER_ENABLED) 1231 | I8x16AddSatU, 1232 | #endif 1233 | #if defined(WASMER_COMPILER_ENABLED) 1234 | I8x16Sub, 1235 | #endif 1236 | #if defined(WASMER_COMPILER_ENABLED) 1237 | I8x16SubSatS, 1238 | #endif 1239 | #if defined(WASMER_COMPILER_ENABLED) 1240 | I8x16SubSatU, 1241 | #endif 1242 | #if defined(WASMER_COMPILER_ENABLED) 1243 | I8x16MinS, 1244 | #endif 1245 | #if defined(WASMER_COMPILER_ENABLED) 1246 | I8x16MinU, 1247 | #endif 1248 | #if defined(WASMER_COMPILER_ENABLED) 1249 | I8x16MaxS, 1250 | #endif 1251 | #if defined(WASMER_COMPILER_ENABLED) 1252 | I8x16MaxU, 1253 | #endif 1254 | #if defined(WASMER_COMPILER_ENABLED) 1255 | I8x16Popcnt, 1256 | #endif 1257 | #if defined(WASMER_COMPILER_ENABLED) 1258 | I16x8Abs, 1259 | #endif 1260 | #if defined(WASMER_COMPILER_ENABLED) 1261 | I16x8Neg, 1262 | #endif 1263 | #if defined(WASMER_COMPILER_ENABLED) 1264 | I16x8AllTrue, 1265 | #endif 1266 | #if defined(WASMER_COMPILER_ENABLED) 1267 | I16x8Bitmask, 1268 | #endif 1269 | #if defined(WASMER_COMPILER_ENABLED) 1270 | I16x8Shl, 1271 | #endif 1272 | #if defined(WASMER_COMPILER_ENABLED) 1273 | I16x8ShrS, 1274 | #endif 1275 | #if defined(WASMER_COMPILER_ENABLED) 1276 | I16x8ShrU, 1277 | #endif 1278 | #if defined(WASMER_COMPILER_ENABLED) 1279 | I16x8Add, 1280 | #endif 1281 | #if defined(WASMER_COMPILER_ENABLED) 1282 | I16x8AddSatS, 1283 | #endif 1284 | #if defined(WASMER_COMPILER_ENABLED) 1285 | I16x8AddSatU, 1286 | #endif 1287 | #if defined(WASMER_COMPILER_ENABLED) 1288 | I16x8Sub, 1289 | #endif 1290 | #if defined(WASMER_COMPILER_ENABLED) 1291 | I16x8SubSatS, 1292 | #endif 1293 | #if defined(WASMER_COMPILER_ENABLED) 1294 | I16x8SubSatU, 1295 | #endif 1296 | #if defined(WASMER_COMPILER_ENABLED) 1297 | I16x8Mul, 1298 | #endif 1299 | #if defined(WASMER_COMPILER_ENABLED) 1300 | I16x8MinS, 1301 | #endif 1302 | #if defined(WASMER_COMPILER_ENABLED) 1303 | I16x8MinU, 1304 | #endif 1305 | #if defined(WASMER_COMPILER_ENABLED) 1306 | I16x8MaxS, 1307 | #endif 1308 | #if defined(WASMER_COMPILER_ENABLED) 1309 | I16x8MaxU, 1310 | #endif 1311 | #if defined(WASMER_COMPILER_ENABLED) 1312 | I16x8ExtAddPairwiseI8x16S, 1313 | #endif 1314 | #if defined(WASMER_COMPILER_ENABLED) 1315 | I16x8ExtAddPairwiseI8x16U, 1316 | #endif 1317 | #if defined(WASMER_COMPILER_ENABLED) 1318 | I32x4Abs, 1319 | #endif 1320 | #if defined(WASMER_COMPILER_ENABLED) 1321 | I32x4Neg, 1322 | #endif 1323 | #if defined(WASMER_COMPILER_ENABLED) 1324 | I32x4AllTrue, 1325 | #endif 1326 | #if defined(WASMER_COMPILER_ENABLED) 1327 | I32x4Bitmask, 1328 | #endif 1329 | #if defined(WASMER_COMPILER_ENABLED) 1330 | I32x4Shl, 1331 | #endif 1332 | #if defined(WASMER_COMPILER_ENABLED) 1333 | I32x4ShrS, 1334 | #endif 1335 | #if defined(WASMER_COMPILER_ENABLED) 1336 | I32x4ShrU, 1337 | #endif 1338 | #if defined(WASMER_COMPILER_ENABLED) 1339 | I32x4Add, 1340 | #endif 1341 | #if defined(WASMER_COMPILER_ENABLED) 1342 | I32x4Sub, 1343 | #endif 1344 | #if defined(WASMER_COMPILER_ENABLED) 1345 | I32x4Mul, 1346 | #endif 1347 | #if defined(WASMER_COMPILER_ENABLED) 1348 | I32x4MinS, 1349 | #endif 1350 | #if defined(WASMER_COMPILER_ENABLED) 1351 | I32x4MinU, 1352 | #endif 1353 | #if defined(WASMER_COMPILER_ENABLED) 1354 | I32x4MaxS, 1355 | #endif 1356 | #if defined(WASMER_COMPILER_ENABLED) 1357 | I32x4MaxU, 1358 | #endif 1359 | #if defined(WASMER_COMPILER_ENABLED) 1360 | I32x4DotI16x8S, 1361 | #endif 1362 | #if defined(WASMER_COMPILER_ENABLED) 1363 | I32x4ExtAddPairwiseI16x8S, 1364 | #endif 1365 | #if defined(WASMER_COMPILER_ENABLED) 1366 | I32x4ExtAddPairwiseI16x8U, 1367 | #endif 1368 | #if defined(WASMER_COMPILER_ENABLED) 1369 | I64x2Abs, 1370 | #endif 1371 | #if defined(WASMER_COMPILER_ENABLED) 1372 | I64x2Neg, 1373 | #endif 1374 | #if defined(WASMER_COMPILER_ENABLED) 1375 | I64x2AllTrue, 1376 | #endif 1377 | #if defined(WASMER_COMPILER_ENABLED) 1378 | I64x2Bitmask, 1379 | #endif 1380 | #if defined(WASMER_COMPILER_ENABLED) 1381 | I64x2Shl, 1382 | #endif 1383 | #if defined(WASMER_COMPILER_ENABLED) 1384 | I64x2ShrS, 1385 | #endif 1386 | #if defined(WASMER_COMPILER_ENABLED) 1387 | I64x2ShrU, 1388 | #endif 1389 | #if defined(WASMER_COMPILER_ENABLED) 1390 | I64x2Add, 1391 | #endif 1392 | #if defined(WASMER_COMPILER_ENABLED) 1393 | I64x2Sub, 1394 | #endif 1395 | #if defined(WASMER_COMPILER_ENABLED) 1396 | I64x2Mul, 1397 | #endif 1398 | #if defined(WASMER_COMPILER_ENABLED) 1399 | F32x4Ceil, 1400 | #endif 1401 | #if defined(WASMER_COMPILER_ENABLED) 1402 | F32x4Floor, 1403 | #endif 1404 | #if defined(WASMER_COMPILER_ENABLED) 1405 | F32x4Trunc, 1406 | #endif 1407 | #if defined(WASMER_COMPILER_ENABLED) 1408 | F32x4Nearest, 1409 | #endif 1410 | #if defined(WASMER_COMPILER_ENABLED) 1411 | F64x2Ceil, 1412 | #endif 1413 | #if defined(WASMER_COMPILER_ENABLED) 1414 | F64x2Floor, 1415 | #endif 1416 | #if defined(WASMER_COMPILER_ENABLED) 1417 | F64x2Trunc, 1418 | #endif 1419 | #if defined(WASMER_COMPILER_ENABLED) 1420 | F64x2Nearest, 1421 | #endif 1422 | #if defined(WASMER_COMPILER_ENABLED) 1423 | F32x4Abs, 1424 | #endif 1425 | #if defined(WASMER_COMPILER_ENABLED) 1426 | F32x4Neg, 1427 | #endif 1428 | #if defined(WASMER_COMPILER_ENABLED) 1429 | F32x4Sqrt, 1430 | #endif 1431 | #if defined(WASMER_COMPILER_ENABLED) 1432 | F32x4Add, 1433 | #endif 1434 | #if defined(WASMER_COMPILER_ENABLED) 1435 | F32x4Sub, 1436 | #endif 1437 | #if defined(WASMER_COMPILER_ENABLED) 1438 | F32x4Mul, 1439 | #endif 1440 | #if defined(WASMER_COMPILER_ENABLED) 1441 | F32x4Div, 1442 | #endif 1443 | #if defined(WASMER_COMPILER_ENABLED) 1444 | F32x4Min, 1445 | #endif 1446 | #if defined(WASMER_COMPILER_ENABLED) 1447 | F32x4Max, 1448 | #endif 1449 | #if defined(WASMER_COMPILER_ENABLED) 1450 | F32x4PMin, 1451 | #endif 1452 | #if defined(WASMER_COMPILER_ENABLED) 1453 | F32x4PMax, 1454 | #endif 1455 | #if defined(WASMER_COMPILER_ENABLED) 1456 | F64x2Abs, 1457 | #endif 1458 | #if defined(WASMER_COMPILER_ENABLED) 1459 | F64x2Neg, 1460 | #endif 1461 | #if defined(WASMER_COMPILER_ENABLED) 1462 | F64x2Sqrt, 1463 | #endif 1464 | #if defined(WASMER_COMPILER_ENABLED) 1465 | F64x2Add, 1466 | #endif 1467 | #if defined(WASMER_COMPILER_ENABLED) 1468 | F64x2Sub, 1469 | #endif 1470 | #if defined(WASMER_COMPILER_ENABLED) 1471 | F64x2Mul, 1472 | #endif 1473 | #if defined(WASMER_COMPILER_ENABLED) 1474 | F64x2Div, 1475 | #endif 1476 | #if defined(WASMER_COMPILER_ENABLED) 1477 | F64x2Min, 1478 | #endif 1479 | #if defined(WASMER_COMPILER_ENABLED) 1480 | F64x2Max, 1481 | #endif 1482 | #if defined(WASMER_COMPILER_ENABLED) 1483 | F64x2PMin, 1484 | #endif 1485 | #if defined(WASMER_COMPILER_ENABLED) 1486 | F64x2PMax, 1487 | #endif 1488 | #if defined(WASMER_COMPILER_ENABLED) 1489 | I32x4TruncSatF32x4S, 1490 | #endif 1491 | #if defined(WASMER_COMPILER_ENABLED) 1492 | I32x4TruncSatF32x4U, 1493 | #endif 1494 | #if defined(WASMER_COMPILER_ENABLED) 1495 | F32x4ConvertI32x4S, 1496 | #endif 1497 | #if defined(WASMER_COMPILER_ENABLED) 1498 | F32x4ConvertI32x4U, 1499 | #endif 1500 | #if defined(WASMER_COMPILER_ENABLED) 1501 | I8x16Swizzle, 1502 | #endif 1503 | #if defined(WASMER_COMPILER_ENABLED) 1504 | I8x16Shuffle, 1505 | #endif 1506 | #if defined(WASMER_COMPILER_ENABLED) 1507 | V128Load8Splat, 1508 | #endif 1509 | #if defined(WASMER_COMPILER_ENABLED) 1510 | V128Load16Splat, 1511 | #endif 1512 | #if defined(WASMER_COMPILER_ENABLED) 1513 | V128Load32Splat, 1514 | #endif 1515 | #if defined(WASMER_COMPILER_ENABLED) 1516 | V128Load32Zero, 1517 | #endif 1518 | #if defined(WASMER_COMPILER_ENABLED) 1519 | V128Load64Splat, 1520 | #endif 1521 | #if defined(WASMER_COMPILER_ENABLED) 1522 | V128Load64Zero, 1523 | #endif 1524 | #if defined(WASMER_COMPILER_ENABLED) 1525 | I8x16NarrowI16x8S, 1526 | #endif 1527 | #if defined(WASMER_COMPILER_ENABLED) 1528 | I8x16NarrowI16x8U, 1529 | #endif 1530 | #if defined(WASMER_COMPILER_ENABLED) 1531 | I16x8NarrowI32x4S, 1532 | #endif 1533 | #if defined(WASMER_COMPILER_ENABLED) 1534 | I16x8NarrowI32x4U, 1535 | #endif 1536 | #if defined(WASMER_COMPILER_ENABLED) 1537 | I16x8ExtendLowI8x16S, 1538 | #endif 1539 | #if defined(WASMER_COMPILER_ENABLED) 1540 | I16x8ExtendHighI8x16S, 1541 | #endif 1542 | #if defined(WASMER_COMPILER_ENABLED) 1543 | I16x8ExtendLowI8x16U, 1544 | #endif 1545 | #if defined(WASMER_COMPILER_ENABLED) 1546 | I16x8ExtendHighI8x16U, 1547 | #endif 1548 | #if defined(WASMER_COMPILER_ENABLED) 1549 | I32x4ExtendLowI16x8S, 1550 | #endif 1551 | #if defined(WASMER_COMPILER_ENABLED) 1552 | I32x4ExtendHighI16x8S, 1553 | #endif 1554 | #if defined(WASMER_COMPILER_ENABLED) 1555 | I32x4ExtendLowI16x8U, 1556 | #endif 1557 | #if defined(WASMER_COMPILER_ENABLED) 1558 | I32x4ExtendHighI16x8U, 1559 | #endif 1560 | #if defined(WASMER_COMPILER_ENABLED) 1561 | I64x2ExtendLowI32x4S, 1562 | #endif 1563 | #if defined(WASMER_COMPILER_ENABLED) 1564 | I64x2ExtendHighI32x4S, 1565 | #endif 1566 | #if defined(WASMER_COMPILER_ENABLED) 1567 | I64x2ExtendLowI32x4U, 1568 | #endif 1569 | #if defined(WASMER_COMPILER_ENABLED) 1570 | I64x2ExtendHighI32x4U, 1571 | #endif 1572 | #if defined(WASMER_COMPILER_ENABLED) 1573 | I16x8ExtMulLowI8x16S, 1574 | #endif 1575 | #if defined(WASMER_COMPILER_ENABLED) 1576 | I16x8ExtMulHighI8x16S, 1577 | #endif 1578 | #if defined(WASMER_COMPILER_ENABLED) 1579 | I16x8ExtMulLowI8x16U, 1580 | #endif 1581 | #if defined(WASMER_COMPILER_ENABLED) 1582 | I16x8ExtMulHighI8x16U, 1583 | #endif 1584 | #if defined(WASMER_COMPILER_ENABLED) 1585 | I32x4ExtMulLowI16x8S, 1586 | #endif 1587 | #if defined(WASMER_COMPILER_ENABLED) 1588 | I32x4ExtMulHighI16x8S, 1589 | #endif 1590 | #if defined(WASMER_COMPILER_ENABLED) 1591 | I32x4ExtMulLowI16x8U, 1592 | #endif 1593 | #if defined(WASMER_COMPILER_ENABLED) 1594 | I32x4ExtMulHighI16x8U, 1595 | #endif 1596 | #if defined(WASMER_COMPILER_ENABLED) 1597 | I64x2ExtMulLowI32x4S, 1598 | #endif 1599 | #if defined(WASMER_COMPILER_ENABLED) 1600 | I64x2ExtMulHighI32x4S, 1601 | #endif 1602 | #if defined(WASMER_COMPILER_ENABLED) 1603 | I64x2ExtMulLowI32x4U, 1604 | #endif 1605 | #if defined(WASMER_COMPILER_ENABLED) 1606 | I64x2ExtMulHighI32x4U, 1607 | #endif 1608 | #if defined(WASMER_COMPILER_ENABLED) 1609 | V128Load8x8S, 1610 | #endif 1611 | #if defined(WASMER_COMPILER_ENABLED) 1612 | V128Load8x8U, 1613 | #endif 1614 | #if defined(WASMER_COMPILER_ENABLED) 1615 | V128Load16x4S, 1616 | #endif 1617 | #if defined(WASMER_COMPILER_ENABLED) 1618 | V128Load16x4U, 1619 | #endif 1620 | #if defined(WASMER_COMPILER_ENABLED) 1621 | V128Load32x2S, 1622 | #endif 1623 | #if defined(WASMER_COMPILER_ENABLED) 1624 | V128Load32x2U, 1625 | #endif 1626 | #if defined(WASMER_COMPILER_ENABLED) 1627 | V128Load8Lane, 1628 | #endif 1629 | #if defined(WASMER_COMPILER_ENABLED) 1630 | V128Load16Lane, 1631 | #endif 1632 | #if defined(WASMER_COMPILER_ENABLED) 1633 | V128Load32Lane, 1634 | #endif 1635 | #if defined(WASMER_COMPILER_ENABLED) 1636 | V128Load64Lane, 1637 | #endif 1638 | #if defined(WASMER_COMPILER_ENABLED) 1639 | V128Store8Lane, 1640 | #endif 1641 | #if defined(WASMER_COMPILER_ENABLED) 1642 | V128Store16Lane, 1643 | #endif 1644 | #if defined(WASMER_COMPILER_ENABLED) 1645 | V128Store32Lane, 1646 | #endif 1647 | #if defined(WASMER_COMPILER_ENABLED) 1648 | V128Store64Lane, 1649 | #endif 1650 | #if defined(WASMER_COMPILER_ENABLED) 1651 | I8x16RoundingAverageU, 1652 | #endif 1653 | #if defined(WASMER_COMPILER_ENABLED) 1654 | I16x8RoundingAverageU, 1655 | #endif 1656 | #if defined(WASMER_COMPILER_ENABLED) 1657 | I16x8Q15MulrSatS, 1658 | #endif 1659 | #if defined(WASMER_COMPILER_ENABLED) 1660 | F32x4DemoteF64x2Zero, 1661 | #endif 1662 | #if defined(WASMER_COMPILER_ENABLED) 1663 | F64x2PromoteLowF32x4, 1664 | #endif 1665 | #if defined(WASMER_COMPILER_ENABLED) 1666 | F64x2ConvertLowI32x4S, 1667 | #endif 1668 | #if defined(WASMER_COMPILER_ENABLED) 1669 | F64x2ConvertLowI32x4U, 1670 | #endif 1671 | #if defined(WASMER_COMPILER_ENABLED) 1672 | I32x4TruncSatF64x2SZero, 1673 | #endif 1674 | #if defined(WASMER_COMPILER_ENABLED) 1675 | I32x4TruncSatF64x2UZero, 1676 | #endif 1677 | #if defined(WASMER_COMPILER_ENABLED) 1678 | I8x16RelaxedSwizzle, 1679 | #endif 1680 | #if defined(WASMER_COMPILER_ENABLED) 1681 | I32x4RelaxedTruncSatF32x4S, 1682 | #endif 1683 | #if defined(WASMER_COMPILER_ENABLED) 1684 | I32x4RelaxedTruncSatF32x4U, 1685 | #endif 1686 | #if defined(WASMER_COMPILER_ENABLED) 1687 | I32x4RelaxedTruncSatF64x2SZero, 1688 | #endif 1689 | #if defined(WASMER_COMPILER_ENABLED) 1690 | I32x4RelaxedTruncSatF64x2UZero, 1691 | #endif 1692 | #if defined(WASMER_COMPILER_ENABLED) 1693 | F32x4Fma, 1694 | #endif 1695 | #if defined(WASMER_COMPILER_ENABLED) 1696 | F32x4Fms, 1697 | #endif 1698 | #if defined(WASMER_COMPILER_ENABLED) 1699 | F64x2Fma, 1700 | #endif 1701 | #if defined(WASMER_COMPILER_ENABLED) 1702 | F64x2Fms, 1703 | #endif 1704 | #if defined(WASMER_COMPILER_ENABLED) 1705 | I8x16LaneSelect, 1706 | #endif 1707 | #if defined(WASMER_COMPILER_ENABLED) 1708 | I16x8LaneSelect, 1709 | #endif 1710 | #if defined(WASMER_COMPILER_ENABLED) 1711 | I32x4LaneSelect, 1712 | #endif 1713 | #if defined(WASMER_COMPILER_ENABLED) 1714 | I64x2LaneSelect, 1715 | #endif 1716 | #if defined(WASMER_COMPILER_ENABLED) 1717 | F32x4RelaxedMin, 1718 | #endif 1719 | #if defined(WASMER_COMPILER_ENABLED) 1720 | F32x4RelaxedMax, 1721 | #endif 1722 | #if defined(WASMER_COMPILER_ENABLED) 1723 | F64x2RelaxedMin, 1724 | #endif 1725 | #if defined(WASMER_COMPILER_ENABLED) 1726 | F64x2RelaxedMax, 1727 | #endif 1728 | #if defined(WASMER_COMPILER_ENABLED) 1729 | I16x8RelaxedQ15mulrS, 1730 | #endif 1731 | #if defined(WASMER_COMPILER_ENABLED) 1732 | I16x8DotI8x16I7x16S, 1733 | #endif 1734 | #if defined(WASMER_COMPILER_ENABLED) 1735 | I32x4DotI8x16I7x16AddS, 1736 | #endif 1737 | #if defined(WASMER_COMPILER_ENABLED) 1738 | F32x4RelaxedDotBf16x8AddF32x4, 1739 | #endif 1740 | } wasmer_parser_operator_t; 1741 | #endif 1742 | 1743 | #if defined(WASMER_WASI_ENABLED) 1744 | typedef struct wasi_config_t wasi_config_t; 1745 | #endif 1746 | 1747 | #if defined(WASMER_WASI_ENABLED) 1748 | typedef struct wasi_env_t wasi_env_t; 1749 | #endif 1750 | 1751 | typedef struct wasmer_cpu_features_t wasmer_cpu_features_t; 1752 | 1753 | typedef struct wasmer_features_t wasmer_features_t; 1754 | 1755 | typedef struct wasmer_metering_t wasmer_metering_t; 1756 | 1757 | typedef struct wasmer_middleware_t wasmer_middleware_t; 1758 | 1759 | #if defined(WASMER_WASI_ENABLED) 1760 | typedef struct wasmer_named_extern_t wasmer_named_extern_t; 1761 | #endif 1762 | 1763 | typedef struct wasmer_target_t wasmer_target_t; 1764 | 1765 | typedef struct wasmer_triple_t wasmer_triple_t; 1766 | 1767 | #if defined(WASMER_WASI_ENABLED) 1768 | typedef struct wasi_filesystem_t { 1769 | const char *ptr; 1770 | uintptr_t size; 1771 | } wasi_filesystem_t; 1772 | #endif 1773 | 1774 | #if defined(WASMER_WASI_ENABLED) 1775 | typedef struct wasmer_named_extern_vec_t { 1776 | uintptr_t size; 1777 | struct wasmer_named_extern_t **data; 1778 | } wasmer_named_extern_vec_t; 1779 | #endif 1780 | 1781 | typedef struct FunctionCEnv { 1782 | void *inner; 1783 | } FunctionCEnv; 1784 | 1785 | typedef struct wasmer_funcenv_t { 1786 | struct FunctionCEnv inner; 1787 | } wasmer_funcenv_t; 1788 | 1789 | typedef uint64_t (*wasmer_metering_cost_function_t)(enum wasmer_parser_operator_t wasm_operator); 1790 | 1791 | #ifdef __cplusplus 1792 | extern "C" { 1793 | #endif // __cplusplus 1794 | 1795 | #if defined(WASMER_WASI_ENABLED) 1796 | void wasi_config_arg(struct wasi_config_t *config, const char *arg); 1797 | #endif 1798 | 1799 | #if defined(WASMER_WASI_ENABLED) 1800 | void wasi_config_capture_stderr(struct wasi_config_t *config); 1801 | #endif 1802 | 1803 | #if defined(WASMER_WASI_ENABLED) 1804 | void wasi_config_capture_stdout(struct wasi_config_t *config); 1805 | #endif 1806 | 1807 | #if defined(WASMER_WASI_ENABLED) 1808 | void wasi_config_env(struct wasi_config_t *config, const char *key, const char *value); 1809 | #endif 1810 | 1811 | #if defined(WASMER_WASI_ENABLED) 1812 | void wasi_config_inherit_stderr(struct wasi_config_t *config); 1813 | #endif 1814 | 1815 | #if defined(WASMER_WASI_ENABLED) 1816 | void wasi_config_inherit_stdin(struct wasi_config_t *config); 1817 | #endif 1818 | 1819 | #if defined(WASMER_WASI_ENABLED) 1820 | void wasi_config_inherit_stdout(struct wasi_config_t *config); 1821 | #endif 1822 | 1823 | #if defined(WASMER_WASI_ENABLED) 1824 | bool wasi_config_mapdir(struct wasi_config_t *config, const char *alias, const char *dir); 1825 | #endif 1826 | 1827 | #if defined(WASMER_WASI_ENABLED) 1828 | struct wasi_config_t *wasi_config_new(const char *program_name); 1829 | #endif 1830 | 1831 | #if defined(WASMER_WASI_ENABLED) 1832 | bool wasi_config_preopen_dir(struct wasi_config_t *config, const char *dir); 1833 | #endif 1834 | 1835 | #if defined(WASMER_WASI_ENABLED) 1836 | void wasi_env_delete(struct wasi_env_t *state); 1837 | #endif 1838 | 1839 | #if defined(WASMER_WASI_ENABLED) 1840 | bool wasi_env_initialize_instance(struct wasi_env_t *wasi_env, 1841 | wasm_store_t *store, 1842 | wasm_instance_t *instance); 1843 | #endif 1844 | 1845 | #if defined(WASMER_WASI_ENABLED) 1846 | struct wasi_env_t *wasi_env_new(wasm_store_t *store, struct wasi_config_t *config); 1847 | #endif 1848 | 1849 | #if defined(WASMER_WASI_ENABLED) 1850 | intptr_t wasi_env_read_stderr(struct wasi_env_t *env, char *buffer, uintptr_t buffer_len); 1851 | #endif 1852 | 1853 | #if defined(WASMER_WASI_ENABLED) 1854 | intptr_t wasi_env_read_stdout(struct wasi_env_t *env, char *buffer, uintptr_t buffer_len); 1855 | #endif 1856 | 1857 | #if defined(WASMER_WASI_ENABLED) 1858 | void wasi_env_set_memory(struct wasi_env_t *_env, const wasm_memory_t *_memory); 1859 | #endif 1860 | 1861 | #if defined(WASMER_WASI_ENABLED) 1862 | struct wasi_env_t *wasi_env_with_filesystem(struct wasi_config_t *config, 1863 | wasm_store_t *store, 1864 | const wasm_module_t *module, 1865 | const struct wasi_filesystem_t *fs, 1866 | wasm_extern_vec_t *imports, 1867 | const char *package); 1868 | #endif 1869 | 1870 | #if defined(WASMER_WASI_ENABLED) 1871 | void wasi_filesystem_delete(struct wasi_filesystem_t *ptr); 1872 | #endif 1873 | 1874 | #if defined(WASMER_WASI_ENABLED) 1875 | struct wasi_filesystem_t *wasi_filesystem_init_static_memory(const wasm_byte_vec_t *volume_bytes); 1876 | #endif 1877 | 1878 | #if defined(WASMER_WASI_ENABLED) 1879 | bool wasi_get_imports(const wasm_store_t *_store, 1880 | struct wasi_env_t *wasi_env, 1881 | const wasm_module_t *module, 1882 | wasm_extern_vec_t *imports); 1883 | #endif 1884 | 1885 | #if defined(WASMER_WASI_ENABLED) 1886 | wasm_func_t *wasi_get_start_function(wasm_instance_t *instance); 1887 | #endif 1888 | 1889 | #if defined(WASMER_WASI_ENABLED) 1890 | bool wasi_get_unordered_imports(struct wasi_env_t *wasi_env, 1891 | const wasm_module_t *module, 1892 | struct wasmer_named_extern_vec_t *imports); 1893 | #endif 1894 | 1895 | #if defined(WASMER_WASI_ENABLED) 1896 | enum wasi_version_t wasi_get_wasi_version(const wasm_module_t *module); 1897 | #endif 1898 | 1899 | void wasm_config_canonicalize_nans(wasm_config_t *config, bool enable); 1900 | 1901 | void wasm_config_push_middleware(wasm_config_t *config, struct wasmer_middleware_t *middleware); 1902 | 1903 | #if defined(WASMER_COMPILER_ENABLED) 1904 | void wasm_config_set_compiler(wasm_config_t *config, enum wasmer_compiler_t compiler); 1905 | #endif 1906 | 1907 | void wasm_config_set_engine(wasm_config_t *config, enum wasmer_engine_t engine); 1908 | 1909 | void wasm_config_set_features(wasm_config_t *config, struct wasmer_features_t *features); 1910 | 1911 | void wasm_config_set_target(wasm_config_t *config, struct wasmer_target_t *target); 1912 | 1913 | bool wasmer_cpu_features_add(struct wasmer_cpu_features_t *cpu_features, 1914 | const wasm_name_t *feature); 1915 | 1916 | void wasmer_cpu_features_delete(struct wasmer_cpu_features_t *_cpu_features); 1917 | 1918 | struct wasmer_cpu_features_t *wasmer_cpu_features_new(void); 1919 | 1920 | bool wasmer_features_bulk_memory(struct wasmer_features_t *features, bool enable); 1921 | 1922 | void wasmer_features_delete(struct wasmer_features_t *_features); 1923 | 1924 | bool wasmer_features_memory64(struct wasmer_features_t *features, bool enable); 1925 | 1926 | bool wasmer_features_module_linking(struct wasmer_features_t *features, bool enable); 1927 | 1928 | bool wasmer_features_multi_memory(struct wasmer_features_t *features, bool enable); 1929 | 1930 | bool wasmer_features_multi_value(struct wasmer_features_t *features, bool enable); 1931 | 1932 | struct wasmer_features_t *wasmer_features_new(void); 1933 | 1934 | bool wasmer_features_reference_types(struct wasmer_features_t *features, bool enable); 1935 | 1936 | bool wasmer_features_simd(struct wasmer_features_t *features, bool enable); 1937 | 1938 | bool wasmer_features_tail_call(struct wasmer_features_t *features, bool enable); 1939 | 1940 | bool wasmer_features_threads(struct wasmer_features_t *features, bool enable); 1941 | 1942 | void wasmer_funcenv_delete(struct wasmer_funcenv_t *_funcenv); 1943 | 1944 | struct wasmer_funcenv_t *wasmer_funcenv_new(wasm_store_t *store, void *data); 1945 | 1946 | #if defined(WASMER_COMPILER_ENABLED) 1947 | bool wasmer_is_compiler_available(enum wasmer_compiler_t compiler); 1948 | #endif 1949 | 1950 | bool wasmer_is_engine_available(enum wasmer_engine_t engine); 1951 | 1952 | bool wasmer_is_headless(void); 1953 | 1954 | int wasmer_last_error_length(void); 1955 | 1956 | int wasmer_last_error_message(char *buffer, int length); 1957 | 1958 | struct wasmer_middleware_t *wasmer_metering_as_middleware(struct wasmer_metering_t *metering); 1959 | 1960 | void wasmer_metering_delete(struct wasmer_metering_t *_metering); 1961 | 1962 | uint64_t wasmer_metering_get_remaining_points(wasm_instance_t *instance); 1963 | 1964 | struct wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit, 1965 | wasmer_metering_cost_function_t cost_function); 1966 | 1967 | bool wasmer_metering_points_are_exhausted(wasm_instance_t *instance); 1968 | 1969 | void wasmer_metering_set_remaining_points(wasm_instance_t *instance, uint64_t new_limit); 1970 | 1971 | void wasmer_module_name(const wasm_module_t *module, wasm_name_t *out); 1972 | 1973 | wasm_module_t *wasmer_module_new(wasm_engine_t *engine, const wasm_byte_vec_t *bytes); 1974 | 1975 | bool wasmer_module_set_name(wasm_module_t *module, const wasm_name_t *name); 1976 | 1977 | #if defined(WASMER_WASI_ENABLED) 1978 | const wasm_name_t *wasmer_named_extern_module(const struct wasmer_named_extern_t *named_extern); 1979 | #endif 1980 | 1981 | #if defined(WASMER_WASI_ENABLED) 1982 | const wasm_name_t *wasmer_named_extern_name(const struct wasmer_named_extern_t *named_extern); 1983 | #endif 1984 | 1985 | #if defined(WASMER_WASI_ENABLED) 1986 | const wasm_extern_t *wasmer_named_extern_unwrap(const struct wasmer_named_extern_t *named_extern); 1987 | #endif 1988 | 1989 | #if defined(WASMER_WASI_ENABLED) 1990 | void wasmer_named_extern_vec_copy(struct wasmer_named_extern_vec_t *out_ptr, 1991 | const struct wasmer_named_extern_vec_t *in_ptr); 1992 | #endif 1993 | 1994 | #if defined(WASMER_WASI_ENABLED) 1995 | void wasmer_named_extern_vec_delete(struct wasmer_named_extern_vec_t *ptr); 1996 | #endif 1997 | 1998 | #if defined(WASMER_WASI_ENABLED) 1999 | void wasmer_named_extern_vec_new(struct wasmer_named_extern_vec_t *out, 2000 | uintptr_t length, 2001 | struct wasmer_named_extern_t *const *init); 2002 | #endif 2003 | 2004 | #if defined(WASMER_WASI_ENABLED) 2005 | void wasmer_named_extern_vec_new_empty(struct wasmer_named_extern_vec_t *out); 2006 | #endif 2007 | 2008 | #if defined(WASMER_WASI_ENABLED) 2009 | void wasmer_named_extern_vec_new_uninitialized(struct wasmer_named_extern_vec_t *out, 2010 | uintptr_t length); 2011 | #endif 2012 | 2013 | void wasmer_target_delete(struct wasmer_target_t *_target); 2014 | 2015 | struct wasmer_target_t *wasmer_target_new(struct wasmer_triple_t *triple, 2016 | struct wasmer_cpu_features_t *cpu_features); 2017 | 2018 | void wasmer_triple_delete(struct wasmer_triple_t *_triple); 2019 | 2020 | struct wasmer_triple_t *wasmer_triple_new(const wasm_name_t *triple); 2021 | 2022 | struct wasmer_triple_t *wasmer_triple_new_from_host(void); 2023 | 2024 | const char *wasmer_version(void); 2025 | 2026 | uint8_t wasmer_version_major(void); 2027 | 2028 | uint8_t wasmer_version_minor(void); 2029 | 2030 | uint8_t wasmer_version_patch(void); 2031 | 2032 | const char *wasmer_version_pre(void); 2033 | 2034 | void wat2wasm(const wasm_byte_vec_t *wat, wasm_byte_vec_t *out); 2035 | 2036 | #ifdef __cplusplus 2037 | } // extern "C" 2038 | #endif // __cplusplus 2039 | 2040 | #endif /* WASMER_H */ 2041 | -------------------------------------------------------------------------------- /src/wasi.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const wasm = @import("./wasm.zig"); 3 | 4 | /// Custom error set for WASI operations 5 | pub const WasiError = error{ 6 | ConfigInit, 7 | PreopenDirFailed, 8 | MapDirFailed, 9 | EnvInit, 10 | ReadStdoutFailed, 11 | ReadStderrFailed, 12 | InitializeInstanceFailed, 13 | GetImportsFailed, 14 | StartFunctionNotFound, 15 | }; 16 | 17 | /// Opaque type representing WASI configuration 18 | pub const WasiConfig = opaque { 19 | /// Options to inherit when inheriting configs 20 | const InheritOptions = struct { 21 | argv: bool = true, 22 | env: bool = true, 23 | std_in: bool = true, 24 | std_out: bool = true, 25 | std_err: bool = true, 26 | }; 27 | 28 | /// Initialize a new WASI configuration 29 | pub fn init() !*WasiConfig { 30 | return wasi_config_new() orelse WasiError.ConfigInit; 31 | } 32 | 33 | /// Clean up WASI configuration 34 | /// The `wasi_env_new` function takes the ownership of the wasm_config_t 35 | /// https://github.com/wasmerio/wasmer/issues/2468 36 | pub fn deinit(self: *WasiConfig) void { 37 | _ = self; 38 | @compileError("not implemented in wasmer"); 39 | } 40 | 41 | /// Inherit native environment settings 42 | pub fn inherit(self: *WasiConfig, options: InheritOptions) void { 43 | if (options.argv) self.inheritArgv(); 44 | if (options.env) self.inheritEnv(); 45 | if (options.std_in) self.inheritStdIn(); 46 | if (options.std_out) self.inheritStdOut(); 47 | if (options.std_err) self.inheritStdErr(); 48 | } 49 | 50 | pub fn inheritArgv(self: *WasiConfig) void { 51 | wasi_config_inherit_argv(self); 52 | } 53 | 54 | pub fn inheritEnv(self: *WasiConfig) void { 55 | wasi_config_inherit_env(self); 56 | } 57 | 58 | pub fn inheritStdIn(self: *WasiConfig) void { 59 | wasi_config_inherit_stdin(self); 60 | } 61 | 62 | pub fn inheritStdOut(self: *WasiConfig) void { 63 | wasi_config_inherit_stdout(self); 64 | } 65 | 66 | pub fn inheritStdErr(self: *WasiConfig) void { 67 | wasi_config_inherit_stderr(self); 68 | } 69 | 70 | /// Set a command-line argument 71 | pub fn setArg(self: *WasiConfig, arg: []const u8) void { 72 | wasi_config_arg(self, arg.ptr); 73 | } 74 | 75 | /// Set an environment variable 76 | pub fn setEnv(self: *WasiConfig, key: []const u8, value: []const u8) void { 77 | wasi_config_env(self, key.ptr, value.ptr); 78 | } 79 | 80 | /// Pre-open a directory 81 | pub fn preopenDir(self: *WasiConfig, dir: []const u8) !void { 82 | if (!wasi_config_preopen_dir(self, dir.ptr)) { 83 | return WasiError.PreopenDirFailed; 84 | } 85 | } 86 | 87 | /// Map a directory 88 | pub fn mapDir(self: *WasiConfig, alias: []const u8, dir: []const u8) !void { 89 | if (!wasi_config_mapdir(self, alias.ptr, dir.ptr)) { 90 | return WasiError.MapDirFailed; 91 | } 92 | } 93 | 94 | /// Capture stdout 95 | pub fn captureStdout(self: *WasiConfig) void { 96 | wasi_config_capture_stdout(self); 97 | } 98 | 99 | /// Capture stderr 100 | pub fn captureStderr(self: *WasiConfig) void { 101 | wasi_config_capture_stderr(self); 102 | } 103 | 104 | // External C function declarations 105 | extern "c" fn wasi_config_new() ?*WasiConfig; 106 | extern "c" fn wasi_config_delete(?*WasiConfig) void; 107 | extern "c" fn wasi_config_inherit_argv(?*WasiConfig) void; 108 | extern "c" fn wasi_config_inherit_env(?*WasiConfig) void; 109 | extern "c" fn wasi_config_inherit_stdin(?*WasiConfig) void; 110 | extern "c" fn wasi_config_inherit_stdout(?*WasiConfig) void; 111 | extern "c" fn wasi_config_inherit_stderr(?*WasiConfig) void; 112 | extern "c" fn wasi_config_arg(?*WasiConfig, [*]const u8) void; 113 | extern "c" fn wasi_config_env(?*WasiConfig, [*]const u8, [*]const u8) void; 114 | extern "c" fn wasi_config_preopen_dir(?*WasiConfig, [*]const u8) bool; 115 | extern "c" fn wasi_config_mapdir(?*WasiConfig, [*]const u8, [*]const u8) bool; 116 | extern "c" fn wasi_config_capture_stdout(?*WasiConfig) void; 117 | extern "c" fn wasi_config_capture_stderr(?*WasiConfig) void; 118 | }; 119 | 120 | /// Opaque type representing WASI environment 121 | pub const WasiEnv = opaque { 122 | /// Initialize a new WASI environment 123 | pub fn init(store: *wasm.Store, config: *WasiConfig) !*WasiEnv { 124 | return wasi_env_new(store, config) orelse WasiError.EnvInit; 125 | } 126 | 127 | /// Clean up WASI environment 128 | pub fn deinit(self: *WasiEnv) void { 129 | wasi_env_delete(self); 130 | } 131 | 132 | /// Read from captured stdout 133 | pub fn readStdout(self: *WasiEnv, buffer: []u8) !usize { 134 | const result = wasi_env_read_stdout(self, buffer.ptr, buffer.len); 135 | return if (result >= 0) @as(usize, @intCast(result)) else WasiError.ReadStdoutFailed; 136 | } 137 | 138 | /// Read from captured stderr 139 | pub fn readStderr(self: *WasiEnv, buffer: []u8) !usize { 140 | const result = wasi_env_read_stderr(self, buffer.ptr, buffer.len); 141 | return if (result >= 0) @as(usize, @intCast(result)) else WasiError.ReadStderrFailed; 142 | } 143 | 144 | /// Initialize a WASI instance 145 | pub fn initializeInstance(self: *WasiEnv, store: *wasm.Store, instance: *wasm.Instance) !void { 146 | if (!wasi_env_initialize_instance(self, store, instance)) { 147 | return WasiError.InitializeInstanceFailed; 148 | } 149 | } 150 | 151 | // External C function declarations 152 | extern "c" fn wasi_env_new(?*wasm.Store, ?*WasiConfig) ?*WasiEnv; 153 | extern "c" fn wasi_env_delete(?*WasiEnv) void; 154 | extern "c" fn wasi_env_read_stdout(?*WasiEnv, [*]u8, usize) isize; 155 | extern "c" fn wasi_env_read_stderr(?*WasiEnv, [*]u8, usize) isize; 156 | extern "c" fn wasi_env_initialize_instance(?*WasiEnv, ?*wasm.Store, ?*wasm.Instance) bool; 157 | }; 158 | 159 | /// Enum representing different WASI versions 160 | pub const WasiVersion = enum(c_int) { 161 | InvalidVersion = -1, 162 | Latest = 0, 163 | Snapshot0 = 1, 164 | Snapshot1 = 2, 165 | Wasix32v1 = 3, 166 | Wasix64v1 = 4, 167 | }; 168 | 169 | /// Get the WASI version of a module 170 | pub fn getWasiVersion(module: *wasm.Module) WasiVersion { 171 | return @enumFromInt(wasi_get_wasi_version(module)); 172 | } 173 | 174 | /// Get WASI imports for a module 175 | pub fn getImports(store: *wasm.Store, wasi_env: *WasiEnv, module: *wasm.Module) !wasm.ExternVec { 176 | var imports = wasm.ExternVec.empty(); 177 | if (!wasi_get_imports(store, wasi_env, module, &imports)) { 178 | return WasiError.GetImportsFailed; 179 | } 180 | return imports; 181 | } 182 | 183 | /// Get the start function of a WASI module 184 | pub fn getStartFunction(instance: *wasm.Instance) !*wasm.Func { 185 | return wasi_get_start_function(instance) orelse WasiError.StartFunctionNotFound; 186 | } 187 | 188 | // External C function declarations 189 | extern "c" fn wasi_get_wasi_version(?*wasm.Module) c_int; 190 | extern "c" fn wasi_get_imports(?*wasm.Store, ?*WasiEnv, ?*wasm.Module, ?*wasm.ExternVec) bool; 191 | extern "c" fn wasi_get_start_function(?*wasm.Instance) ?*wasm.Func; 192 | -------------------------------------------------------------------------------- /src/wasm.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const testing = std.testing; 3 | const meta = std.meta; 4 | const trait = std.meta.trait; 5 | const log = std.log.scoped(.wasm_zig); 6 | 7 | var CALLBACK: usize = undefined; 8 | 9 | // @TODO: Split these up into own error sets 10 | pub const Error = error{ 11 | /// Failed to initialize a `Config` 12 | ConfigInit, 13 | /// Failed to initialize an `Engine` (i.e. invalid config) 14 | EngineInit, 15 | /// Failed to initialize a `Store` 16 | StoreInit, 17 | /// Failed to initialize a `Module` 18 | ModuleInit, 19 | /// Failed to create a wasm function based on 20 | /// the given `Store` and functype 21 | FuncInit, 22 | /// Failed to initialize a new `Instance` 23 | InstanceInit, 24 | }; 25 | 26 | pub const Config = opaque { 27 | pub fn init() !*Config { 28 | const config = wasm_config_new() orelse return Error.ConfigInit; 29 | return config; 30 | } 31 | 32 | extern "c" fn wasm_config_new() ?*Config; 33 | }; 34 | 35 | pub const Engine = opaque { 36 | /// Initializes a new `Engine` 37 | pub fn init() !*Engine { 38 | return wasm_engine_new() orelse Error.EngineInit; 39 | } 40 | 41 | pub fn withConfig(config: *Config) !*Engine { 42 | return wasm_engine_new_with_config(config) orelse Error.EngineInit; 43 | } 44 | 45 | /// Frees the resources of the `Engine` 46 | pub fn deinit(self: *Engine) void { 47 | wasm_engine_delete(self); 48 | } 49 | 50 | extern "c" fn wasm_engine_new() ?*Engine; 51 | extern "c" fn wasm_engine_new_with_config(*Config) ?*Engine; 52 | extern "c" fn wasm_engine_delete(*Engine) void; 53 | }; 54 | 55 | pub const Store = opaque { 56 | /// Initializes a new `Store` based on the given `Engine` 57 | pub fn init(engine: *Engine) !*Store { 58 | return wasm_store_new(engine) orelse Error.StoreInit; 59 | } 60 | 61 | /// Frees the resource of the `Store` itself 62 | pub fn deinit(self: *Store) void { 63 | wasm_store_delete(self); 64 | } 65 | 66 | extern "c" fn wasm_store_new(*Engine) ?*Store; 67 | extern "c" fn wasm_store_delete(*Store) void; 68 | }; 69 | 70 | pub const Module = opaque { 71 | /// Initializes a new `Module` using the supplied Store and wasm bytecode 72 | pub fn init(store: *Store, bytes: []const u8) !*Module { 73 | var byte_vec = ByteVec.initWithCapacity(bytes.len); 74 | defer byte_vec.deinit(); 75 | 76 | var ptr = byte_vec.data; 77 | var i: usize = 0; 78 | while (i < bytes.len) : (i += 1) { 79 | ptr[i] = bytes[i]; 80 | } 81 | 82 | return wasm_module_new(store, &byte_vec) orelse return Error.ModuleInit; 83 | } 84 | 85 | pub fn deinit(self: *Module) void { 86 | wasm_module_delete(self); 87 | } 88 | 89 | /// Returns a list of export types in `ExportTypeVec` 90 | pub fn exports(self: *Module) ExportTypeVec { 91 | var vec: ExportTypeVec = undefined; 92 | wasm_module_exports(self, &vec); 93 | return vec; 94 | } 95 | 96 | extern "c" fn wasm_module_new(*Store, *const ByteVec) ?*Module; 97 | extern "c" fn wasm_module_delete(*Module) void; 98 | extern "c" fn wasm_module_exports(?*const Module, *ExportTypeVec) void; 99 | }; 100 | 101 | fn cb(params: ?*const Valtype, results: ?*Valtype) callconv(.C) ?*Trap { 102 | _ = params; 103 | _ = results; 104 | const func = @as(*const fn () void, @ptrFromInt(CALLBACK)); 105 | func(); 106 | return null; 107 | } 108 | 109 | pub const Func = opaque { 110 | pub const CallError = error{ 111 | /// Failed to call the function 112 | /// and resulted into an error 113 | InnerError, 114 | /// When the user provided a different ResultType to `Func.call` 115 | /// than what is defined by the wasm binary 116 | InvalidResultType, 117 | /// The given argument count to `Func.call` mismatches that 118 | /// of the func argument count of the wasm binary 119 | InvalidParamCount, 120 | /// The wasm function number of results mismatch that of the given 121 | /// ResultType to `Func.Call`. Note that `void` equals to 0 result types. 122 | InvalidResultCount, 123 | /// Function call resulted in an unexpected trap. 124 | Trap, 125 | }; 126 | pub fn init(store: *Store, callback: anytype) !*Func { 127 | const cb_meta = @typeInfo(@TypeOf(callback)); 128 | switch (cb_meta) { 129 | .@"fn" => { 130 | if (cb_meta.@"fn".params.len > 0 or cb_meta.@"fn".return_type.? != void) { 131 | @compileError("only callbacks with no input args and no results are currently supported"); 132 | } 133 | }, 134 | else => @compileError("only functions can be used as callbacks into Wasm"), 135 | } 136 | 137 | const func_ptr: *const fn () void = @ptrCast(&callback); 138 | 139 | CALLBACK = @intFromPtr(func_ptr); 140 | 141 | var args = ValtypeVec.empty(); 142 | var results = ValtypeVec.empty(); 143 | 144 | const functype = wasm_functype_new(&args, &results) orelse return Error.FuncInit; 145 | defer wasm_functype_delete(functype); 146 | 147 | return wasm_func_new(store, functype, cb) orelse Error.FuncInit; 148 | } 149 | 150 | /// Returns the `Func` as an `Extern` 151 | /// 152 | /// Owned by `self` and shouldn't be deinitialized 153 | pub fn asExtern(self: *Func) *Extern { 154 | return wasm_func_as_extern(self).?; 155 | } 156 | 157 | /// Returns the `Func` from an `Extern` 158 | /// return null if extern's type isn't a functype 159 | /// 160 | /// Owned by `extern_func` and shouldn't be deinitialized 161 | pub fn fromExtern(extern_func: *Extern) ?*Func { 162 | return extern_func.asFunc(); 163 | } 164 | 165 | /// Creates a copy of the current `Func` 166 | /// returned copy is owned by the caller and must be freed 167 | /// by the owner 168 | pub fn copy(self: *Func) *Func { 169 | return self.wasm_func_copy().?; 170 | } 171 | 172 | // /// Tries to call the wasm function 173 | // /// expects `args` to be tuple of arguments 174 | // pub fn call(self: *Func, comptime ResultType: type, args: anytype) CallError!ResultType { 175 | // // if (!comptime trait.isTuple(@TypeOf(args))) 176 | // // TODO: remove it 177 | // if (!comptime @typeInfo(@TypeOf(args)).@"struct".is_tuple) 178 | // @compileError("Expected 'args' to be a tuple, but found type '" ++ @typeName(@TypeOf(args)) ++ "'"); 179 | 180 | // const args_len = args.len; 181 | // comptime var wasm_args: [args_len]Value = undefined; 182 | // inline for (&wasm_args, 0..) |*arg, i| { 183 | // arg.* = switch (@TypeOf(args[i])) { 184 | // i32, u32 => .{ .kind = .i32, .of = .{ .i32 = @as(i32, @bitCast(args[i])) } }, 185 | // i64, u64 => .{ .kind = .i64, .of = .{ .i64 = @as(i64, @bitCast(args[i])) } }, 186 | // f32 => .{ .kind = .f32, .of = .{ .f32 = args[i] } }, 187 | // f64 => .{ .kind = .f64, .of = .{ .f64 = args[i] } }, 188 | // *Func => .{ .kind = .funcref, .of = .{ .ref = args[i] } }, 189 | // *Extern => .{ .kind = .anyref, .of = .{ .ref = args[i] } }, 190 | // else => |ty| @compileError("Unsupported argument type '" ++ @typeName(ty) + "'"), 191 | // }; 192 | // } 193 | 194 | // // TODO multiple return values 195 | // const result_len: usize = if (ResultType == void) 0 else 1; 196 | // if (result_len != wasm_func_result_arity(self)) return CallError.InvalidResultCount; 197 | // if (args_len != wasm_func_param_arity(self)) return CallError.InvalidParamCount; 198 | 199 | // const final_args = ValVec{ 200 | // .size = args_len, 201 | // .data = if (args_len == 0) undefined else @as([*]Value, @ptrCast(&wasm_args)), 202 | // }; 203 | 204 | // var result_list = ValVec.initWithCapacity(result_len); 205 | // defer result_list.deinit(); 206 | 207 | // const trap = wasm_func_call(self, &final_args, &result_list); 208 | 209 | // if (trap) |t| { 210 | // t.deinit(); 211 | // // TODO handle trap message 212 | // log.err("code unexpectedly trapped", .{}); 213 | // return CallError.Trap; 214 | // } 215 | 216 | // if (ResultType == void) return; 217 | 218 | // // TODO: Handle multiple returns 219 | // const result_ty = result_list.data[0]; 220 | // if (!matchesKind(ResultType, result_ty.kind)) return CallError.InvalidResultType; 221 | 222 | // return switch (ResultType) { 223 | // i32, u32 => @as(ResultType, @intCast(result_ty.of.i32)), 224 | // i64, u64 => @as(ResultType, @intCast(result_ty.of.i64)), 225 | // f32 => result_ty.of.f32, 226 | // f64 => result_ty.of.f64, 227 | // *Func => @as(?*Func, @ptrCast(result_ty.of.ref)).?, 228 | // *Extern => @as(?*Extern, @ptrCast(result_ty.of.ref)).?, 229 | // else => |ty| @compileError("Unsupported result type '" ++ @typeName(ty) ++ "'"), 230 | // }; 231 | // } 232 | 233 | pub fn call(self: *Func, comptime ResultType: type, args: anytype) CallError!ResultType { 234 | if (!comptime @typeInfo(@TypeOf(args)).@"struct".is_tuple) 235 | @compileError("Expected 'args' to be a tuple, but found type '" ++ @typeName(@TypeOf(args)) ++ "'"); 236 | 237 | const args_len = args.len; 238 | var wasm_args: [args_len]Value = undefined; // Remove 'comptime' from here 239 | 240 | inline for (&wasm_args, 0..) |*arg, i| { 241 | arg.* = switch (@TypeOf(args[i])) { 242 | i32, u32 => .{ .kind = .i32, .of = .{ .i32 = @as(i32, @bitCast(args[i])) } }, 243 | i64, u64 => .{ .kind = .i64, .of = .{ .i64 = @as(i64, @bitCast(args[i])) } }, 244 | f32 => .{ .kind = .f32, .of = .{ .f32 = args[i] } }, 245 | f64 => .{ .kind = .f64, .of = .{ .f64 = args[i] } }, 246 | *Func => .{ .kind = .funcref, .of = .{ .ref = args[i] } }, 247 | *Extern => .{ .kind = .anyref, .of = .{ .ref = args[i] } }, 248 | else => |ty| @compileError("Unsupported argument type '" ++ @typeName(ty) ++ "'"), 249 | }; 250 | } 251 | 252 | const result_len: usize = if (ResultType == void) 0 else 1; 253 | if (result_len != wasm_func_result_arity(self)) return CallError.InvalidResultCount; 254 | if (args_len != wasm_func_param_arity(self)) return CallError.InvalidParamCount; 255 | 256 | const final_args = ValVec{ 257 | .size = args_len, 258 | .data = if (args_len == 0) undefined else &wasm_args, // Remove @as and @ptrCast 259 | }; 260 | 261 | var result_list = ValVec.initWithCapacity(result_len); 262 | defer result_list.deinit(); 263 | 264 | const trap = wasm_func_call(self, &final_args, &result_list); 265 | 266 | if (trap) |t| { 267 | t.deinit(); 268 | // TODO handle trap message 269 | log.err("code unexpectedly trapped", .{}); 270 | return CallError.Trap; 271 | } 272 | 273 | if (ResultType == void) return; 274 | 275 | // TODO: Handle multiple returns 276 | const result_ty = result_list.data[0]; 277 | if (!matchesKind(ResultType, result_ty.kind)) return CallError.InvalidResultType; 278 | 279 | return switch (ResultType) { 280 | i32, u32 => @as(ResultType, @intCast(result_ty.of.i32)), 281 | i64, u64 => @as(ResultType, @intCast(result_ty.of.i64)), 282 | f32 => result_ty.of.f32, 283 | f64 => result_ty.of.f64, 284 | *Func => @as(?*Func, @ptrCast(result_ty.of.ref)).?, 285 | *Extern => @as(?*Extern, @ptrCast(result_ty.of.ref)).?, 286 | else => |ty| @compileError("Unsupported result type '" ++ @typeName(ty) ++ "'"), 287 | }; 288 | } 289 | 290 | pub fn deinit(self: *Func) void { 291 | wasm_func_delete(self); 292 | } 293 | 294 | /// Returns true if the given `kind` of `Valkind` can coerce to type `T` 295 | pub fn matchesKind(comptime T: type, kind: Valkind) bool { 296 | return switch (T) { 297 | i32, u32 => kind == .i32, 298 | i64, u64 => kind == .i64, 299 | f32 => kind == .f32, 300 | f64 => kind == .f64, 301 | *Func => kind == .funcref, 302 | *Extern => kind == .ref, 303 | else => false, 304 | }; 305 | } 306 | 307 | extern "c" fn wasm_func_new(*Store, ?*anyopaque, *const Callback) ?*Func; 308 | extern "c" fn wasm_func_delete(*Func) void; 309 | extern "c" fn wasm_func_as_extern(*Func) ?*Extern; 310 | extern "c" fn wasm_func_copy(*const Func) ?*Func; 311 | extern "c" fn wasm_func_call(*Func, *const ValVec, *ValVec) ?*Trap; 312 | extern "c" fn wasm_func_result_arity(*Func) usize; 313 | extern "c" fn wasm_func_param_arity(*Func) usize; 314 | }; 315 | 316 | pub const Instance = opaque { 317 | /// Initializes a new `Instance` using the given `store` and `mode`. 318 | /// The given slice defined in `import` must match what was initialized 319 | /// using the same `Store` as given. 320 | pub fn init(store: *Store, module: *Module, import: []const *Func) !*Instance { 321 | var trap: ?*Trap = null; 322 | var imports = ExternVec.initWithCapacity(import.len); 323 | defer imports.deinit(); 324 | 325 | var ptr = imports.data; 326 | var i: usize = 0; 327 | while (i < import.len) : (i += 1) { 328 | ptr[i] = import[i].asExtern(); 329 | } 330 | 331 | const instance = wasm_instance_new(store, module, &imports, &trap); 332 | 333 | if (trap) |t| { 334 | defer t.deinit(); 335 | // TODO handle trap message 336 | log.err("code unexpectedly trapped", .{}); 337 | return Error.InstanceInit; 338 | } 339 | 340 | return instance orelse Error.InstanceInit; 341 | } 342 | 343 | pub fn initFromImports(store: *Store, module: *Module, imports: *ExternVec) !*Instance { 344 | var trap: ?*Trap = null; 345 | 346 | const instance = wasm_instance_new(store, module, imports, &trap); 347 | 348 | if (trap) |t| { 349 | defer t.deinit(); 350 | // TODO handle trap message 351 | log.err("code unexpectedly trapped", .{}); 352 | return Error.InstanceInit; 353 | } 354 | 355 | return instance orelse Error.InstanceInit; 356 | } 357 | 358 | /// Returns an export func by its name if found 359 | /// Asserts the export is of type `Func` 360 | /// The returned `Func` is a copy and must be freed by the caller 361 | pub fn getExportFunc(self: *Instance, module: *Module, name: []const u8) ?*Func { 362 | return if (self.getExport(module, name)) |exp| { 363 | defer exp.deinit(); // free the copy 364 | return exp.asFunc().copy(); 365 | } else null; 366 | } 367 | 368 | /// Returns an export by its name and `null` when not found 369 | /// The `Extern` is copied and must be freed manually 370 | /// 371 | /// a `Module` must be provided to find an extern by its name, rather than index. 372 | /// use getExportByIndex for quick access to an extern by index. 373 | pub fn getExport(self: *Instance, module: *Module, name: []const u8) ?*Extern { 374 | var externs: ExternVec = undefined; 375 | wasm_instance_exports(self, &externs); 376 | defer externs.deinit(); 377 | 378 | var exports = module.exports(); 379 | defer exports.deinit(); 380 | 381 | return for (exports.toSlice(), 0..) |export_type, index| { 382 | const ty = export_type orelse continue; 383 | const type_name = ty.name(); 384 | defer type_name.deinit(); 385 | 386 | if (std.mem.eql(u8, name, type_name.toSlice())) { 387 | if (externs.data[index]) |ext| { 388 | break ext.copy(); 389 | } 390 | } 391 | } else null; 392 | } 393 | 394 | /// Returns an export by a given index. Returns null when the index 395 | /// is out of bounds. The extern is non-owned, meaning it's illegal 396 | /// behaviour to free its memory. 397 | pub fn getExportByIndex(self: *Instance, index: u32) ?*Extern { 398 | var externs: ExternVec = undefined; 399 | wasm_instance_exports(self, &externs); 400 | defer externs.deinit(); 401 | 402 | if (index > externs.size) return null; 403 | return externs.data[index].?; 404 | } 405 | 406 | /// Returns an exported `Memory` when found and `null` when not. 407 | /// The result is copied and must be freed manually by calling `deinit()` on the result. 408 | pub fn getExportMem(self: *Instance, module: *Module, name: []const u8) ?*Memory { 409 | return if (self.getExport(module, name)) |exp| { 410 | defer exp.deinit(); // free the copy 411 | return exp.asMemory().copy(); 412 | } else null; 413 | } 414 | 415 | /// Frees the `Instance`'s resources 416 | pub fn deinit(self: *Instance) void { 417 | wasm_instance_delete(self); 418 | } 419 | 420 | extern "c" fn wasm_instance_new(*Store, *const Module, *const ExternVec, *?*Trap) ?*Instance; 421 | extern "c" fn wasm_instance_delete(*Instance) void; 422 | extern "c" fn wasm_instance_exports(*Instance, *ExternVec) void; 423 | }; 424 | 425 | pub const Trap = opaque { 426 | pub fn deinit(self: *Trap) void { 427 | wasm_trap_delete(self); 428 | } 429 | 430 | /// Returns the trap message. 431 | /// Memory of the returned `ByteVec` must be freed using `deinit` 432 | pub fn message(self: *Trap) *ByteVec { 433 | var bytes: ?*ByteVec = null; 434 | wasm_trap_message(self, &bytes); 435 | return bytes.?; 436 | } 437 | 438 | extern "c" fn wasm_trap_delete(*Trap) void; 439 | extern "c" fn wasm_trap_message(*const Trap, out: *?*ByteVec) void; 440 | }; 441 | 442 | pub const Extern = opaque { 443 | /// Returns the `Extern` as a function 444 | /// returns `null` when the given `Extern` is not a function 445 | /// 446 | /// Asserts `Extern` is of type `Func` 447 | pub fn asFunc(self: *Extern) *Func { 448 | return wasm_extern_as_func(self).?; 449 | } 450 | 451 | /// Returns the `Extern` as a `Memory` object 452 | /// returns `null` when the given `Extern` is not a memory object 453 | /// 454 | /// Asserts `Extern` is of type `Memory` 455 | pub fn asMemory(self: *Extern) *Memory { 456 | return wasm_extern_as_memory(self).?; 457 | } 458 | 459 | /// Returns the `Extern` as a `Global` 460 | /// returns `null` when the given `Extern` is not a global 461 | /// 462 | /// Asserts `Extern` is of type `Global` 463 | pub fn asGlobal(self: *Extern) *Global { 464 | return wasm_extern_as_global(self).?; 465 | } 466 | 467 | /// Returns the `Extern` as a `Table` 468 | /// returns `null` when the given `Extern` is not a table 469 | /// 470 | /// Asserts `Extern` is of type `Table` 471 | pub fn asTable(self: *Extern) *Table { 472 | return wasm_extern_as_table(self).?; 473 | } 474 | 475 | /// Frees the memory of the `Extern` 476 | pub fn deinit(self: *Extern) void { 477 | wasm_extern_delete(self); 478 | } 479 | 480 | /// Creates a copy of the `Extern` and returns it 481 | /// Memory of the copied version must be freed manually by calling `deinit` 482 | /// 483 | /// Asserts the copy succeeds 484 | pub fn copy(self: *Extern) *Extern { 485 | return wasm_extern_copy(self).?; 486 | } 487 | 488 | /// Checks if the given externs are equal and returns true if so 489 | pub fn eql(self: *const Extern, other: *const Extern) bool { 490 | return wasm_extern_same(self, other); 491 | } 492 | 493 | /// Returns the type of an `Extern` as `ExternType` 494 | pub fn toType(self: *const Extern) *ExternType { 495 | return wasm_extern_type(self).?; 496 | } 497 | 498 | /// Returns the kind of an `Extern` 499 | pub fn kind(self: *const Extern) ExternKind { 500 | return wasm_extern_kind(self); 501 | } 502 | 503 | extern "c" fn wasm_extern_as_func(*Extern) ?*Func; 504 | extern "c" fn wasm_extern_as_memory(*Extern) ?*Memory; 505 | extern "c" fn wasm_extern_as_global(*Extern) ?*Global; 506 | extern "c" fn wasm_extern_as_table(*Extern) ?*Table; 507 | extern "c" fn wasm_extern_delete(*Extern) void; 508 | extern "c" fn wasm_extern_copy(*Extern) ?*Extern; 509 | extern "c" fn wasm_extern_same(*const Extern, *const Extern) bool; 510 | extern "c" fn wasm_extern_type(?*const Extern) ?*ExternType; 511 | extern "c" fn wasm_extern_kind(?*const Extern) ExternKind; 512 | }; 513 | 514 | pub const ExternKind = std.wasm.ExternalKind; 515 | 516 | pub const ExternType = opaque { 517 | /// Creates an `ExternType` from an existing `Extern` 518 | pub fn fromExtern(extern_object: *const Extern) *ExternType { 519 | return Extern.wasm_extern_type(extern_object).?; 520 | } 521 | 522 | /// Frees the memory of given `ExternType` 523 | pub fn deinit(self: *ExternType) void { 524 | wasm_externtype_delete(self); 525 | } 526 | 527 | /// Copies the given export type. Returned copy's memory must be 528 | /// freed manually by calling `deinit()` on the object. 529 | pub fn copy(self: *ExportType) *ExportType { 530 | return wasm_externtype_copy(self).?; 531 | } 532 | 533 | /// Returns the `ExternKind` from a given export type. 534 | pub fn kind(self: *const ExportType) ExternKind { 535 | return wasm_externtype_kind(self); 536 | } 537 | 538 | extern "c" fn wasm_externtype_delete(?*ExportType) void; 539 | extern "c" fn wasm_externtype_copy(?*ExportType) ?*ExportType; 540 | extern "c" fn wasm_externtype_kind(?*const ExternType) ExternKind; 541 | }; 542 | 543 | pub const Memory = opaque { 544 | /// Creates a new `Memory` object for the given `Store` and `MemoryType` 545 | pub fn init(store: *Store, mem_type: *const MemoryType) !*Memory { 546 | return wasm_memory_new(store, mem_type) orelse error.MemoryInit; 547 | } 548 | 549 | /// Returns the `MemoryType` of a given `Memory` object 550 | pub fn getType(self: *const Memory) *MemoryType { 551 | return wasm_memory_type(self).?; 552 | } 553 | 554 | /// Frees the memory of the `Memory` object 555 | pub fn deinit(self: *Memory) void { 556 | wasm_memory_delete(self); 557 | } 558 | 559 | /// Creates a copy of the given `Memory` object 560 | /// Returned copy must be freed manually. 561 | pub fn copy(self: *const Memory) ?*Memory { 562 | return wasm_memory_copy(self); 563 | } 564 | 565 | /// Returns true when the given `Memory` objects are equal 566 | pub fn eql(self: *const Memory, other: *const Memory) bool { 567 | return wasm_memory_same(self, other); 568 | } 569 | 570 | /// Returns a pointer-to-many bytes 571 | /// 572 | /// Tip: Use toSlice() to get a slice for better ergonomics 573 | pub fn data(self: *Memory) [*]u8 { 574 | return wasm_memory_data(self); 575 | } 576 | 577 | /// Returns the data size of the `Memory` object. 578 | pub fn size(self: *const Memory) usize { 579 | return wasm_memory_data_size(self); 580 | } 581 | 582 | /// Returns the amount of pages the `Memory` object consists of 583 | /// where each page is 65536 bytes 584 | pub fn pages(self: *const Memory) u32 { 585 | return wasm_memory_size(self); 586 | } 587 | 588 | /// Convenient helper function to represent the memory 589 | /// as a slice of bytes. Memory is however still owned by wasm 590 | /// and must be freed by calling `deinit` on the original `Memory` object 591 | pub fn toSlice(self: *Memory) []const u8 { 592 | var slice: []const u8 = undefined; 593 | slice.ptr = self.data(); 594 | slice.len = self.size(); 595 | return slice; 596 | } 597 | 598 | /// Increases the amount of memory pages by the given count. 599 | pub fn grow(self: *Memory, page_count: u32) error{OutOfMemory}!void { 600 | if (!wasm_memory_grow(self, page_count)) return error.OutOfMemory; 601 | } 602 | 603 | extern "c" fn wasm_memory_delete(*Memory) void; 604 | extern "c" fn wasm_memory_copy(*const Memory) ?*Memory; 605 | extern "c" fn wasm_memory_same(*const Memory, *const Memory) bool; 606 | extern "c" fn wasm_memory_new(*Store, *const MemoryType) ?*Memory; 607 | extern "c" fn wasm_memory_type(*const Memory) *MemoryType; 608 | extern "c" fn wasm_memory_data(*Memory) [*]u8; 609 | extern "c" fn wasm_memory_data_size(*const Memory) usize; 610 | extern "c" fn wasm_memory_grow(*Memory, delta: u32) bool; 611 | extern "c" fn wasm_memory_size(*const Memory) u32; 612 | }; 613 | 614 | pub const Limits = extern struct { 615 | min: u32, 616 | max: u32, 617 | }; 618 | 619 | pub const MemoryType = opaque { 620 | pub fn init(limits: Limits) !*MemoryType { 621 | return wasm_memorytype_new(&limits) orelse return error.InitMemoryType; 622 | } 623 | 624 | pub fn deinit(self: *MemoryType) void { 625 | wasm_memorytype_delete(self); 626 | } 627 | 628 | extern "c" fn wasm_memorytype_new(*const Limits) ?*MemoryType; 629 | extern "c" fn wasm_memorytype_delete(*MemoryType) void; 630 | }; 631 | 632 | // TODO: implement table and global types 633 | pub const Table = opaque {}; 634 | pub const Global = opaque {}; 635 | 636 | pub const ExportType = opaque { 637 | /// Returns the name of the given `ExportType` 638 | pub fn name(self: *ExportType) *ByteVec { 639 | return self.wasm_exporttype_name().?; 640 | } 641 | 642 | extern "c" fn wasm_exporttype_name(*ExportType) ?*ByteVec; 643 | }; 644 | 645 | pub const ExportTypeVec = extern struct { 646 | size: usize, 647 | data: [*]?*ExportType, 648 | 649 | /// Returns a slice of an `ExportTypeVec`. 650 | /// Memory is still owned by the runtime and can only be freed using 651 | /// `deinit()` on the original `ExportTypeVec` 652 | pub fn toSlice(self: *const ExportTypeVec) []const ?*ExportType { 653 | return self.data[0..self.size]; 654 | } 655 | 656 | pub fn deinit(self: *ExportTypeVec) void { 657 | self.wasm_exporttype_vec_delete(); 658 | } 659 | 660 | extern "c" fn wasm_exporttype_vec_delete(*ExportTypeVec) void; 661 | }; 662 | 663 | pub const Callback = fn (?*const Valtype, ?*Valtype) callconv(.C) ?*Trap; 664 | 665 | pub const ByteVec = extern struct { 666 | size: usize, 667 | data: [*]u8, 668 | 669 | /// Initializes a new wasm byte vector 670 | pub fn initWithCapacity(size: usize) ByteVec { 671 | var bytes: ByteVec = undefined; 672 | wasm_byte_vec_new_uninitialized(&bytes, size); 673 | return bytes; 674 | } 675 | 676 | /// Initializes and copies contents of the input slice 677 | pub fn fromSlice(slice: []const u8) ByteVec { 678 | var bytes: ByteVec = undefined; 679 | wasm_byte_vec_new(&bytes, slice.len, slice.ptr); 680 | return bytes; 681 | } 682 | 683 | /// Returns a slice to the byte vector 684 | pub fn toSlice(self: ByteVec) []const u8 { 685 | return self.data[0..self.size]; 686 | } 687 | 688 | /// Frees the memory allocated by initWithCapacity 689 | pub fn deinit(self: *ByteVec) void { 690 | wasm_byte_vec_delete(self); 691 | } 692 | 693 | extern "c" fn wasm_byte_vec_new(*ByteVec, usize, [*]const u8) void; 694 | extern "c" fn wasm_byte_vec_new_uninitialized(*ByteVec, usize) void; 695 | extern "c" fn wasm_byte_vec_delete(*ByteVec) void; 696 | }; 697 | 698 | pub const NameVec = extern struct { 699 | size: usize, 700 | data: [*]const u8, 701 | 702 | pub fn fromSlice(slice: []const u8) NameVec { 703 | return .{ .size = slice.len, .data = slice.ptr }; 704 | } 705 | }; 706 | 707 | pub const ExternVec = extern struct { 708 | size: usize, 709 | data: [*]?*Extern, 710 | 711 | pub fn empty() ExternVec { 712 | return .{ .size = 0, .data = undefined }; 713 | } 714 | 715 | pub fn deinit(self: *ExternVec) void { 716 | wasm_extern_vec_delete(self); 717 | } 718 | 719 | pub fn initWithCapacity(size: usize) ExternVec { 720 | var externs: ExternVec = undefined; 721 | wasm_extern_vec_new_uninitialized(&externs, size); 722 | return externs; 723 | } 724 | 725 | extern "c" fn wasm_extern_vec_new_empty(*ExternVec) void; 726 | extern "c" fn wasm_extern_vec_new_uninitialized(*ExternVec, usize) void; 727 | extern "c" fn wasm_extern_vec_delete(*ExternVec) void; 728 | }; 729 | 730 | pub const Valkind = enum(u8) { 731 | i32 = 0, 732 | i64 = 1, 733 | f32 = 2, 734 | f64 = 3, 735 | anyref = 128, 736 | funcref = 129, 737 | }; 738 | 739 | pub const Value = extern struct { 740 | kind: Valkind, 741 | of: extern union { 742 | i32: i32, 743 | i64: i64, 744 | f32: f32, 745 | f64: f64, 746 | ref: ?*anyopaque, 747 | }, 748 | }; 749 | 750 | pub const Valtype = opaque { 751 | /// Initializes a new `Valtype` based on the given `Valkind` 752 | pub fn init(valKind: Valkind) *Valtype { 753 | return wasm_valtype_new(@intFromEnum(valKind)); 754 | } 755 | 756 | pub fn deinit(self: *Valtype) void { 757 | wasm_valtype_delete(self); 758 | } 759 | 760 | /// Returns the `Valkind` of the given `Valtype` 761 | pub fn kind(self: *Valtype) Valkind { 762 | return @as(Valkind, @enumFromInt(wasm_valtype_kind(self))); 763 | } 764 | 765 | extern "c" fn wasm_valtype_new(kind: u8) *Valtype; 766 | extern "c" fn wasm_valtype_delete(*Valkind) void; 767 | extern "c" fn wasm_valtype_kind(*Valkind) u8; 768 | }; 769 | 770 | pub const ValtypeVec = extern struct { 771 | size: usize, 772 | data: [*]?*Valtype, 773 | 774 | pub fn empty() ValtypeVec { 775 | return .{ .size = 0, .data = undefined }; 776 | } 777 | }; 778 | 779 | pub const ValVec = extern struct { 780 | size: usize, 781 | data: [*]Value, 782 | 783 | pub fn initWithCapacity(size: usize) ValVec { 784 | var bytes: ValVec = undefined; 785 | wasm_val_vec_new_uninitialized(&bytes, size); 786 | return bytes; 787 | } 788 | 789 | pub fn deinit(self: *ValVec) void { 790 | self.wasm_val_vec_delete(); 791 | } 792 | 793 | extern "c" fn wasm_val_vec_new_uninitialized(*ValVec, usize) void; 794 | extern "c" fn wasm_val_vec_delete(*ValVec) void; 795 | }; 796 | 797 | // Func 798 | pub extern "c" fn wasm_functype_new(args: *ValtypeVec, results: *ValtypeVec) ?*anyopaque; 799 | pub extern "c" fn wasm_functype_delete(functype: *anyopaque) void; 800 | 801 | test "run_tests" { 802 | testing.refAllDecls(@This()); 803 | } 804 | -------------------------------------------------------------------------------- /src/wasmer.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | pub const wasm = @import("./wasm.zig"); 4 | 5 | pub usingnamespace @import("./wasi.zig"); 6 | 7 | // Re-exports 8 | pub const ExternVec = wasm.ExternVec; 9 | pub const ByteVec = wasm.ByteVec; 10 | pub const Engine = wasm.Engine; 11 | pub const Store = wasm.Store; 12 | pub const Module = wasm.Module; 13 | pub const Instance = wasm.Instance; 14 | pub const Extern = wasm.Extern; 15 | pub const Func = wasm.Func; 16 | pub const Memory = wasm.Memory; 17 | pub const MemoryType = wasm.MemoryType; 18 | pub const Limits = wasm.Limits; 19 | 20 | const OS_PATH_MAX: usize = switch (builtin.os.tag) { 21 | .windows => std.os.windows.MAX_PATH, 22 | .linux, .macos => std.os.linux.PATH_MAX, 23 | else => std.math.maxInt(usize), 24 | }; 25 | 26 | /// Detect Wasmer library directory 27 | pub fn detectWasmerLibDir(allocator: std.mem.Allocator) !?[]const u8 { 28 | const argv = [_][]const u8{ "wasmer", "config", "--libdir" }; 29 | 30 | // By default, child will inherit stdout & stderr from its parents, 31 | // this usually means that child's output will be printed to terminal. 32 | // Here we change them to pipe and collect into `ArrayList`. 33 | var child = std.process.Child.init(&argv, allocator); 34 | child.stdout_behavior = .Pipe; 35 | child.stderr_behavior = .Pipe; 36 | var stdout = std.ArrayListUnmanaged(u8){}; 37 | var stderr = std.ArrayListUnmanaged(u8){}; 38 | defer { 39 | stdout.deinit(allocator); 40 | stderr.deinit(allocator); 41 | } 42 | 43 | try child.spawn(); 44 | try child.collectOutput(allocator, &stdout, &stderr, OS_PATH_MAX); 45 | 46 | const term = try child.wait(); 47 | 48 | if (stderr.items.len != 0 or term.Exited != 0) return null; 49 | 50 | const stdout_res = try stdout.toOwnedSlice(allocator); 51 | defer allocator.free(stdout_res); 52 | 53 | return try allocator.dupe(u8, std.mem.trimRight(u8, stdout_res, "\r\n")); 54 | } 55 | 56 | pub fn setupTracing(verbosity_level: usize, use_colors: usize) void { 57 | wasmer_setup_tracing(@as(c_int, @intCast(verbosity_level)), @as(c_int, @intCast(use_colors))); 58 | } 59 | 60 | pub extern "c" fn wasmer_setup_tracing(c_int, c_int) void; 61 | 62 | pub fn lastError(allocator: std.mem.Allocator) ![:0]u8 { 63 | const buf_len = @as(usize, @intCast(wasmer_last_error_length())); 64 | const buf = try allocator.alloc(u8, buf_len); 65 | _ = wasmer_last_error_message(buf.ptr, @as(c_int, @intCast(buf_len))); 66 | return buf[0 .. buf_len - 1 :0]; 67 | } 68 | 69 | pub extern "c" fn wasmer_last_error_length() c_int; 70 | pub extern "c" fn wasmer_last_error_message([*]const u8, c_int) c_int; 71 | 72 | pub fn watToWasm(wat: []const u8) !ByteVec { 73 | var wat_bytes = ByteVec.fromSlice(wat); 74 | defer wat_bytes.deinit(); 75 | 76 | var wasm_bytes: ByteVec = undefined; 77 | wat2wasm(&wat_bytes, &wasm_bytes); 78 | 79 | if (wasm_bytes.size == 0) return error.WatParse; 80 | 81 | return wasm_bytes; 82 | } 83 | 84 | extern "c" fn wat2wasm(*const wasm.ByteVec, *wasm.ByteVec) void; 85 | 86 | test "detect wasmer lib directory" { 87 | const result = try detectWasmerLibDir(std.testing.allocator) orelse ""; 88 | defer std.testing.allocator.free(result); 89 | 90 | try std.testing.expectStringEndsWith(result, ".wasmer/lib"); 91 | } 92 | 93 | test "transform WAT to WASM" { 94 | const wat = 95 | \\(module 96 | \\ (type $add_one_t (func (param i32) (result i32))) 97 | \\ (func $add_one_f (type $add_one_t) (param $value i32) (result i32) 98 | \\ local.get $value 99 | \\ i32.const 1 100 | \\ i32.add) 101 | \\ (export "add_one" (func $add_one_f))) 102 | ; 103 | 104 | var wasm_bytes = try watToWasm(wat); 105 | 106 | try std.testing.expectEqual(91, wasm_bytes.size); 107 | 108 | defer wasm_bytes.deinit(); 109 | } 110 | --------------------------------------------------------------------------------