Wasmtime bindings for Zig
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.1 KiB

const std = @import("std");
const Allocator = std.mem.Allocator;
const Error = @import("./error.zig").Error;
const Trap = @import("./trap.zig").Trap;
const TrapCode = @import("./trap.zig").TrapCode;
const TrapError = @import("./trap.zig").TrapError;
pub const ExitStatus = c_int;
pub const ErrorUnion = union(enum) {
none: void,
err: ?ExitStatus,
trap: ?TrapCode,
};
pub const Diagnostics = struct {
allocator: Allocator,
debug_print: bool,
data: ErrorUnion = .{ .none = {} },
message: ?[]const u8 = null,
pub fn init(allocator: Allocator, debug_print: bool) !*Diagnostics {
var result = try allocator.create(Diagnostics);
result.* = .{ .allocator = allocator, .debug_print = debug_print };
return result;
}
pub fn clear(self: *Diagnostics) void {
if (self.message) |msg| self.allocator.free(msg);
self.data = .{ .none = {} };
self.message = null;
}
pub fn deinit(self: *Diagnostics) void {
if (self.message) |msg| self.allocator.free(msg);
self.allocator.destroy(self);
}
pub fn handleError(
err: ?*Error,
err_enum: anyerror,
result: anytype,
diag: ?*Diagnostics,
) @TypeOf(err_enum)!@TypeOf(result) {
if (err) |e| {
defer e.deinit();
if (diag) |d| {
var msg = e.getMessage();
defer msg.deinit();
// If the message ends with NUL byte, don't include it.
const size = if (msg.data[msg.size - 1] == 0) msg.size - 1 else msg.size;
d.data = .{ .err = e.getExitStatus() };
d.message = try d.allocator.alloc(u8, size);
@memcpy(@constCast(d.message.?), msg.data);
if (d.debug_print) std.debug.print("{s}\n", .{d.message.?});
}
return err_enum;
} else {
if (diag) |d| d.clear();
return result;
}
}
pub fn handleTrap(
trap: ?*Trap,
result: anytype,
diag: ?*Diagnostics,
) !@TypeOf(result) {
if (trap) |t| {
defer t.deinit();
const code = t.getTrapCode();
if (diag) |d| {
var msg = t.getMessage();
defer msg.deinit();
// If the message ends with NUL byte, don't include it.
const size = if (msg.data[msg.size - 1] == 0) msg.size - 1 else msg.size;
d.data = .{ .trap = code };
d.message = try d.allocator.alloc(u8, size);
@memcpy(@constCast(d.message.?), msg.data);
if (d.debug_print) std.debug.print("{s}\n", .{d.message.?});
}
return if (code) |c| c.toError() else TrapError.UnknownTrap;
} else {
if (diag) |d| d.clear();
return result;
}
}
pub fn handleErrorOrTrap(
err: ?*Error,
err_enum: anyerror,
trap: ?*Trap,
result: anytype,
diag: ?*Diagnostics,
) !@TypeOf(result) {
try handleError(err, err_enum, {}, diag);
return try handleTrap(trap, result, diag);
}
};