Skip to content

Commit 8f9a0d1

Browse files
committed
Remove instancetype and replace with externtype
- This means we must pass module to get an extern by name - This also implements getExportByIndex for quicker access
1 parent 3041a2d commit 8f9a0d1

File tree

1 file changed

+76
-37
lines changed

1 file changed

+76
-37
lines changed

src/main.zig

Lines changed: 76 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,16 @@ pub const Module = opaque {
8787
wasm_module_delete(self);
8888
}
8989

90+
/// Returns a list of export types in `ExportTypeVec`
91+
pub fn exports(self: *Module) ExportTypeVec {
92+
var vec: ExportTypeVec = undefined;
93+
wasm_module_exports(self, &vec);
94+
return vec;
95+
}
96+
9097
extern "c" fn wasm_module_new(*Store, *const ByteVec) ?*Module;
9198
extern "c" fn wasm_module_delete(*Module) void;
99+
extern "c" fn wasm_module_exports(?*const Module, *ExportTypeVec) void;
92100
};
93101

94102
fn cb(params: ?*const Valtype, results: ?*Valtype) callconv(.C) ?*Trap {
@@ -179,8 +187,8 @@ pub const Func = opaque {
179187

180188
// TODO multiple return values
181189
const result_len: usize = if (ResultType == void) 0 else 1;
182-
if (result_len != self.wasm_func_result_arity()) return CallError.InvalidResultCount;
183-
if (args_len != self.wasm_func_param_arity()) return CallError.InvalidParamCount;
190+
if (result_len != wasm_func_result_arity(self)) return CallError.InvalidResultCount;
191+
if (args_len != wasm_func_param_arity(self)) return CallError.InvalidParamCount;
184192

185193
const final_args = ValVec{
186194
.size = args_len,
@@ -272,29 +280,29 @@ pub const Instance = opaque {
272280
/// Returns an export func by its name if found
273281
/// Asserts the export is of type `Func`
274282
/// The returned `Func` is a copy and must be freed by the caller
275-
pub fn getExportFunc(self: *Instance, name: []const u8) ?*Func {
276-
return if (self.getExport(name)) |exp| {
283+
pub fn getExportFunc(self: *Instance, module: *Module, name: []const u8) ?*Func {
284+
return if (self.getExport(module, name)) |exp| {
277285
defer exp.deinit(); // free the copy
278286
return exp.asFunc().copy();
279287
} else null;
280288
}
281289

282290
/// Returns an export by its name and `null` when not found
283291
/// The `Extern` is copied and must be freed manually
284-
pub fn getExport(self: *Instance, name: []const u8) ?*Extern {
292+
///
293+
/// a `Module` must be provided to find an extern by its name, rather than index.
294+
/// use getExportByIndex for quick access to an extern by index.
295+
pub fn getExport(self: *Instance, module: *Module, name: []const u8) ?*Extern {
285296
var externs: ExternVec = undefined;
286297
wasm_instance_exports(self, &externs);
287298
defer externs.deinit();
288299

289-
const instance_type = self.getType();
290-
defer instance_type.deinit();
300+
var exports = module.exports();
301+
defer exports.deinit();
291302

292-
var type_exports = instance_type.exports();
293-
defer type_exports.deinit();
294-
295-
return for (type_exports.toSlice()) |ty, index| {
296-
const t = ty orelse continue;
297-
const type_name = t.name();
303+
return for (exports.toSlice()) |export_type, index| {
304+
const ty = export_type orelse continue;
305+
const type_name = ty.name();
298306
defer type_name.deinit();
299307

300308
if (std.mem.eql(u8, name, type_name.toSlice())) {
@@ -305,20 +313,27 @@ pub const Instance = opaque {
305313
} else null;
306314
}
307315

316+
/// Returns an export by a given index. Returns null when the index
317+
/// is out of bounds. The extern is non-owned, meaning it's illegal
318+
/// behaviour to free its memory.
319+
pub fn getExportByIndex(self: *Instance, index: u32) ?*Extern {
320+
var externs: ExternVec = undefined;
321+
wasm_instance_exports(self, &externs);
322+
defer externs.deinit();
323+
324+
if (index > externs.size) return null;
325+
return externs.data[index].?;
326+
}
327+
308328
/// Returns an exported `Memory` when found and `null` when not.
309329
/// The result is copied and must be freed manually by calling `deinit()` on the result.
310-
pub fn getExportMem(self: *Instance, name: []const u8) ?*Memory {
311-
return if (self.getExport(name)) |exp| {
330+
pub fn getExportMem(self: *Instance, module: *Module, name: []const u8) ?*Memory {
331+
return if (self.getExport(module, name)) |exp| {
312332
defer exp.deinit(); // free the copy
313333
return exp.asMemory().copy();
314334
} else null;
315335
}
316336

317-
/// Returns the `InstanceType` of the `Instance`
318-
pub fn getType(self: *Instance) *InstanceType {
319-
return wasm_instance_type(self).?;
320-
}
321-
322337
/// Frees the `Instance`'s resources
323338
pub fn deinit(self: *Instance) void {
324339
wasm_instance_delete(self);
@@ -327,7 +342,6 @@ pub const Instance = opaque {
327342
extern "c" fn wasm_instance_new(*Store, *const Module, *const ExternVec, *?*Trap) ?*Instance;
328343
extern "c" fn wasm_instance_delete(*Instance) void;
329344
extern "c" fn wasm_instance_exports(*Instance, *ExternVec) void;
330-
extern "c" fn wasm_instance_type(*const Instance) ?*InstanceType;
331345
};
332346

333347
pub const Trap = opaque {
@@ -398,13 +412,54 @@ pub const Extern = opaque {
398412
return wasm_extern_same(self, other);
399413
}
400414

415+
/// Returns the type of an `Extern` as `ExternType`
416+
pub fn toType(self: *const Extern) *ExternType {
417+
return wasm_extern_type(self).?;
418+
}
419+
420+
/// Returns the kind of an `Extern`
421+
pub fn kind(self: *const Extern) ExternKind {
422+
return wasm_extern_kind(self);
423+
}
424+
401425
extern "c" fn wasm_extern_as_func(*Extern) ?*Func;
402426
extern "c" fn wasm_extern_as_memory(*Extern) ?*Memory;
403427
extern "c" fn wasm_extern_as_global(*Extern) ?*Global;
404428
extern "c" fn wasm_extern_as_table(*Extern) ?*Table;
405429
extern "c" fn wasm_extern_delete(*Extern) void;
406430
extern "c" fn wasm_extern_copy(*Extern) ?*Extern;
407431
extern "c" fn wasm_extern_same(*const Extern, *const Extern) bool;
432+
extern "c" fn wasm_extern_type(?*const Extern) ?*ExternType;
433+
extern "c" fn wasm_extern_kind(?*const Extern) ExternKind;
434+
};
435+
436+
pub const ExternKind = std.wasm.ExternalKind;
437+
438+
pub const ExternType = opaque {
439+
/// Creates an `ExternType` from an existing `Extern`
440+
pub fn fromExtern(extern_object: *const Extern) *ExternType {
441+
return Extern.wasm_extern_type(extern_object).?;
442+
}
443+
444+
/// Frees the memory of given `ExternType`
445+
pub fn deinit(self: *ExternType) void {
446+
wasm_externtype_delete(self);
447+
}
448+
449+
/// Copies the given export type. Returned copy's memory must be
450+
/// freed manually by calling `deinit()` on the object.
451+
pub fn copy(self: *ExportType) *ExportType {
452+
return wasm_externtype_copy(self).?;
453+
}
454+
455+
/// Returns the `ExternKind` from a given export type.
456+
pub fn kind(self: *const ExportType) ExternKind {
457+
return wasm_externtype_kind(self);
458+
}
459+
460+
extern "c" fn wasm_externtype_delete(?*ExportType) void;
461+
extern "c" fn wasm_externtype_copy(?*ExportType) ?*ExportType;
462+
extern "c" fn wasm_externtype_kind(?*const ExternType) ExternKind;
408463
};
409464

410465
pub const Memory = opaque {
@@ -527,22 +582,6 @@ pub const ExportTypeVec = extern struct {
527582
extern "c" fn wasm_exporttype_vec_delete(*ExportTypeVec) void;
528583
};
529584

530-
pub const InstanceType = opaque {
531-
pub fn deinit(self: *InstanceType) void {
532-
self.wasm_instancetype_delete();
533-
}
534-
535-
/// Returns a vector of `ExportType` in a singular type `ExportTypeVec`
536-
pub fn exports(self: *InstanceType) ExportTypeVec {
537-
var export_vec: ExportTypeVec = undefined;
538-
self.wasm_instancetype_exports(&export_vec);
539-
return export_vec;
540-
}
541-
542-
extern "c" fn wasm_instancetype_delete(*InstanceType) void;
543-
extern "c" fn wasm_instancetype_exports(*InstanceType, ?*ExportTypeVec) void;
544-
};
545-
546585
pub const Callback = fn (?*const Valtype, ?*Valtype) callconv(.C) ?*Trap;
547586

548587
pub const ByteVec = extern struct {

0 commit comments

Comments
 (0)