| ... | ... | @@ -466,10 +466,74 @@ pub fn generateSymbol( |
| 466 | 466 | return Result{ .appended = {} }; |
| 467 | 467 | }, |
| 468 | 468 | .Union => { |
| 469 | | // TODO generateSymbol for unions |
| 469 | // TODO generate debug info for unions |
| 470 | 470 | const target = bin_file.options.target; |
| 471 | | const abi_size = try math.cast(usize, typed_value.ty.abiSize(target)); |
| 472 | | try code.writer().writeByteNTimes(0xaa, abi_size); |
| 471 | const union_obj = typed_value.val.castTag(.@"union").?.data; |
| 472 | const layout = typed_value.ty.unionGetLayout(target); |
| 473 | |
| 474 | if (layout.payload_size == 0) { |
| 475 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ |
| 476 | .ty = typed_value.ty.unionTagType().?, |
| 477 | .val = union_obj.tag, |
| 478 | }, code, debug_output)) { |
| 479 | .appended => {}, |
| 480 | .externally_managed => |external_slice| { |
| 481 | code.appendSliceAssumeCapacity(external_slice); |
| 482 | }, |
| 483 | .fail => |em| return Result{ .fail = em }, |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | // Check if we should store the tag first. |
| 488 | if (layout.tag_align >= layout.payload_align) { |
| 489 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ |
| 490 | .ty = typed_value.ty.unionTagType().?, |
| 491 | .val = union_obj.tag, |
| 492 | }, code, debug_output)) { |
| 493 | .appended => {}, |
| 494 | .externally_managed => |external_slice| { |
| 495 | code.appendSliceAssumeCapacity(external_slice); |
| 496 | }, |
| 497 | .fail => |em| return Result{ .fail = em }, |
| 498 | } |
| 499 | } |
| 500 | |
| 501 | const union_ty = typed_value.ty.cast(Type.Payload.Union).?.data; |
| 502 | const field_index = union_ty.tag_ty.enumTagFieldIndex(union_obj.tag).?; |
| 503 | assert(union_ty.haveFieldTypes()); |
| 504 | const field_ty = union_ty.fields.values()[field_index].ty; |
| 505 | if (!field_ty.hasRuntimeBits()) { |
| 506 | try code.writer().writeByteNTimes(0xaa, try math.cast(usize, layout.payload_size)); |
| 507 | } else { |
| 508 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ |
| 509 | .ty = field_ty, |
| 510 | .val = union_obj.val, |
| 511 | }, code, debug_output)) { |
| 512 | .appended => {}, |
| 513 | .externally_managed => |external_slice| { |
| 514 | code.appendSliceAssumeCapacity(external_slice); |
| 515 | }, |
| 516 | .fail => |em| return Result{ .fail = em }, |
| 517 | } |
| 518 | |
| 519 | const padding = try math.cast(usize, layout.payload_size - field_ty.abiSize(target)); |
| 520 | if (padding > 0) { |
| 521 | try code.writer().writeByteNTimes(0, padding); |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | if (layout.tag_size > 0) { |
| 526 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ |
| 527 | .ty = union_ty.tag_ty, |
| 528 | .val = union_obj.tag, |
| 529 | }, code, debug_output)) { |
| 530 | .appended => {}, |
| 531 | .externally_managed => |external_slice| { |
| 532 | code.appendSliceAssumeCapacity(external_slice); |
| 533 | }, |
| 534 | .fail => |em| return Result{ .fail = em }, |
| 535 | } |
| 536 | } |
| 473 | 537 | |
| 474 | 538 | return Result{ .appended = {} }; |
| 475 | 539 | }, |