const Engine = @import("./engine.zig").Engine; const Store = @import("./store.zig").Store; const Module = @import("./module.zig").Module; const Instance = @import("./instance.zig").Instance; const Func = @import("./func.zig").Func; const FuncType = @import("./func.zig").FuncType; const Extern = @import("./extern.zig").Extern; const Diagnostics = @import("./diagnostics.zig").Diagnostics; const Error = @import("./error.zig").Error; const Trap = @import("./trap.zig").Trap; /// Object used to conveniently link together and instantiate Wasm modules. /// This type is intended to make it easier to manage a set of modules that /// link together, or to make it easier to link WebAssembly modules to WASI. /// /// A `Linker` is a higher level way to instantiate a module than /// `Instance.init` since it works at the "string" level of imports rather /// than requiring 1:1 mappings. pub const Linker = opaque { /// Creates a new linker for the specified engine. pub fn init(engine: *Engine) *Linker { return wasmtime_linker_new(engine); } /// Deletes a linker pub fn deinit(self: *Linker) void { wasmtime_linker_delete(self); } /// Configures whether this linker allows later definitions to shadow /// previous definitions. (The default is `false`.) pub fn setAllowShadowing(self: *Linker, value: bool) void { wasmtime_linker_allow_shadowing(self, value); } /// Defines a new item in this linker. pub fn define( self: *Linker, context: *Store.Context, module: []const u8, name: []const u8, item: *Extern, diag: ?*Diagnostics, ) !void { const err = wasmtime_linker_define(self, context, module.ptr, module.len, name.ptr, name.len, item); try Diagnostics.handleError(err, error.LinkerDefine, {}, diag); } /// Defines a new function in this linker. /// /// Note that this function does not create a `Func`. This creates a /// store-independent function within the linker, allowing this function /// definition to be used with multiple stores. pub fn defineFunc( self: *Linker, module: []const u8, name: []const u8, func_type: *FuncType, callback: *const Func.Callback, env: ?*anyopaque, env_finalizer: ?*const Func.Finalizer, diag: ?*Diagnostics, ) !void { const err = wasmtime_linker_define_func(self, module.ptr, module.len, name.ptr, name.len, func_type, callback, env, env_finalizer); try Diagnostics.handleError(err, error.LinkerDefineFunc, {}, diag); } pub fn defineFuncFromFn( self: *Linker, module: []const u8, name: []const u8, func: anytype, diag: ?*Diagnostics, ) !void { const func_type = FuncType.fromFn(func); const wrapped = Func.Wrapped.init(func); try defineFunc(self, module, name, func_type, wrapped.callback, wrapped.env, wrapped.env_finalizer, diag); } /// Defines an instance under the specified name in this linker. /// /// This function will take all of the exports of the `instance` provided /// and defined them under a module called `name` with a field name as the /// export's own name. pub fn defineInstance( self: *Linker, context: *Store.Context, name: []const u8, instance: *const Instance, diag: ?*Diagnostics, ) !void { const err = wasmtime_linker_define_instance(self, context, name.ptr, name.len, instance); try Diagnostics.handleError(err, error.LinkerDefineInstance, {}, diag); } /// Instantiates a `Module` with the items defined in this linker. /// /// This function will attempt to satisfy all of the imports of the /// `module` provided with items previously defined in this linker. If any /// name isn't defined in the linker (or if the previously defined item is /// of the wrong type) then an error is returned. pub fn instantiate( linker: *const Linker, context: *Store.Context, module: *const Module, diag: ?*Diagnostics, ) !Instance { var result: Instance = undefined; var trap: ?*Trap = null; const err = wasmtime_linker_instantiate(linker, context, module, &result, &trap); return Diagnostics.handleErrorOrTrap(err, error.LinkerInstantiate, trap, result, diag); } /// Defines automatic instantiations of a `Module` in this linker. pub fn autoInstantiateModule( linker: *const Linker, context: *Store.Context, name: []const u8, module: *const Module, diag: ?*Diagnostics, ) !void { const err = wasmtime_linker_module(linker, context, name.ptr, name.len, module); try Diagnostics.handleError(err, error.LinkerAutoInstantiateModule, {}, diag); } /// Acquires the "default export" of the named module in this linker. pub fn getDefault( linker: *const Linker, context: *Store.Context, module: []const u8, diag: ?*Diagnostics, ) !Func { var result: Func = undefined; const err = wasmtime_linker_get_default(linker, context, module.ptr, module.len, &result); return Diagnostics.handleError(err, error.LinkerGetDefault, result, diag); } /// Loads an item by name from this linker. pub fn get( linker: *const Linker, context: *Store.Context, module: []const u8, name: []const u8, ) ?Extern { var result: Extern = undefined; return if (wasmtime_linker_get(linker, context, module.ptr, module.len, name.ptr, name.len, &result)) result else null; } extern "c" fn wasmtime_linker_new(*Engine) *Linker; extern "c" fn wasmtime_linker_delete(*Linker) void; extern "c" fn wasmtime_linker_allow_shadowing(*Linker, bool) void; extern "c" fn wasmtime_linker_define( linker: *Linker, context: *Store.Context, module: [*]const u8, module_len: usize, name: [*]const u8, name_len: usize, item: *Extern, ) ?*Error; extern "c" fn wasmtime_linker_define_func( linker: *Linker, module: [*]const u8, module_len: usize, name: [*]const u8, name_len: usize, func_type: *FuncType, callback: *const Func.Callback, env: ?*anyopaque, env_finalizer: ?*const Func.Finalizer, ) ?*Error; // extern "c" fn wasmtime_linker_define_wasi( // linker: *Linker, // ) ?*Error; extern "c" fn wasmtime_linker_define_instance( linker: *Linker, context: *Store.Context, name: [*]const u8, name_len: usize, instance: *const Instance, ) ?*Error; extern "c" fn wasmtime_linker_instantiate( linker: *const Linker, context: *Store.Context, module: *const Module, result: *Instance, trap: *?*Trap, ) ?*Error; extern "c" fn wasmtime_linker_module( linker: *Linker, context: *Store.Context, name: [*]const u8, name_len: usize, module: *const Module, ) ?*Error; extern "c" fn wasmtime_linker_get_default( linker: *const Linker, context: *Store.Context, name: [*]const u8, name_len: usize, result: *Func, ) ?*Error; extern "c" fn wasmtime_linker_get( linker: *const Linker, context: *Store.Context, module: [*]const u8, module_len: usize, name: [*]const u8, name_len: usize, result: *Extern, ) bool; };