aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorXavier Bouchoux <xavierb@gmail.com>2023-07-29 20:08:08 +0200
committerXavier Bouchoux <xavierb@gmail.com>2023-10-03 06:39:20 +0200
commit62d178e91af57c19d0ac000fe6930039a23e53a3 (patch)
treef849674dd8aa13839319e05585b8513a0192b7ba /src/arch/wasm/CodeGen.zig
parent412d863ba5801c1376af7ab8f04a71b839a820a6 (diff)
downloadzig-62d178e91af57c19d0ac000fe6930039a23e53a3.tar.gz
zig-62d178e91af57c19d0ac000fe6930039a23e53a3.zip
codegen: fix field offsets in packed structs
* add nested packed struct/union behavior tests * use ptr_info.packed_offset rather than trying to duplicate the logic from Sema.structFieldPtrByIndex() * use the container_ptr_info.packed_offset to account for non-aligned nested structs. * dedup type.packedStructFieldBitOffset() and module.structPackedFieldBitOffset()
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
-rw-r--r--src/arch/wasm/CodeGen.zig15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 850e08a6bc..1fc28a8287 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -3090,12 +3090,19 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
return func.lowerParentPtr(elem.base.toValue(), @as(u32, @intCast(elem_offset + offset)));
},
.field => |field| {
- const parent_ty = mod.intern_pool.typeOf(field.base).toType().childType(mod);
+ const parent_ptr_ty = mod.intern_pool.typeOf(field.base).toType();
+ const parent_ty = parent_ptr_ty.childType(mod);
+ const field_index: u32 = @intCast(field.index);
const field_offset = switch (parent_ty.zigTypeTag(mod)) {
- .Struct => switch (parent_ty.containerLayout(mod)) {
- .Packed => parent_ty.packedStructFieldByteOffset(@as(usize, @intCast(field.index)), mod),
- else => parent_ty.structFieldOffset(@as(usize, @intCast(field.index)), mod),
+ .Struct => blk: {
+ if (mod.typeToPackedStruct(parent_ty)) |struct_type| {
+ if (ptr.ty.toType().ptrInfo(mod).packed_offset.host_size == 0)
+ break :blk @divExact(mod.structPackedFieldBitOffset(struct_type, field_index) + parent_ptr_ty.ptrInfo(mod).packed_offset.bit_offset, 8)
+ else
+ break :blk 0;
+ }
+ break :blk parent_ty.structFieldOffset(field_index, mod);
},
.Union => switch (parent_ty.containerLayout(mod)) {
.Packed => 0,