diff --git a/src/codegen.zig b/src/codegen.zig index 1d83d452b9bc14faaaef15450eb0dfd5f0181add..c1a956a7656379b34ad7ec7954713babfa443a54 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -513,19 +513,27 @@ pub fn generateSymbol( } } else { const struct_begin = code.items.len; - for (struct_obj.fields.values(), 0..) |field, index| { - const field_ty = field.ty; + const fields = struct_obj.fields.values(); + + var it = typed_value.ty.iterateStructOffsets(mod); + + while (it.next()) |field_offset| { + const field_ty = fields[field_offset.field].ty; + if (!field_ty.hasRuntimeBits(mod)) continue; const field_val = switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).aggregate.storage) { .bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{ .ty = field_ty.toIntern(), - .storage = .{ .u64 = bytes[index] }, + .storage = .{ .u64 = bytes[field_offset.field] }, } }), - .elems => |elems| elems[index], + .elems => |elems| elems[field_offset.field], .repeated_elem => |elem| elem, }; + const padding = math.cast(usize, field_offset.offset - (code.items.len - struct_begin)) orelse return error.Overflow; + if (padding > 0) try code.appendNTimes(0, padding); + switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, .val = field_val.toValue(), @@ -533,16 +541,10 @@ pub fn generateSymbol( .ok => {}, .fail => |em| return Result{ .fail = em }, } - const unpadded_field_end = code.items.len - struct_begin; - - // Pad struct members if required - const padded_field_end = typed_value.ty.structFieldOffset(index + 1, mod); - const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow; - - if (padding > 0) { - try code.appendNTimes(0, padding); - } } + + const padding = math.cast(usize, std.mem.alignForward(u64, it.offset, @max(it.big_align, 1)) - (code.items.len - struct_begin)) orelse return error.Overflow; + if (padding > 0) try code.appendNTimes(0, padding); } }, else => unreachable,