diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-11-25 19:14:24 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-11-30 17:56:01 +0100 |
| commit | 4af5bbde53da7f6ac8acc630135e569885bd94c4 (patch) | |
| tree | 83c9bc7b3707f9f7447bea8d69bf00324c290c18 /src/arch/wasm/CodeGen.zig | |
| parent | eb2caf939023bba16e473661d4f3cd1c19616e53 (diff) | |
| download | zig-4af5bbde53da7f6ac8acc630135e569885bd94c4.tar.gz zig-4af5bbde53da7f6ac8acc630135e569885bd94c4.zip | |
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.
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index f872bb804f..5eadc5167f 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3131,13 +3131,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const struct_ptr = try func.resolveInst(extra.data.struct_operand); const struct_ty = func.air.typeOf(extra.data.struct_operand).childType(); - const offset = std.math.cast(u32, struct_ty.structFieldOffset(extra.data.field_index, func.target)) orelse { - const module = func.bin_file.base.options.module.?; - return func.fail("Field type '{}' too big to fit into stack frame", .{ - struct_ty.structFieldType(extra.data.field_index).fmt(module), - }); - }; - const result = try func.structFieldPtr(struct_ptr, offset); + const result = try func.structFieldPtr(struct_ptr, struct_ty, extra.data.field_index); func.finishAir(inst, result, &.{extra.data.struct_operand}); } @@ -3146,21 +3140,23 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne if (func.liveness.isUnused(inst)) return func.finishAir(inst, .none, &.{ty_op.operand}); const struct_ptr = try func.resolveInst(ty_op.operand); const struct_ty = func.air.typeOf(ty_op.operand).childType(); - const field_ty = struct_ty.structFieldType(index); - const offset = std.math.cast(u32, struct_ty.structFieldOffset(index, func.target)) orelse { - const module = func.bin_file.base.options.module.?; - return func.fail("Field type '{}' too big to fit into stack frame", .{ - field_ty.fmt(module), - }); - }; - const result = try func.structFieldPtr(struct_ptr, offset); + + const result = try func.structFieldPtr(struct_ptr, struct_ty, index); func.finishAir(inst, result, &.{ty_op.operand}); } -fn structFieldPtr(func: *CodeGen, struct_ptr: WValue, offset: u32) InnerError!WValue { +fn structFieldPtr(func: *CodeGen, struct_ptr: WValue, struct_ty: Type, index: u32) InnerError!WValue { + const offset = switch (struct_ty.containerLayout()) { + .Packed => switch (struct_ty.zigTypeTag()) { + .Struct => struct_ty.packedStructFieldByteOffset(index, func.target), + .Union => 0, + else => unreachable, + }, + else => struct_ty.structFieldOffset(index, func.target), + }; switch (struct_ptr) { .stack_offset => |stack_offset| { - return WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } }; + return WValue{ .stack_offset = .{ .value = stack_offset.value + @intCast(u32, offset), .references = 1 } }; }, else => return func.buildPointerOffset(struct_ptr, offset, .new), } |
