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 {...@@ -3131,13 +3131,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
31313131
3132 const struct_ptr = try func.resolveInst(extra.data.struct_operand);3132 const struct_ptr = try func.resolveInst(extra.data.struct_operand);
3133 const struct_ty = func.air.typeOf(extra.data.struct_operand).childType();3133 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 {3134 const result = try func.structFieldPtr(struct_ptr, struct_ty, extra.data.field_index);
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);
3141 func.finishAir(inst, result, &.{extra.data.struct_operand});3135 func.finishAir(inst, result, &.{extra.data.struct_operand});
3142}3136}
31433137
...@@ -3146,21 +3140,23 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne...@@ -3146,21 +3140,23 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne
3146 if (func.liveness.isUnused(inst)) return func.finishAir(inst, .none, &.{ty_op.operand});3140 if (func.liveness.isUnused(inst)) return func.finishAir(inst, .none, &.{ty_op.operand});
3147 const struct_ptr = try func.resolveInst(ty_op.operand);3141 const struct_ptr = try func.resolveInst(ty_op.operand);
3148 const struct_ty = func.air.typeOf(ty_op.operand).childType();3142 const struct_ty = func.air.typeOf(ty_op.operand).childType();
3149 const field_ty = struct_ty.structFieldType(index);3143
3150 const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, func.target)) orelse {3144 const result = try func.structFieldPtr(struct_ptr, struct_ty, index);
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);
3157 func.finishAir(inst, result, &.{ty_op.operand});3145 func.finishAir(inst, result, &.{ty_op.operand});
3158}3146}
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 };
3161 switch (struct_ptr) {3157 switch (struct_ptr) {
3162 .stack_offset => |stack_offset| {3158 .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 } };
3164 },3160 },
3165 else => return func.buildPointerOffset(struct_ptr, offset, .new),3161 else => return func.buildPointerOffset(struct_ptr, offset, .new),
3166 }3162 }