authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-11-25 19:14:24+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-11-30 17:56:01+01:00
log4af5bbde53da7f6ac8acc630135e569885bd94c4
tree83c9bc7b3707f9f7447bea8d69bf00324c290c18
parenteb2caf939023bba16e473661d4f3cd1c19616e53
signaturelock-open Commit is signed but in an unrecognized format.

wasm: airStructFieldPtr - Support packed structs

Simplifies the airStructFieldPtr(index) functions to only obtain the correct struct type and field index, which is then passed into the structFieldPtr function. This function now calculates the byte-offset of the field's address and returns a new `WValue` with this offset. This means we only have to do this calculation in a single function, and no longer have to duplicate any logic. This also handles both regular (tagged) unions and packed unions.

1 files changed, 13 insertions(+), 17 deletions(-)

src/arch/wasm/CodeGen.zig+13-17
......@@ -3131,13 +3131,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
31313131
31323132 const struct_ptr = try func.resolveInst(extra.data.struct_operand);
31333133 const struct_ty = func.air.typeOf(extra.data.struct_operand).childType();
3134 const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, func.target)) orelse {
3135 const module = func.bin_file.base.options.module.?;
3136 return func.fail("Field type '{}' too big to fit into stack frame", .{
3137 struct_ty.structFieldType(extra.data.field_index).fmt(module),
3138 });
3139 };
3140 const result = try func.structFieldPtr(struct_ptr, offset);
3134 const result = try func.structFieldPtr(struct_ptr, struct_ty, extra.data.field_index);
31413135 func.finishAir(inst, result, &.{extra.data.struct_operand});
31423136}
31433137
......@@ -3146,21 +3140,23 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne
31463140 if (func.liveness.isUnused(inst)) return func.finishAir(inst, .none, &.{ty_op.operand});
31473141 const struct_ptr = try func.resolveInst(ty_op.operand);
31483142 const struct_ty = func.air.typeOf(ty_op.operand).childType();
3149 const field_ty = struct_ty.structFieldType(index);
3150 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, func.target)) orelse {
3151 const module = func.bin_file.base.options.module.?;
3152 return func.fail("Field type '{}' too big to fit into stack frame", .{
3153 field_ty.fmt(module),
3154 });
3155 };
3156 const result = try func.structFieldPtr(struct_ptr, offset);
3143
3144 const result = try func.structFieldPtr(struct_ptr, struct_ty, index);
31573145 func.finishAir(inst, result, &.{ty_op.operand});
31583146}
31593147
3160fn structFieldPtr(func: *CodeGen, struct_ptr: WValue, offset: u32) InnerError!WValue {
3148fn structFieldPtr(func: *CodeGen, struct_ptr: WValue, struct_ty: Type, index: u32) InnerError!WValue {
3149 const offset = switch (struct_ty.containerLayout()) {
3150 .Packed => switch (struct_ty.zigTypeTag()) {
3151 .Struct => struct_ty.packedStructFieldByteOffset(index, func.target),
3152 .Union => 0,
3153 else => unreachable,
3154 },
3155 else => struct_ty.structFieldOffset(index, func.target),
3156 };
31613157 switch (struct_ptr) {
31623158 .stack_offset => |stack_offset| {
3163 return WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
3159 return WValue{ .stack_offset = .{ .value = stack_offset.value + @intCast(u32, offset), .references = 1 } };
31643160 },
31653161 else => return func.buildPointerOffset(struct_ptr, offset, .new),
31663162 }