authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-22 21:23:17+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-25 19:00:52+01:00
loge9d122f1640bcf7ad71d731e6b1b259d1f065da8
tree2065756d7513e5b3198124921354ffe05fd618c6
parent288b407fa9c40addafe521862c3eef08c878b1f6
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Implement lowering unions


1 files changed, 40 insertions(+), 3 deletions(-)

src/arch/wasm/CodeGen.zig+40-3
......@@ -1053,9 +1053,46 @@ pub const DeclGen = struct {
10531053 return Result{ .appended = {} };
10541054 },
10551055 .Union => {
1056 // TODO: Implement Union declarations
1057 try writer.writeByteNTimes(0xaa, @intCast(usize, ty.abiSize(self.target())));
1058 return Result{ .appended = {} };
1056 const union_val = val.castTag(.@"union").?.data;
1057 const layout = ty.unionGetLayout(self.target());
1058
1059 if (layout.payload_size == 0) {
1060 return self.genTypedValue(ty.unionTagType().?, union_val.tag, writer);
1061 }
1062
1063 // Check if we should store the tag first, in which case, do so now:
1064 if (layout.tag_align >= layout.payload_align) {
1065 switch (try self.genTypedValue(ty.unionTagType().?, union_val.tag, writer)) {
1066 .appended => {},
1067 .externally_managed => |payload| try writer.writeAll(payload),
1068 }
1069 }
1070
1071 const union_ty = ty.cast(Type.Payload.Union).?.data;
1072 const field_index = union_ty.tag_ty.enumTagFieldIndex(union_val.tag).?;
1073 assert(union_ty.haveFieldTypes());
1074 const field_ty = union_ty.fields.values()[field_index].ty;
1075 if (!field_ty.hasCodeGenBits()) {
1076 try writer.writeByteNTimes(0xaa, layout.payload_size);
1077 } else {
1078 switch (try self.genTypedValue(field_ty, union_val.val, writer)) {
1079 .appended => {},
1080 .externally_managed => |payload| try writer.writeAll(payload),
1081 }
1082
1083 // Unions have the size of the largest field, so we must pad
1084 // whenever the active field has a smaller size.
1085 const diff = layout.payload_size - field_ty.abiSize(self.target());
1086 if (diff > 0) {
1087 try writer.writeByteNTimes(0xaa, diff);
1088 }
1089 }
1090
1091 if (layout.tag_size == 0) {
1092 return Result{ .appended = {} };
1093 }
1094
1095 return self.genTypedValue(union_ty.tag_ty, union_val.tag, writer);
10591096 },
10601097 .Pointer => switch (val.tag()) {
10611098 .variable => {