| ... | ... | @@ -794,6 +794,28 @@ pub const File = struct { |
| 794 | 794 | } |
| 795 | 795 | } |
| 796 | 796 | |
| 797 | /// When there is a ZCU, this is called exactly once per update, to indicate that all per-file |
| 798 | /// state (e.g. `Zcu.alive_files`) has been populated by the frontend, so can now be safely |
| 799 | /// accessed by the linker. |
| 800 | /// |
| 801 | /// This call occurs before any call to any of these functions: |
| 802 | /// * `updateNav` |
| 803 | /// * `updateFunc` |
| 804 | /// * `updateContainerType` |
| 805 | /// * `updateLineNumber` |
| 806 | /// |
| 807 | /// Asserts that the ZCU is not using the LLVM backend. |
| 808 | fn zcuFilesReady(base: *File) Error!void { |
| 809 | assert(base.comp.zcu.?.llvm_object == null); |
| 810 | switch (base.tag) { |
| 811 | else => {}, |
| 812 | inline .elf2 => |tag| { |
| 813 | dev.check(tag.devFeature()); |
| 814 | return @as(*tag.Type(), @fieldParentPtr("base", base)).zcuFilesReady(); |
| 815 | }, |
| 816 | } |
| 817 | } |
| 818 | |
| 797 | 819 | /// Asserts that the ZCU is not using the LLVM backend. |
| 798 | 820 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void { |
| 799 | 821 | assert(base.comp.zcu.?.llvm_object == null); |
| ... | ... | @@ -823,19 +845,6 @@ pub const File = struct { |
| 823 | 845 | } |
| 824 | 846 | } |
| 825 | 847 | |
| 826 | | /// Never called when LLVM is codegenning the ZCU. |
| 827 | | fn clearContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) Error!void { |
| 828 | | assert(base.comp.zcu.?.llvm_object == null); |
| 829 | | switch (base.tag) { |
| 830 | | .lld => unreachable, |
| 831 | | else => {}, |
| 832 | | inline .elf => |tag| { |
| 833 | | dev.check(tag.devFeature()); |
| 834 | | return @as(*tag.Type(), @fieldParentPtr("base", base)).clearContainerType(pt, ty); |
| 835 | | }, |
| 836 | | } |
| 837 | | } |
| 838 | | |
| 839 | 848 | /// The active tag of `mir` is determined by the backend used for the module this function is in. |
| 840 | 849 | /// Never called when LLVM is codegenning the ZCU. |
| 841 | 850 | fn updateFunc( |
| ... | ... | @@ -1417,6 +1426,9 @@ pub const PrelinkTask = union(enum) { |
| 1417 | 1426 | load_dso: Path, |
| 1418 | 1427 | }; |
| 1419 | 1428 | pub const ZcuTask = union(enum) { |
| 1429 | /// Sent once per update, as the very first `ZcuTask` in the update. Indicates that all per-file |
| 1430 | /// state (e.g. `Zcu.alive_files`) is populated so can now be safely accessed by the linker. |
| 1431 | files_ready, |
| 1420 | 1432 | /// Write the constant value for a Decl to the output file. |
| 1421 | 1433 | link_nav: InternPool.Nav.Index, |
| 1422 | 1434 | /// Write the machine code for a function to the output file. |
| ... | ... | @@ -1620,6 +1632,16 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1620 | 1632 | var timer = comp.startTimer(); |
| 1621 | 1633 | |
| 1622 | 1634 | const maybe_nav: ?InternPool.Nav.Index = switch (task) { |
| 1635 | .files_ready => { |
| 1636 | if (zcu.llvm_object != null) return; |
| 1637 | const lf = comp.bin_file orelse return; |
| 1638 | lf.zcuFilesReady() catch |err| switch (err) { |
| 1639 | error.Canceled => io.recancel(), |
| 1640 | error.AlreadyReported => return, |
| 1641 | error.OutOfMemory => return diags.setAllocFailure(), |
| 1642 | }; |
| 1643 | return; |
| 1644 | }, |
| 1623 | 1645 | .link_nav => |nav_index| nav: { |
| 1624 | 1646 | const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip); |
| 1625 | 1647 | const nav_prog_node = comp.link_prog_node.start(fqn_slice, 0); |