| ... | @@ -466,10 +466,74 @@ pub fn generateSymbol( | ... | @@ -466,10 +466,74 @@ pub fn generateSymbol( |
| 466 | return Result{ .appended = {} }; | 466 | return Result{ .appended = {} }; |
| 467 | }, | 467 | }, |
| 468 | .Union => { | 468 | .Union => { |
| 469 | // TODO generateSymbol for unions | 469 | // TODO generate debug info for unions |
| 470 | const target = bin_file.options.target; | 470 | const target = bin_file.options.target; |
| 471 | const abi_size = try math.cast(usize, typed_value.ty.abiSize(target)); | 471 | const union_obj = typed_value.val.castTag(.@"union").?.data; |
| 472 | try code.writer().writeByteNTimes(0xaa, abi_size); | 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 | return Result{ .appended = {} }; | 538 | return Result{ .appended = {} }; |
| 475 | }, | 539 | }, |