diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-03-19 16:32:07 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-03-19 20:56:03 +0100 |
| commit | 2041176c5e7d2b469c2fe0168e142fe8f322b9bc (patch) | |
| tree | 1868288991f3288032fd38bb9674ec838b4b716e /src | |
| parent | 69e6d455ce8e21835ec3ce268a0533e0e7666e8b (diff) | |
| download | zig-2041176c5e7d2b469c2fe0168e142fe8f322b9bc.tar.gz zig-2041176c5e7d2b469c2fe0168e142fe8f322b9bc.zip | |
wasm: Implement `union_init` instruction
Implements the `@unionInit` builtin instruction.
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 685528c05d..4f5855c93b 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3221,7 +3221,34 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue { fn airUnionInit(self: *Self, inst: Air.Inst.Index) InnerError!WValue { if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; - return self.fail("TODO: Wasm backend: implement airUnionInit", .{}); + + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; + const union_ty = self.air.typeOfIndex(inst); + const layout = union_ty.unionGetLayout(self.target); + if (layout.payload_size == 0) { + if (layout.tag_size == 0) { + return WValue{ .none = {} }; + } + assert(!isByRef(union_ty, self.target)); + return WValue{ .imm32 = extra.field_index }; + } + assert(isByRef(union_ty, self.target)); + + const result_ptr = try self.allocStack(union_ty); + const payload = try self.resolveInst(extra.init); + const union_obj = union_ty.cast(Type.Payload.Union).?.data; + assert(union_obj.haveFieldTypes()); + const field = union_obj.fields.values()[extra.field_index]; + + if (layout.tag_align >= layout.payload_align) { + const payload_ptr = try self.buildPointerOffset(result_ptr, layout.tag_size, .new); + try self.store(payload_ptr, payload, field.ty, 0); + } else { + try self.store(result_ptr, payload, field.ty, 0); + } + + return result_ptr; } fn airPrefetch(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
