Skip to content

Commit d4fc62c

Browse files
committed
Implement the linking example
1 parent 6ec79ec commit d4fc62c

File tree

4 files changed

+120
-8
lines changed

4 files changed

+120
-8
lines changed

example/interrupt.zig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ pub fn main() !void {
1818
const wasm = try wasm_file.readToEndAlloc(ga, std.math.maxInt(u64));
1919
defer ga.free(wasm);
2020

21-
const config = try wasmtime.Config.init();
22-
config.setInterruptable(true);
21+
const config = try wasmtime.Config.init(.{ .interruptable = true });
2322
var engine = try wasmtime.Engine.withConfig(config);
2423
defer engine.deinit();
2524
std.debug.print("Engine initialized...\n", .{});

example/linking.zig

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const std = @import("std");
2+
const wasmtime = @import("wasmtime");
3+
const builtin = std.builtin;
4+
const fs = std.fs;
5+
const ga = std.heap.c_allocator;
6+
const Allocator = std.mem.Allocator;
7+
8+
pub fn main() !void {
9+
const wasm_path = if (builtin.os.tag == .windows) "example\\linking1.wat" else "example/linking1.wat";
10+
const wasm_path2 = if (builtin.os.tag == .windows) "example\\linking2.wat" else "example/linking2.wat";
11+
const wasm_file = try fs.cwd().openFile(wasm_path, .{});
12+
defer wasm_file.close();
13+
const wasm_file2 = try fs.cwd().openFile(wasm_path2, .{});
14+
defer wasm_file2.close();
15+
const wasm = try wasm_file.readToEndAlloc(ga, std.math.maxInt(u64));
16+
defer ga.free(wasm);
17+
const wasm2 = try wasm_file2.readToEndAlloc(ga, std.math.maxInt(u64));
18+
defer ga.free(wasm2);
19+
20+
const engine = try wasmtime.Engine.init();
21+
defer engine.deinit();
22+
std.debug.print("Engine initialized...\n", .{});
23+
24+
const module = try wasmtime.Module.initFromWat(engine, wasm);
25+
defer module.deinit();
26+
27+
const module2 = try wasmtime.Module.initFromWat(engine, wasm2);
28+
defer module2.deinit();
29+
30+
const store = try wasmtime.Store.init(engine);
31+
defer store.deinit();
32+
std.debug.print("Store initialized...\n", .{});
33+
34+
// intantiate wasi
35+
const config = try wasmtime.c.WasiConfig.init();
36+
config.inherit(.{});
37+
38+
var trap: ?*wasmtime.c.Trap = null;
39+
const wasi = try wasmtime.c.WasiInstance.init(store, "wasi_snapshot_preview1", config, &trap);
40+
if (trap) |t| {
41+
std.debug.print("Unexpected trap during WasiInstance initialization\n", .{});
42+
t.deinit();
43+
return;
44+
}
45+
defer wasi.deinit();
46+
std.debug.print("wasi instance initialized...\n", .{});
47+
48+
// create our linker and then add our WASI instance to it.
49+
const linker = try wasmtime.c.Linker.init(store);
50+
defer linker.deinit();
51+
if (linker.defineWasi(wasi)) |err| {
52+
var msg = err.getMessage();
53+
defer msg.deinit();
54+
std.debug.print("Linking init err: '{s}'\n", .{msg.toSlice()});
55+
return;
56+
}
57+
58+
// Instantiate `linking2` with our linker.
59+
var linking2: ?*wasmtime.Instance = null;
60+
const link_error2 = linker.instantiate(module2, &linking2, &trap);
61+
if (trap) |t| {
62+
std.debug.print("Unexpected trap during linker initialization\n", .{});
63+
t.deinit();
64+
return;
65+
}
66+
if (link_error2) |err| {
67+
var msg = err.getMessage();
68+
defer msg.deinit();
69+
std.debug.print("Linker instantiate err: '{s}'\n", .{msg.toSlice()});
70+
return;
71+
}
72+
73+
// Register our new `linking2` instance with the linker
74+
const name = wasmtime.c.NameVec.fromSlice("linking2");
75+
if (linker.defineInstance(&name, linking2.?)) |err| {
76+
var msg = err.getMessage();
77+
defer msg.deinit();
78+
std.debug.print("Define instance err: '{s}'\n", .{msg.toSlice()});
79+
return;
80+
}
81+
82+
var instance: ?*wasmtime.Instance = undefined;
83+
if (linker.instantiate(module, &instance, &trap)) |err| {
84+
var msg = err.getMessage();
85+
defer msg.deinit();
86+
std.debug.print("Instantiate err: '{s}'\n", .{msg.toSlice()});
87+
return;
88+
}
89+
if (trap) |t| {
90+
std.debug.print("Unexpected trap during linker initialization\n", .{});
91+
t.deinit();
92+
return;
93+
}
94+
defer instance.?.deinit();
95+
std.debug.print("Instance initialized...\n", .{});
96+
std.debug.print("Wasm linking completed...\n", .{});
97+
98+
if (instance.?.getExportFunc("run")) |f| {
99+
std.debug.print("Calling export...\n", .{});
100+
try f.call(void, .{});
101+
} else {
102+
std.debug.print("Export not found...\n", .{});
103+
}
104+
}

src/c.zig

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ pub const ByteVec = extern struct {
102102
extern fn wasm_byte_vec_delete(ptr: *ByteVec) void;
103103
};
104104

105+
pub const NameVec = extern struct {
106+
size: usize,
107+
data: [*]const u8,
108+
109+
pub fn fromSlice(slice: []const u8) NameVec {
110+
return .{ .size = slice.len, .data = slice.ptr };
111+
}
112+
};
113+
105114
pub const ExternVec = extern struct {
106115
size: usize,
107116
data: [*]?*Extern,
@@ -284,11 +293,11 @@ pub const WasiInstance = opaque {
284293
}
285294

286295
pub fn deinit(self: *WasiInstance) void {
287-
was_instance_delete(self);
296+
wasm_instance_delete(self);
288297
}
289298

290299
extern fn wasi_instance_new(?*Store, [*:0]const u8, ?*WasiConfig, *?*Trap) ?*WasiInstance;
291-
extern fn was_instance_delete(?*WasiInstance) void;
300+
extern fn wasm_instance_delete(?*WasiInstance) void;
292301
};
293302

294303
pub const Linker = opaque {
@@ -304,8 +313,8 @@ pub const Linker = opaque {
304313
return wasmtime_linker_define_wasi(self, wasi);
305314
}
306315

307-
pub fn defineInstance(self: *Linker, name: *const ByteVec, instance: *const Instance) ?*WasmError {
308-
wasmtime_linker_define_instance(self, name, instance);
316+
pub fn defineInstance(self: *Linker, name: *const NameVec, instance: *const Instance) ?*WasmError {
317+
return wasmtime_linker_define_instance(self, name, instance);
309318
}
310319

311320
pub fn instantiate(
@@ -320,7 +329,7 @@ pub const Linker = opaque {
320329
extern fn wasmtime_linker_new(?*Store) ?*Linker;
321330
extern fn wasmtime_linker_delete(?*Linker) void;
322331
extern fn wasmtime_linker_define_wasi(?*Linker, ?*const WasiInstance) ?*WasmError;
323-
extern fn wasmtime_linker_define_instance(?*Linker, ?*const ByteVec, ?*const Instance) ?*WasmError;
332+
extern fn wasmtime_linker_define_instance(?*Linker, ?*const NameVec, ?*const Instance) ?*WasmError;
324333
extern fn wasmtime_linker_instantiate(
325334
linker: ?*const Linker,
326335
module: ?*const Module,

src/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub const Config = opaque {
3939
interruptable: bool = false,
4040
};
4141
pub fn init(options: Options) !*Config {
42-
const config = wasm_config_new() orelse Error.ConfigInit;
42+
const config = wasm_config_new() orelse return Error.ConfigInit;
4343
if (options.interruptable) {
4444
config.setInterruptable(true);
4545
}

0 commit comments

Comments
 (0)