authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-11-30 20:12:34+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-12-04 19:22:07+01:00
log1777fb25bc37c626fee91e88feeafa28f177628a
tree852260fcc6ca283ac6845ff2b52c5cdb0dced4c7
parente81fda982372061fca56c7e43d1df1653446d2a8
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Implement WrapErrorUnionErr(payload)


2 files changed, 35 insertions(+), 14 deletions(-)

src/arch/wasm/CodeGen.zig+28-9
...@@ -1148,6 +1148,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1148,6 +1148,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1148 .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst),1148 .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst),
1149 .unwrap_errunion_err => self.airUnwrapErrUnionError(inst),1149 .unwrap_errunion_err => self.airUnwrapErrUnionError(inst),
1150 .wrap_errunion_payload => self.airWrapErrUnionPayload(inst),1150 .wrap_errunion_payload => self.airWrapErrUnionPayload(inst),
1151 .wrap_errunion_err => self.airWrapErrUnionErr(inst),
11511152
1152 .optional_payload => self.airOptionalPayload(inst),1153 .optional_payload => self.airOptionalPayload(inst),
1153 .optional_payload_ptr => self.airOptionalPayload(inst),1154 .optional_payload_ptr => self.airOptionalPayload(inst),
...@@ -1328,16 +1329,15 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro...@@ -1328,16 +1329,15 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
1328 return;1329 return;
1329 },1330 },
1330 .local => {1331 .local => {
1331 // Load values from `rhs` stack position and store in `lhs` instead1332 if (payload_ty.hasCodeGenBits()) {
1332 const tag_local = try self.load(rhs, tag_ty, 0);1333 try self.store(lhs, rhs, payload_ty, payload_offset);
1333 const payload_local = try self.load(rhs, payload_ty, payload_offset);1334 }
13341335 return try self.store(lhs, rhs, tag_ty, 0);
1335 try self.store(lhs, tag_local, tag_ty, 0);
1336 return try self.store(lhs, payload_local, payload_ty, payload_offset);
1337 },1336 },
1338 .local_with_offset => |with_offset| {1337 .local_with_offset => |with_offset| {
1339 const tag_local = try self.allocLocal(tag_ty);1338 const tag_local = try self.allocLocal(tag_ty);
1340 try self.addImm32(0);1339 try self.addImm32(0);
1340 try self.addLabel(.local_set, tag_local.local);
1341 try self.store(lhs, tag_local, tag_ty, 0);1341 try self.store(lhs, tag_local, tag_ty, 0);
13421342
1343 return try self.store(1343 return try self.store(
...@@ -1415,7 +1415,10 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue {...@@ -1415,7 +1415,10 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
1415 // load local's value from memory by its stack position1415 // load local's value from memory by its stack position
1416 try self.emitWValue(operand);1416 try self.emitWValue(operand);
1417 // Build the opcode with the right bitsize1417 // Build the opcode with the right bitsize
1418 const signedness: std.builtin.Signedness = if (ty.isUnsignedInt()) .unsigned else .signed;1418 const signedness: std.builtin.Signedness = if (ty.isUnsignedInt() or ty.zigTypeTag() == .ErrorSet)
1419 .unsigned
1420 else
1421 .signed;
1419 // check if we should pass by pointer or value based on ABI size1422 // check if we should pass by pointer or value based on ABI size
1420 // TODO: Implement a way to get ABI values from a given type,1423 // TODO: Implement a way to get ABI values from a given type,
1421 // that is portable across the backend, rather than copying logic.1424 // that is portable across the backend, rather than copying logic.
...@@ -2081,9 +2084,25 @@ fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2081,9 +2084,25 @@ fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2081}2084}
20822085
2083fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {2086fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2087 if (self.liveness.isUnused(inst)) return WValue.none;
2088 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2089 const operand = self.resolveInst(ty_op.operand);
2090
2091 const op_ty = self.air.typeOf(ty_op.operand);
2092 if (!op_ty.hasCodeGenBits()) return WValue.none;
2093 const err_ty = self.air.getRefType(ty_op.ty);
2094 const offset = err_ty.errorUnionSet().abiSize(self.target);
2095
2096 return WValue{ .local_with_offset = .{
2097 .local = operand.local,
2098 .offset = @intCast(u32, offset),
2099 } };
2100}
2101
2102fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2103 if (self.liveness.isUnused(inst)) return WValue.none;
2084 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2104 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2085 _ = ty_op;2105 return self.resolveInst(ty_op.operand);
2086 return self.fail("TODO: wasm airWrapErrUnionPayload", .{});
2087}2106}
20882107
2089fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue {2108fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
src/link/Wasm.zig+7-5
...@@ -162,9 +162,8 @@ pub fn deinit(self: *Wasm) void {...@@ -162,9 +162,8 @@ pub fn deinit(self: *Wasm) void {
162 decl.link.wasm.deinit(self.base.allocator);162 decl.link.wasm.deinit(self.base.allocator);
163 }163 }
164164
165 for (self.func_types.items) |func_type| {165 for (self.func_types.items) |*func_type| {
166 self.base.allocator.free(func_type.params);166 func_type.deinit(self.base.allocator);
167 self.base.allocator.free(func_type.returns);
168 }167 }
169 for (self.segment_info.items) |segment_info| {168 for (self.segment_info.items) |segment_info| {
170 self.base.allocator.free(segment_info.name);169 self.base.allocator.free(segment_info.name);
...@@ -574,7 +573,6 @@ fn resetState(self: *Wasm) void {...@@ -574,7 +573,6 @@ fn resetState(self: *Wasm) void {
574 self.segments.clearRetainingCapacity();573 self.segments.clearRetainingCapacity();
575 self.segment_info.clearRetainingCapacity();574 self.segment_info.clearRetainingCapacity();
576 self.data_segments.clearRetainingCapacity();575 self.data_segments.clearRetainingCapacity();
577 self.function_table.clearRetainingCapacity();
578 self.atoms.clearRetainingCapacity();576 self.atoms.clearRetainingCapacity();
579 self.code_section_index = null;577 self.code_section_index = null;
580}578}
...@@ -684,12 +682,16 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {...@@ -684,12 +682,16 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
684 );682 );
685 }683 }
686684
685 // Table section
687 if (self.function_table.count() > 0) {686 if (self.function_table.count() > 0) {
688 const header_offset = try reserveVecSectionHeader(file);687 const header_offset = try reserveVecSectionHeader(file);
689 const writer = file.writer();688 const writer = file.writer();
690689
691 try leb.writeULEB128(writer, wasm.reftype(.funcref));690 try leb.writeULEB128(writer, wasm.reftype(.funcref));
692 try emitLimits(writer, .{ .min = 1, .max = null });691 try emitLimits(writer, .{
692 .min = @intCast(u32, self.function_table.count()),
693 .max = null,
694 });
693695
694 try writeVecSectionHeader(696 try writeVecSectionHeader(
695 file,697 file,