authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-05-21 17:07:46+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-05-28 12:58:17+02:00
loga5b5a5532e6500f7458ed5408c0b511a6f306b93
treef5f701c46547b0a0fb32e5acbee3f531dea32468
parent673ae5b457479760ff8e08b3e06917a4b2651436
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Support error sets


2 files changed, 15 insertions(+), 1 deletions(-)

src/codegen/wasm.zig+14-1
...@@ -510,6 +510,10 @@ pub const Context = struct {...@@ -510,6 +510,10 @@ pub const Context = struct {
510 locals: std.ArrayListUnmanaged(u8),510 locals: std.ArrayListUnmanaged(u8),
511 /// The Target we're emitting (used to call intInfo)511 /// The Target we're emitting (used to call intInfo)
512 target: std.Target,512 target: std.Target,
513 /// Table with the global error set. Consists of every error found in
514 /// the compiled code. Each error name maps to a `Module.ErrorInt` which is emitted
515 /// during codegen to determine the error value.
516 global_error_set: std.StringHashMapUnmanaged(Module.ErrorInt),
513517
514 const InnerError = error{518 const InnerError = error{
515 OutOfMemory,519 OutOfMemory,
...@@ -559,7 +563,6 @@ pub const Context = struct {...@@ -559,7 +563,6 @@ pub const Context = struct {
559 if (info.bits > 32 and info.bits <= 64) break :blk wasm.Valtype.i64;563 if (info.bits > 32 and info.bits <= 64) break :blk wasm.Valtype.i64;
560 return self.fail(src, "Integer bit size not supported by wasm: '{d}'", .{info.bits});564 return self.fail(src, "Integer bit size not supported by wasm: '{d}'", .{info.bits});
561 },565 },
562 .Bool, .Pointer, .Struct => wasm.Valtype.i32,
563 .Enum => switch (ty.tag()) {566 .Enum => switch (ty.tag()) {
564 .enum_simple => wasm.Valtype.i32,567 .enum_simple => wasm.Valtype.i32,
565 else => self.typeToValtype(568 else => self.typeToValtype(
...@@ -567,6 +570,11 @@ pub const Context = struct {...@@ -567,6 +570,11 @@ pub const Context = struct {
567 ty.cast(Type.Payload.EnumFull).?.data.tag_ty,570 ty.cast(Type.Payload.EnumFull).?.data.tag_ty,
568 ),571 ),
569 },572 },
573 .Bool,
574 .Pointer,
575 .Struct,
576 .ErrorSet,
577 => wasm.Valtype.i32,
570 else => self.fail(src, "TODO - Wasm valtype for type '{s}'", .{ty.zigTypeTag()}),578 else => self.fail(src, "TODO - Wasm valtype for type '{s}'", .{ty.zigTypeTag()}),
571 };579 };
572 }580 }
...@@ -959,6 +967,11 @@ pub const Context = struct {...@@ -959,6 +967,11 @@ pub const Context = struct {
959 try self.emitConstant(src, value, int_tag_ty);967 try self.emitConstant(src, value, int_tag_ty);
960 }968 }
961 },969 },
970 .ErrorSet => {
971 const error_index = self.global_error_set.get(value.getError().?).?;
972 try writer.writeByte(wasm.opcode(.i32_const));
973 try leb.writeULEB128(writer, error_index);
974 },
962 else => |zig_type| return self.fail(src, "Wasm TODO: emitConstant for zigTypeTag {s}", .{zig_type}),975 else => |zig_type| return self.fail(src, "Wasm TODO: emitConstant for zigTypeTag {s}", .{zig_type}),
963 }976 }
964 }977 }
src/link/Wasm.zig+1
...@@ -204,6 +204,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {...@@ -204,6 +204,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
204 .err_msg = undefined,204 .err_msg = undefined,
205 .locals = .{},205 .locals = .{},
206 .target = self.base.options.target,206 .target = self.base.options.target,
207 .global_error_set = self.base.options.module.?.global_error_set,
207 };208 };
208 defer context.deinit();209 defer context.deinit();
209210