| ... | @@ -513,19 +513,27 @@ pub fn generateSymbol( | ... | @@ -513,19 +513,27 @@ pub fn generateSymbol( |
| 513 | } | 513 | } |
| 514 | } else { | 514 | } else { |
| 515 | const struct_begin = code.items.len; | 515 | const struct_begin = code.items.len; |
| 516 | for (struct_obj.fields.values(), 0..) |field, index| { | 516 | const fields = struct_obj.fields.values(); |
| 517 | const field_ty = field.ty; | 517 | |
| | 518 | var it = typed_value.ty.iterateStructOffsets(mod); |
| | 519 | |
| | 520 | while (it.next()) |field_offset| { |
| | 521 | const field_ty = fields[field_offset.field].ty; |
| | 522 | |
| 518 | if (!field_ty.hasRuntimeBits(mod)) continue; | 523 | if (!field_ty.hasRuntimeBits(mod)) continue; |
| 519 | | 524 | |
| 520 | const field_val = switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).aggregate.storage) { | 525 | const field_val = switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).aggregate.storage) { |
| 521 | .bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{ | 526 | .bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{ |
| 522 | .ty = field_ty.toIntern(), | 527 | .ty = field_ty.toIntern(), |
| 523 | .storage = .{ .u64 = bytes[index] }, | 528 | .storage = .{ .u64 = bytes[field_offset.field] }, |
| 524 | } }), | 529 | } }), |
| 525 | .elems => |elems| elems[index], | 530 | .elems => |elems| elems[field_offset.field], |
| 526 | .repeated_elem => |elem| elem, | 531 | .repeated_elem => |elem| elem, |
| 527 | }; | 532 | }; |
| 528 | | 533 | |
| | 534 | const padding = math.cast(usize, field_offset.offset - (code.items.len - struct_begin)) orelse return error.Overflow; |
| | 535 | if (padding > 0) try code.appendNTimes(0, padding); |
| | 536 | |
| 529 | switch (try generateSymbol(bin_file, src_loc, .{ | 537 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 530 | .ty = field_ty, | 538 | .ty = field_ty, |
| 531 | .val = field_val.toValue(), | 539 | .val = field_val.toValue(), |
| ... | @@ -533,16 +541,10 @@ pub fn generateSymbol( | ... | @@ -533,16 +541,10 @@ pub fn generateSymbol( |
| 533 | .ok => {}, | 541 | .ok => {}, |
| 534 | .fail => |em| return Result{ .fail = em }, | 542 | .fail => |em| return Result{ .fail = em }, |
| 535 | } | 543 | } |
| 536 | const unpadded_field_end = code.items.len - struct_begin; | | |
| 537 | | | |
| 538 | // Pad struct members if required | | |
| 539 | const padded_field_end = typed_value.ty.structFieldOffset(index + 1, mod); | | |
| 540 | const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow; | | |
| 541 | | | |
| 542 | if (padding > 0) { | | |
| 543 | try code.appendNTimes(0, padding); | | |
| 544 | } | | |
| 545 | } | 544 | } |
| | 545 | |
| | 546 | 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; |
| | 547 | if (padding > 0) try code.appendNTimes(0, padding); |
| 546 | } | 548 | } |
| 547 | }, | 549 | }, |
| 548 | else => unreachable, | 550 | else => unreachable, |