| author | |
| committer | |
| log | 5d215838a79a24c21842fbc76fd77aca4c28b162 |
| tree | 4f0c95e0b2a6dea5a7b7dbcb53649d9839dadcd1 |
| parent | 065c6e7946e712dc8563c975a4ca951927145da7 |
| signature |
I've realised that the cause of at least some of our weird CI flakiness
was a bug in how `Nav` values were resolved. Consider this scenario: the
frontend resolves the type of a `Nav`, and then sends a function to the
backend, which requires the backend to lower a pointer to that `Nav`.
The backend calls `InternPool.getNav` to determine the `Nav`'s type.
However, this races with the frontend resolving the *value* of that
`Nav`. This involves writing separately to two fields, `bits` and
`type_or_value`. If only one of these changes is observed, then the
backend will incorrectly interpret the type as the value or vice versa,
leading to a crash or even a miscompilation. (Of course, there's also
the straightforward issue that the racing loads were non-atomic, making
them illegal).
The only good solution to this was to make `Nav` 4 bytes bigger, giving
it separate `type` and `value` fields. In theory that's a quite small
change, but it ended up having a bunch of nice consequences which led to
this diff being a bit bulkier than expected:
* `Nav.Repr.Bits` was simplified, because it no longer has to track
"resolution status": we can use `.none` for that. This frees up some
bits to make things more consistent between the "type resolved" and
"fully resolved" states.
* This consistency allowed the `Nav.status` union to be replaced with a
simpler field `Nav.resolved`, which is a bit nicer to work with.
* Most of the "getter" functions were able to be removed from `Nav`
because the state they were fetching had been moved to simple fields
on `Nav.resolved`.
* There were still a handful of free bits in `Nav.Repr.Bits`, which
could be used to represent the "const" and "threadlocal" flags rather
than these being stored on `Key.Extern` and `Key.Variable`. This is a
bit more convenient for linkers.
* With those bits gone, `Key.Variable` is a trivial wrapper around a
type and an initial value, and the fact that a declaration is mutable
can be represented solely through the "const" flag. Therefore,
`Key.Variable` no longer served a purpose, and could be eliminated
entirely in favour of storing the variable's initial value directly in
the "value" field of the `Nav`.
So, I'm quite pleased with this refactor! But anyway, regarding the bug
fix which actually motivated this: if I've done my job correctly, this
should solve some crashes, such as these (which were what tipped me off
to this bug in the first place):
https://codeberg.org/ziglang/zig/actions/runs/2306/jobs/7/attempt/1
https://codeberg.org/ziglang/zig/actions/runs/2173/jobs/6/attempt/1
...and, who knows, perhaps even the random SIGSEGVs we've seen on some
targets! Probably not, but one can hope.33 files changed, 593 insertions(+), 965 deletions(-)
src/IncrementalDebugServer.zig+12-9| ... | @@ -215,22 +215,25 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const | ... | @@ -215,22 +215,25 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const |
| 215 | try w.print( | 215 | try w.print( |
| 216 | \\name: '{f}' | 216 | \\name: '{f}' |
| 217 | \\fqn: '{f}' | 217 | \\fqn: '{f}' |
| 218 | \\status: {s} | ||
| 219 | \\created on generation: {d} | 218 | \\created on generation: {d} |
| 220 | \\ | 219 | \\ |
| 221 | , .{ | 220 | , .{ |
| 222 | nav.name.fmt(ip), | 221 | nav.name.fmt(ip), |
| 223 | nav.fqn.fmt(ip), | 222 | nav.fqn.fmt(ip), |
| 224 | @tagName(nav.status), | ||
| 225 | create_gen, | 223 | create_gen, |
| 226 | }); | 224 | }); |
| 227 | switch (nav.status) { | 225 | if (nav.resolved) |r| { |
| 228 | .unresolved => {}, | 226 | try w.writeAll("status: resolved\n type: "); |
| 229 | .type_resolved, .fully_resolved => { | 227 | try printType(.fromInterned(r.type), zcu, w); |
| 230 | try w.writeAll("type: "); | 228 | try w.writeAll("\n value: "); |
| 231 | try printType(.fromInterned(nav.typeOf(ip)), zcu, w); | 229 | if (r.value == .none) { |
| 232 | try w.writeByte('\n'); | 230 | try w.writeAll("(unresolved)"); |
| 233 | }, | 231 | } else { |
| 232 | try printType(.fromInterned(r.type), zcu, w); | ||
| 233 | } | ||
| 234 | try w.writeByte('\n'); | ||
| 235 | } else { | ||
| 236 | try w.writeAll("status: unresolved\n"); | ||
| 234 | } | 237 | } |
| 235 | } else if (std.mem.eql(u8, cmd_str, "find_type")) { | 238 | } else if (std.mem.eql(u8, cmd_str, "find_type")) { |
| 236 | if (arg_str.len == 0) return w.writeAll("bad usage"); | 239 | if (arg_str.len == 0) return w.writeAll("bad usage"); |
src/InternPool.zig+182-402| ... | @@ -548,144 +548,61 @@ pub const Nav = struct { | ... | @@ -548,144 +548,61 @@ pub const Nav = struct { |
| 548 | /// The fully-qualified name of this `Nav`. | 548 | /// The fully-qualified name of this `Nav`. |
| 549 | fqn: NullTerminatedString, | 549 | fqn: NullTerminatedString, |
| 550 | /// This field is populated iff this `Nav` is resolved by semantic analysis. | 550 | /// This field is populated iff this `Nav` is resolved by semantic analysis. |
| 551 | /// If this is `null`, then `status == .fully_resolved` always. | 551 | /// If this is `null`, then `resolved` is *not* `null`. |
| 552 | analysis: ?struct { | 552 | analysis: ?struct { |
| 553 | namespace: NamespaceIndex, | 553 | namespace: NamespaceIndex, |
| 554 | zir_index: TrackedInst.Index, | 554 | zir_index: TrackedInst.Index, |
| 555 | /// Initially `false`. Set to `true` by `setWantNavAnalysis`. | 555 | /// Initially `false`. Set to `true` by `setWantNavAnalysis`. |
| 556 | wanted: bool, | 556 | wanted: bool, |
| 557 | }, | 557 | }, |
| 558 | status: union(enum) { | 558 | /// If this is `null`, then `analysis` is *not* `null`, and semantic analysis is required to |
| 559 | /// This `Nav` is pending semantic analysis. | 559 | /// resolve the type and value of this `Nav`. Otherwise, the type is resolved---therefore, |
| 560 | unresolved, | 560 | /// `Nav.resolved.?.type` is never `.none`. However, the *value* may not be resolved yet even |
| 561 | /// The type of this `Nav` is resolved; the value is queued for resolution. | 561 | /// if this field is not `null`---see `Resolved.value` for details. |
| 562 | type_resolved: struct { | 562 | resolved: ?Resolved, |
| 563 | type: InternPool.Index, | 563 | |
| 564 | is_const: bool, | 564 | pub const Resolved = struct { |
| 565 | alignment: Alignment, | 565 | /// This is never `.none` |
| 566 | @"linksection": OptionalNullTerminatedString, | 566 | type: InternPool.Index, |
| 567 | @"addrspace": std.builtin.AddressSpace, | 567 | @"align": Alignment, |
| 568 | is_threadlocal: bool, | 568 | @"linksection": OptionalNullTerminatedString, |
| 569 | /// This field is whether this `Nav` is a literal `extern` definition. | 569 | @"addrspace": std.builtin.AddressSpace, |
| 570 | /// It does *not* tell you whether this might alias an extern fn (see #21027). | 570 | @"const": bool, |
| 571 | is_extern_decl: bool, | 571 | @"threadlocal": bool, |
| 572 | }, | 572 | /// This field is whether this `Nav` is a literal `extern` definition. |
| 573 | /// The value of this `Nav` is resolved. | 573 | /// It does *not* tell you whether this might alias an extern fn (see #21027). |
| 574 | fully_resolved: struct { | 574 | is_extern_decl: bool, |
| 575 | val: InternPool.Index, | 575 | /// If the type is resolved but not the value, this is `.none`. In that case, the value will |
| 576 | is_const: bool, | 576 | /// be resolved by semantic analysis, so `Nav.analysis` is definitely not `null`. |
| 577 | alignment: Alignment, | 577 | /// |
| 578 | @"linksection": OptionalNullTerminatedString, | 578 | /// If this is an extern, the special key `Key.@"extern"` is used. |
| 579 | @"addrspace": std.builtin.AddressSpace, | 579 | /// |
| 580 | }, | 580 | /// If this is a variable (`Resolved.@"const" == false`) and not an extern, then this value |
| 581 | }, | 581 | /// is the global variable's initializer; the value loaded from the variable at runtime may |
| 582 | 582 | /// of course be different. | |
| 583 | /// Asserts that `status != .unresolved`. | 583 | value: InternPool.Index, |
| 584 | pub fn typeOf(nav: Nav, ip: *const InternPool) InternPool.Index { | 584 | }; |
| 585 | return switch (nav.status) { | 585 | |
| 586 | .unresolved => unreachable, | 586 | /// If the value of this `Nav` is resolved and is an extern, returns the `Key.Extern`. If the |
| 587 | .type_resolved => |r| r.type, | 587 | /// value is *not* an extern, *or* if the value is not yet resolved (only the type is), returns |
| 588 | .fully_resolved => |r| ip.typeOf(r.val), | 588 | /// `null`. |
| 589 | }; | 589 | /// |
| 590 | } | 590 | /// This logic works because the frontend ensures that if a `Nav` *might* be extern, its value |
| 591 | 591 | /// is resolved more eagerly (see logic in `Sema.analyzeNavRefInner`). Therefore, if we see that | |
| 592 | /// This function is intended to be used by code generation, since semantic | 592 | /// the value is not yet resolved, we know the frontend determined that the `Nav` is definitely |
| 593 | /// analysis will ensure that any `Nav` which is potentially `extern` is | 593 | /// *not* extern. |
| 594 | /// fully resolved. | 594 | /// |
| 595 | /// Asserts that `status == .fully_resolved`. | 595 | /// This function is only intended be used by the compiler backend (codegen/link). The guarantee |
| 596 | pub fn getResolvedExtern(nav: Nav, ip: *const InternPool) ?Key.Extern { | 596 | /// mentioned above does not necessarily hold in the compiler frontend (if we haven't reached |
| 597 | assert(nav.status == .fully_resolved); | 597 | /// `Sema.analyzeNavRefInner` yet). |
| 598 | return nav.getExtern(ip); | 598 | /// |
| 599 | } | 599 | /// Asserts that `nav.resolved != null`. |
| 600 | |||
| 601 | /// Always returns `null` for `status == .type_resolved`. This function is inteded | ||
| 602 | /// to be used by code generation, since semantic analysis will ensure that any `Nav` | ||
| 603 | /// which is potentially `extern` is fully resolved. | ||
| 604 | /// Asserts that `status != .unresolved`. | ||
| 605 | pub fn getExtern(nav: Nav, ip: *const InternPool) ?Key.Extern { | 600 | pub fn getExtern(nav: Nav, ip: *const InternPool) ?Key.Extern { |
| 606 | return switch (nav.status) { | 601 | const r = nav.resolved.?; |
| 607 | .unresolved => unreachable, | 602 | if (r.value == .none) return null; |
| 608 | .type_resolved => null, | 603 | return switch (ip.indexToKey(r.value)) { |
| 609 | .fully_resolved => |r| switch (ip.indexToKey(r.val)) { | 604 | .@"extern" => |e| e, |
| 610 | .@"extern" => |e| e, | 605 | else => null, |
| 611 | else => null, | ||
| 612 | }, | ||
| 613 | }; | ||
| 614 | } | ||
| 615 | |||
| 616 | /// Asserts that `status != .unresolved`. | ||
| 617 | pub fn getAddrspace(nav: Nav) std.builtin.AddressSpace { | ||
| 618 | return switch (nav.status) { | ||
| 619 | .unresolved => unreachable, | ||
| 620 | .type_resolved => |r| r.@"addrspace", | ||
| 621 | .fully_resolved => |r| r.@"addrspace", | ||
| 622 | }; | ||
| 623 | } | ||
| 624 | |||
| 625 | /// Asserts that `status != .unresolved`. | ||
| 626 | pub fn getAlignment(nav: Nav) Alignment { | ||
| 627 | return switch (nav.status) { | ||
| 628 | .unresolved => unreachable, | ||
| 629 | .type_resolved => |r| r.alignment, | ||
| 630 | .fully_resolved => |r| r.alignment, | ||
| 631 | }; | ||
| 632 | } | ||
| 633 | |||
| 634 | /// Asserts that `status != .unresolved`. | ||
| 635 | pub fn getLinkSection(nav: Nav) OptionalNullTerminatedString { | ||
| 636 | return switch (nav.status) { | ||
| 637 | .unresolved => unreachable, | ||
| 638 | .type_resolved => |r| r.@"linksection", | ||
| 639 | .fully_resolved => |r| r.@"linksection", | ||
| 640 | }; | ||
| 641 | } | ||
| 642 | |||
| 643 | /// Asserts that `status != .unresolved`. | ||
| 644 | pub fn isThreadlocal(nav: Nav, ip: *const InternPool) bool { | ||
| 645 | return switch (nav.status) { | ||
| 646 | .unresolved => unreachable, | ||
| 647 | .type_resolved => |r| r.is_threadlocal, | ||
| 648 | .fully_resolved => |r| switch (ip.indexToKey(r.val)) { | ||
| 649 | .@"extern" => |e| e.is_threadlocal, | ||
| 650 | .variable => |v| v.is_threadlocal, | ||
| 651 | else => false, | ||
| 652 | }, | ||
| 653 | }; | ||
| 654 | } | ||
| 655 | |||
| 656 | pub fn isFn(nav: Nav, ip: *const InternPool) bool { | ||
| 657 | return switch (nav.status) { | ||
| 658 | .unresolved => unreachable, | ||
| 659 | .type_resolved => |r| { | ||
| 660 | const tag = ip.zigTypeTag(r.type); | ||
| 661 | return tag == .@"fn"; | ||
| 662 | }, | ||
| 663 | .fully_resolved => |r| { | ||
| 664 | const tag = ip.zigTypeTag(ip.typeOf(r.val)); | ||
| 665 | return tag == .@"fn"; | ||
| 666 | }, | ||
| 667 | }; | ||
| 668 | } | ||
| 669 | |||
| 670 | /// If this returns `true`, then a pointer to this `Nav` might actually be encoded as a pointer | ||
| 671 | /// to some other `Nav` due to an extern definition or extern alias (see #21027). | ||
| 672 | /// This query is valid on `Nav`s for whom only the type is resolved. | ||
| 673 | /// Asserts that `status != .unresolved`. | ||
| 674 | pub fn isExternOrFn(nav: Nav, ip: *const InternPool) bool { | ||
| 675 | return switch (nav.status) { | ||
| 676 | .unresolved => unreachable, | ||
| 677 | .type_resolved => |r| { | ||
| 678 | if (r.is_extern_decl) return true; | ||
| 679 | const tag = ip.zigTypeTag(r.type); | ||
| 680 | if (tag == .@"fn") return true; | ||
| 681 | return false; | ||
| 682 | }, | ||
| 683 | .fully_resolved => |r| { | ||
| 684 | if (ip.indexToKey(r.val) == .@"extern") return true; | ||
| 685 | const tag = ip.zigTypeTag(ip.typeOf(r.val)); | ||
| 686 | if (tag == .@"fn") return true; | ||
| 687 | return false; | ||
| 688 | }, | ||
| 689 | }; | 606 | }; |
| 690 | } | 607 | } |
| 691 | 608 | ||
| ... | @@ -696,7 +613,7 @@ pub const Nav = struct { | ... | @@ -696,7 +613,7 @@ pub const Nav = struct { |
| 696 | return a.zir_index; | 613 | return a.zir_index; |
| 697 | } | 614 | } |
| 698 | // A `Nav` which does not undergo analysis always has a resolved value. | 615 | // A `Nav` which does not undergo analysis always has a resolved value. |
| 699 | return switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 616 | return switch (ip.indexToKey(nav.resolved.?.value)) { |
| 700 | .func => |func| { | 617 | .func => |func| { |
| 701 | // Since `analysis` was not populated, this must be an instantiation. | 618 | // Since `analysis` was not populated, this must be an instantiation. |
| 702 | // Go up to the generic owner and consult *its* `analysis` field. | 619 | // Go up to the generic owner and consult *its* `analysis` field. |
| ... | @@ -747,30 +664,26 @@ pub const Nav = struct { | ... | @@ -747,30 +664,26 @@ pub const Nav = struct { |
| 747 | }; | 664 | }; |
| 748 | 665 | ||
| 749 | /// The compact in-memory representation of a `Nav`. | 666 | /// The compact in-memory representation of a `Nav`. |
| 750 | /// 26 bytes. | 667 | /// 30 bytes. |
| 751 | const Repr = struct { | 668 | const Repr = struct { |
| 752 | name: NullTerminatedString, | 669 | name: NullTerminatedString, |
| 753 | fqn: NullTerminatedString, | 670 | fqn: NullTerminatedString, |
| 754 | // The following 2 fields are either both populated, or both `.none`. | 671 | // The following 2 fields are either both populated, or both `.none`. |
| 755 | analysis_namespace: OptionalNamespaceIndex, | 672 | analysis_namespace: OptionalNamespaceIndex, |
| 756 | analysis_zir_index: TrackedInst.Index.Optional, | 673 | analysis_zir_index: TrackedInst.Index.Optional, |
| 757 | /// Populated only if `bits.status != .unresolved`. | 674 | type: InternPool.Index, |
| 758 | type_or_val: InternPool.Index, | 675 | value: InternPool.Index, |
| 759 | /// Populated only if `bits.status != .unresolved`. | ||
| 760 | @"linksection": OptionalNullTerminatedString, | 676 | @"linksection": OptionalNullTerminatedString, |
| 761 | bits: Bits, | 677 | bits: Bits, |
| 762 | 678 | ||
| 763 | const Bits = packed struct(u16) { | 679 | const Bits = packed struct(u16) { |
| 764 | status: enum(u2) { unresolved, type_resolved, fully_resolved, type_resolved_extern_decl }, | 680 | @"align": Alignment, |
| 765 | /// Populated only if `bits.status != .unresolved`. | ||
| 766 | is_const: bool, | ||
| 767 | /// Populated only if `bits.status != .unresolved`. | ||
| 768 | alignment: Alignment, | ||
| 769 | /// Populated only if `bits.status != .unresolved`. | ||
| 770 | @"addrspace": std.builtin.AddressSpace, | 681 | @"addrspace": std.builtin.AddressSpace, |
| 771 | /// Populated only if `bits.status == .type_resolved`. | 682 | @"const": bool, |
| 772 | is_threadlocal: bool, | 683 | @"threadlocal": bool, |
| 684 | is_extern_decl: bool, | ||
| 773 | want_analysis: bool, | 685 | want_analysis: bool, |
| 686 | _: u1 = 0, | ||
| 774 | }; | 687 | }; |
| 775 | 688 | ||
| 776 | fn unpack(repr: Repr) Nav { | 689 | fn unpack(repr: Repr) Nav { |
| ... | @@ -785,72 +698,46 @@ pub const Nav = struct { | ... | @@ -785,72 +698,46 @@ pub const Nav = struct { |
| 785 | assert(repr.analysis_zir_index == .none); | 698 | assert(repr.analysis_zir_index == .none); |
| 786 | break :a null; | 699 | break :a null; |
| 787 | }, | 700 | }, |
| 788 | .status = switch (repr.bits.status) { | 701 | .resolved = if (repr.type == .none) null else .{ |
| 789 | .unresolved => .unresolved, | 702 | .type = repr.type, |
| 790 | .type_resolved, .type_resolved_extern_decl => .{ .type_resolved = .{ | 703 | .@"align" = repr.bits.@"align", |
| 791 | .type = repr.type_or_val, | 704 | .@"linksection" = repr.@"linksection", |
| 792 | .is_const = repr.bits.is_const, | 705 | .@"addrspace" = repr.bits.@"addrspace", |
| 793 | .alignment = repr.bits.alignment, | 706 | .@"const" = repr.bits.@"const", |
| 794 | .@"linksection" = repr.@"linksection", | 707 | .@"threadlocal" = repr.bits.@"threadlocal", |
| 795 | .@"addrspace" = repr.bits.@"addrspace", | 708 | .is_extern_decl = repr.bits.is_extern_decl, |
| 796 | .is_threadlocal = repr.bits.is_threadlocal, | 709 | .value = repr.value, |
| 797 | .is_extern_decl = repr.bits.status == .type_resolved_extern_decl, | ||
| 798 | } }, | ||
| 799 | .fully_resolved => .{ .fully_resolved = .{ | ||
| 800 | .val = repr.type_or_val, | ||
| 801 | .is_const = repr.bits.is_const, | ||
| 802 | .alignment = repr.bits.alignment, | ||
| 803 | .@"linksection" = repr.@"linksection", | ||
| 804 | .@"addrspace" = repr.bits.@"addrspace", | ||
| 805 | } }, | ||
| 806 | }, | 710 | }, |
| 807 | }; | 711 | }; |
| 808 | } | 712 | } |
| 809 | }; | 713 | }; |
| 810 | 714 | ||
| 811 | fn pack(nav: Nav) Repr { | 715 | fn pack(nav: Nav) Repr { |
| 812 | // Note that in the `unresolved` case, we do not mark fields as `undefined`, even though they should not be used. | 716 | // Note that even if `nav.resolved == null`, we do not set any fields to `undefined`, even |
| 813 | // This is to avoid writing undefined bytes to disk when serializing buffers. | 717 | // though they should not be used. This is to avoid writing undefined bytes to disk when |
| 718 | // serializing buffers. | ||
| 814 | return .{ | 719 | return .{ |
| 815 | .name = nav.name, | 720 | .name = nav.name, |
| 816 | .fqn = nav.fqn, | 721 | .fqn = nav.fqn, |
| 817 | .analysis_namespace = if (nav.analysis) |a| a.namespace.toOptional() else .none, | 722 | .analysis_namespace = if (nav.analysis) |a| a.namespace.toOptional() else .none, |
| 818 | .analysis_zir_index = if (nav.analysis) |a| a.zir_index.toOptional() else .none, | 723 | .analysis_zir_index = if (nav.analysis) |a| a.zir_index.toOptional() else .none, |
| 819 | .type_or_val = switch (nav.status) { | 724 | .type = if (nav.resolved) |r| r.type else .none, |
| 820 | .unresolved => .none, | 725 | .value = if (nav.resolved) |r| r.value else .none, |
| 821 | .type_resolved => |r| r.type, | 726 | .@"linksection" = if (nav.resolved) |r| r.@"linksection" else .none, |
| 822 | .fully_resolved => |r| r.val, | 727 | .bits = if (nav.resolved) |r| .{ |
| 823 | }, | 728 | .@"align" = r.@"align", |
| 824 | .@"linksection" = switch (nav.status) { | 729 | .@"addrspace" = r.@"addrspace", |
| 825 | .unresolved => .none, | 730 | .@"const" = r.@"const", |
| 826 | .type_resolved => |r| r.@"linksection", | 731 | .@"threadlocal" = r.@"threadlocal", |
| 827 | .fully_resolved => |r| r.@"linksection", | 732 | .is_extern_decl = r.is_extern_decl, |
| 828 | }, | 733 | .want_analysis = if (nav.analysis) |a| a.wanted else false, |
| 829 | .bits = switch (nav.status) { | 734 | } else .{ |
| 830 | .unresolved => .{ | 735 | .@"align" = .none, |
| 831 | .status = .unresolved, | 736 | .@"addrspace" = .generic, |
| 832 | .is_const = false, | 737 | .@"const" = false, |
| 833 | .alignment = .none, | 738 | .@"threadlocal" = false, |
| 834 | .@"addrspace" = .generic, | 739 | .is_extern_decl = false, |
| 835 | .is_threadlocal = false, | 740 | .want_analysis = if (nav.analysis) |a| a.wanted else false, |
| 836 | .want_analysis = if (nav.analysis) |a| a.wanted else false, | ||
| 837 | }, | ||
| 838 | .type_resolved => |r| .{ | ||
| 839 | .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved, | ||
| 840 | .is_const = r.is_const, | ||
| 841 | .alignment = r.alignment, | ||
| 842 | .@"addrspace" = r.@"addrspace", | ||
| 843 | .is_threadlocal = r.is_threadlocal, | ||
| 844 | .want_analysis = if (nav.analysis) |a| a.wanted else false, | ||
| 845 | }, | ||
| 846 | .fully_resolved => |r| .{ | ||
| 847 | .status = .fully_resolved, | ||
| 848 | .is_const = r.is_const, | ||
| 849 | .alignment = r.alignment, | ||
| 850 | .@"addrspace" = r.@"addrspace", | ||
| 851 | .is_threadlocal = false, | ||
| 852 | .want_analysis = if (nav.analysis) |a| a.wanted else false, | ||
| 853 | }, | ||
| 854 | }, | 741 | }, |
| 855 | }; | 742 | }; |
| 856 | } | 743 | } |
| ... | @@ -2110,7 +1997,6 @@ pub const Key = union(enum) { | ... | @@ -2110,7 +1997,6 @@ pub const Key = union(enum) { |
| 2110 | /// via `simple_value` and has a named `Index` tag for it. | 1997 | /// via `simple_value` and has a named `Index` tag for it. |
| 2111 | undef: Index, | 1998 | undef: Index, |
| 2112 | simple_value: SimpleValue, | 1999 | simple_value: SimpleValue, |
| 2113 | variable: Variable, | ||
| 2114 | @"extern": Extern, | 2000 | @"extern": Extern, |
| 2115 | func: Func, | 2001 | func: Func, |
| 2116 | int: Key.Int, | 2002 | int: Key.Int, |
| ... | @@ -2311,14 +2197,6 @@ pub const Key = union(enum) { | ... | @@ -2311,14 +2197,6 @@ pub const Key = union(enum) { |
| 2311 | } | 2197 | } |
| 2312 | }; | 2198 | }; |
| 2313 | 2199 | ||
| 2314 | /// A runtime variable defined in this `Zcu`. | ||
| 2315 | pub const Variable = struct { | ||
| 2316 | ty: Index, | ||
| 2317 | init: Index, | ||
| 2318 | owner_nav: Nav.Index, | ||
| 2319 | is_threadlocal: bool, | ||
| 2320 | }; | ||
| 2321 | |||
| 2322 | pub const Extern = struct { | 2200 | pub const Extern = struct { |
| 2323 | /// The name of the extern symbol. | 2201 | /// The name of the extern symbol. |
| 2324 | name: NullTerminatedString, | 2202 | name: NullTerminatedString, |
| ... | @@ -2543,7 +2421,7 @@ pub const Key = union(enum) { | ... | @@ -2543,7 +2421,7 @@ pub const Key = union(enum) { |
| 2543 | pub const BaseAddr = union(enum) { | 2421 | pub const BaseAddr = union(enum) { |
| 2544 | const Tag = @typeInfo(BaseAddr).@"union".tag_type.?; | 2422 | const Tag = @typeInfo(BaseAddr).@"union".tag_type.?; |
| 2545 | 2423 | ||
| 2546 | /// Points to the value of a single `Nav`, which may be constant or a `variable`. | 2424 | /// Points to the value of a single `Nav`. |
| 2547 | nav: Nav.Index, | 2425 | nav: Nav.Index, |
| 2548 | 2426 | ||
| 2549 | /// Points to the value of a single comptime alloc stored in `Sema`. | 2427 | /// Points to the value of a single comptime alloc stored in `Sema`. |
| ... | @@ -2735,8 +2613,6 @@ pub const Key = union(enum) { | ... | @@ -2735,8 +2613,6 @@ pub const Key = union(enum) { |
| 2735 | .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)), | 2613 | .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)), |
| 2736 | }, | 2614 | }, |
| 2737 | 2615 | ||
| 2738 | .variable => |variable| Hash.hash(seed, asBytes(&variable.owner_nav)), | ||
| 2739 | |||
| 2740 | .opaque_type, | 2616 | .opaque_type, |
| 2741 | .enum_type, | 2617 | .enum_type, |
| 2742 | .union_type, | 2618 | .union_type, |
| ... | @@ -3011,13 +2887,6 @@ pub const Key = union(enum) { | ... | @@ -3011,13 +2887,6 @@ pub const Key = union(enum) { |
| 3011 | return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val; | 2887 | return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val; |
| 3012 | }, | 2888 | }, |
| 3013 | 2889 | ||
| 3014 | .variable => |a_info| { | ||
| 3015 | const b_info = b.variable; | ||
| 3016 | return a_info.ty == b_info.ty and | ||
| 3017 | a_info.init == b_info.init and | ||
| 3018 | a_info.owner_nav == b_info.owner_nav and | ||
| 3019 | a_info.is_threadlocal == b_info.is_threadlocal; | ||
| 3020 | }, | ||
| 3021 | .@"extern" => |a_info| { | 2890 | .@"extern" => |a_info| { |
| 3022 | const b_info = b.@"extern"; | 2891 | const b_info = b.@"extern"; |
| 3023 | return a_info.name == b_info.name and | 2892 | return a_info.name == b_info.name and |
| ... | @@ -3277,7 +3146,6 @@ pub const Key = union(enum) { | ... | @@ -3277,7 +3146,6 @@ pub const Key = union(enum) { |
| 3277 | .int, | 3146 | .int, |
| 3278 | .float, | 3147 | .float, |
| 3279 | .opt, | 3148 | .opt, |
| 3280 | .variable, | ||
| 3281 | .@"extern", | 3149 | .@"extern", |
| 3282 | .func, | 3150 | .func, |
| 3283 | .err, | 3151 | .err, |
| ... | @@ -4390,8 +4258,6 @@ pub const Index = enum(u32) { | ... | @@ -4390,8 +4258,6 @@ pub const Index = enum(u32) { |
| 4390 | float_c_longdouble_f80: struct { data: *Float80 }, | 4258 | float_c_longdouble_f80: struct { data: *Float80 }, |
| 4391 | float_c_longdouble_f128: struct { data: *Float128 }, | 4259 | float_c_longdouble_f128: struct { data: *Float128 }, |
| 4392 | float_comptime_float: struct { data: *Float128 }, | 4260 | float_comptime_float: struct { data: *Float128 }, |
| 4393 | variable: struct { data: *Tag.Variable }, | ||
| 4394 | threadlocal_variable: struct { data: *Tag.Variable }, | ||
| 4395 | @"extern": struct { data: *Tag.Extern }, | 4261 | @"extern": struct { data: *Tag.Extern }, |
| 4396 | func_decl: struct { | 4262 | func_decl: struct { |
| 4397 | const @"data.analysis.inferred_error_set" = opaque {}; | 4263 | const @"data.analysis.inferred_error_set" = opaque {}; |
| ... | @@ -5115,12 +4981,6 @@ pub const Tag = enum(u8) { | ... | @@ -5115,12 +4981,6 @@ pub const Tag = enum(u8) { |
| 5115 | /// A comptime_float value. | 4981 | /// A comptime_float value. |
| 5116 | /// data is extra index to Float128. | 4982 | /// data is extra index to Float128. |
| 5117 | float_comptime_float, | 4983 | float_comptime_float, |
| 5118 | /// A global variable. | ||
| 5119 | /// data is extra index to Variable. | ||
| 5120 | variable, | ||
| 5121 | /// A global threadlocal variable. | ||
| 5122 | /// data is extra index to Variable. | ||
| 5123 | threadlocal_variable, | ||
| 5124 | /// An extern function or variable. | 4984 | /// An extern function or variable. |
| 5125 | /// data is extra index to Extern. | 4985 | /// data is extra index to Extern. |
| 5126 | /// Some parts of the key are stored in `owner_nav`. | 4986 | /// Some parts of the key are stored in `owner_nav`. |
| ... | @@ -5457,8 +5317,6 @@ pub const Tag = enum(u8) { | ... | @@ -5457,8 +5317,6 @@ pub const Tag = enum(u8) { |
| 5457 | .float_c_longdouble_f80 = .{ .summary = .@"@as(c_longdouble, {.payload%value})", .payload = f80 }, | 5317 | .float_c_longdouble_f80 = .{ .summary = .@"@as(c_longdouble, {.payload%value})", .payload = f80 }, |
| 5458 | .float_c_longdouble_f128 = .{ .summary = .@"@as(c_longdouble, {.payload%value})", .payload = f128 }, | 5318 | .float_c_longdouble_f128 = .{ .summary = .@"@as(c_longdouble, {.payload%value})", .payload = f128 }, |
| 5459 | .float_comptime_float = .{ .summary = .@"{.payload%value}", .payload = f128 }, | 5319 | .float_comptime_float = .{ .summary = .@"{.payload%value}", .payload = f128 }, |
| 5460 | .variable = .{ .summary = .@"{.payload.owner_nav.fqn%summary#\"}", .payload = Variable }, | ||
| 5461 | .threadlocal_variable = .{ .summary = .@"{.payload.owner_nav.fqn%summary#\"}", .payload = Variable }, | ||
| 5462 | .@"extern" = .{ .summary = .@"{.payload.owner_nav.fqn%summary#\"}", .payload = Extern }, | 5320 | .@"extern" = .{ .summary = .@"{.payload.owner_nav.fqn%summary#\"}", .payload = Extern }, |
| 5463 | .func_decl = .{ | 5321 | .func_decl = .{ |
| 5464 | .summary = .@"{.payload.owner_nav.fqn%summary#\"}", | 5322 | .summary = .@"{.payload.owner_nav.fqn%summary#\"}", |
| ... | @@ -5505,13 +5363,6 @@ pub const Tag = enum(u8) { | ... | @@ -5505,13 +5363,6 @@ pub const Tag = enum(u8) { |
| 5505 | return @field(encodings, @tagName(tag)).payload; | 5363 | return @field(encodings, @tagName(tag)).payload; |
| 5506 | } | 5364 | } |
| 5507 | 5365 | ||
| 5508 | pub const Variable = struct { | ||
| 5509 | ty: Index, | ||
| 5510 | /// May be `none`. | ||
| 5511 | init: Index, | ||
| 5512 | owner_nav: Nav.Index, | ||
| 5513 | }; | ||
| 5514 | |||
| 5515 | pub const Extern = struct { | 5366 | pub const Extern = struct { |
| 5516 | // name, is_const, alignment, addrspace come from `owner_nav`. | 5367 | // name, is_const, alignment, addrspace come from `owner_nav`. |
| 5517 | ty: Index, | 5368 | ty: Index, |
| ... | @@ -5525,12 +5376,11 @@ pub const Tag = enum(u8) { | ... | @@ -5525,12 +5376,11 @@ pub const Tag = enum(u8) { |
| 5525 | pub const Flags = packed struct(u32) { | 5376 | pub const Flags = packed struct(u32) { |
| 5526 | linkage: std.builtin.GlobalLinkage, | 5377 | linkage: std.builtin.GlobalLinkage, |
| 5527 | visibility: std.builtin.SymbolVisibility, | 5378 | visibility: std.builtin.SymbolVisibility, |
| 5528 | is_threadlocal: bool, | ||
| 5529 | is_dll_import: bool, | 5379 | is_dll_import: bool, |
| 5530 | relocation: std.builtin.ExternOptions.Relocation, | 5380 | relocation: std.builtin.ExternOptions.Relocation, |
| 5531 | source: Source, | 5381 | source: Source, |
| 5532 | decoration_type: DecorationType, | 5382 | decoration_type: DecorationType, |
| 5533 | _: u22 = 0, | 5383 | _: u23 = 0, |
| 5534 | 5384 | ||
| 5535 | pub const Source = enum(u1) { builtin, syntax }; | 5385 | pub const Source = enum(u1) { builtin, syntax }; |
| 5536 | pub const DecorationType = enum(u2) { none, location, descriptor }; | 5386 | pub const DecorationType = enum(u2) { none, location, descriptor }; |
| ... | @@ -6894,19 +6744,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6894,19 +6744,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6894 | .ty = .comptime_float_type, | 6744 | .ty = .comptime_float_type, |
| 6895 | .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() }, | 6745 | .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() }, |
| 6896 | } }, | 6746 | } }, |
| 6897 | .variable, .threadlocal_variable => { | ||
| 6898 | const extra = extraData(unwrapped_index.getExtra(ip), Tag.Variable, data); | ||
| 6899 | return .{ .variable = .{ | ||
| 6900 | .ty = extra.ty, | ||
| 6901 | .init = extra.init, | ||
| 6902 | .owner_nav = extra.owner_nav, | ||
| 6903 | .is_threadlocal = switch (item.tag) { | ||
| 6904 | else => unreachable, | ||
| 6905 | .variable => false, | ||
| 6906 | .threadlocal_variable => true, | ||
| 6907 | }, | ||
| 6908 | } }; | ||
| 6909 | }, | ||
| 6910 | .@"extern" => { | 6747 | .@"extern" => { |
| 6911 | const extra = extraData(unwrapped_index.getExtra(ip), Tag.Extern, data); | 6748 | const extra = extraData(unwrapped_index.getExtra(ip), Tag.Extern, data); |
| 6912 | const nav = ip.getNav(extra.owner_nav); | 6749 | const nav = ip.getNav(extra.owner_nav); |
| ... | @@ -6916,13 +6753,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6916,13 +6753,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6916 | .lib_name = extra.lib_name, | 6753 | .lib_name = extra.lib_name, |
| 6917 | .linkage = extra.flags.linkage, | 6754 | .linkage = extra.flags.linkage, |
| 6918 | .visibility = extra.flags.visibility, | 6755 | .visibility = extra.flags.visibility, |
| 6919 | .is_threadlocal = extra.flags.is_threadlocal, | 6756 | .is_threadlocal = nav.resolved.?.@"threadlocal", |
| 6920 | .is_dll_import = extra.flags.is_dll_import, | 6757 | .is_dll_import = extra.flags.is_dll_import, |
| 6921 | .relocation = extra.flags.relocation, | 6758 | .relocation = extra.flags.relocation, |
| 6922 | .decoration = extra.decoration(), | 6759 | .decoration = extra.decoration(), |
| 6923 | .is_const = nav.status.fully_resolved.is_const, | 6760 | .is_const = nav.resolved.?.@"const", |
| 6924 | .alignment = nav.status.fully_resolved.alignment, | 6761 | .alignment = nav.resolved.?.@"align", |
| 6925 | .@"addrspace" = nav.status.fully_resolved.@"addrspace", | 6762 | .@"addrspace" = nav.resolved.?.@"addrspace", |
| 6926 | .zir_index = extra.zir_index, | 6763 | .zir_index = extra.zir_index, |
| 6927 | .owner_nav = extra.owner_nav, | 6764 | .owner_nav = extra.owner_nav, |
| 6928 | .source = extra.flags.source, | 6765 | .source = extra.flags.source, |
| ... | @@ -7516,22 +7353,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: | ... | @@ -7516,22 +7353,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7516 | .func => unreachable, // use getFuncInstance() or getFuncDecl() instead | 7353 | .func => unreachable, // use getFuncInstance() or getFuncDecl() instead |
| 7517 | .un => unreachable, // use getUnion instead | 7354 | .un => unreachable, // use getUnion instead |
| 7518 | 7355 | ||
| 7519 | .variable => |variable| { | ||
| 7520 | const has_init = variable.init != .none; | ||
| 7521 | if (has_init) assert(variable.ty == ip.typeOf(variable.init)); | ||
| 7522 | items.appendAssumeCapacity(.{ | ||
| 7523 | .tag = switch (variable.is_threadlocal) { | ||
| 7524 | false => .variable, | ||
| 7525 | true => .threadlocal_variable, | ||
| 7526 | }, | ||
| 7527 | .data = try addExtra(extra, Tag.Variable{ | ||
| 7528 | .ty = variable.ty, | ||
| 7529 | .init = variable.init, | ||
| 7530 | .owner_nav = variable.owner_nav, | ||
| 7531 | }), | ||
| 7532 | }); | ||
| 7533 | }, | ||
| 7534 | |||
| 7535 | .slice => |slice| { | 7356 | .slice => |slice| { |
| 7536 | assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .slice); | 7357 | assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .slice); |
| 7537 | assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .many); | 7358 | assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .many); |
| ... | @@ -9245,14 +9066,15 @@ pub fn getExtern( | ... | @@ -9245,14 +9066,15 @@ pub fn getExtern( |
| 9245 | .tid = tid, | 9066 | .tid = tid, |
| 9246 | .index = items.mutate.len, | 9067 | .index = items.mutate.len, |
| 9247 | }, ip); | 9068 | }, ip); |
| 9248 | const owner_nav = ip.createNav(gpa, io, tid, .{ | 9069 | const owner_nav = ip.createNav(gpa, io, tid, key.name, key.name, .{ |
| 9249 | .name = key.name, | 9070 | .type = key.ty, |
| 9250 | .fqn = key.name, | 9071 | .@"align" = key.alignment, |
| 9251 | .val = extern_index, | ||
| 9252 | .is_const = key.is_const, | ||
| 9253 | .alignment = key.alignment, | ||
| 9254 | .@"linksection" = .none, | 9072 | .@"linksection" = .none, |
| 9255 | .@"addrspace" = key.@"addrspace", | 9073 | .@"addrspace" = key.@"addrspace", |
| 9074 | .@"const" = key.is_const, | ||
| 9075 | .@"threadlocal" = key.is_threadlocal, | ||
| 9076 | .is_extern_decl = true, | ||
| 9077 | .value = extern_index, | ||
| 9256 | }) catch unreachable; // capacity asserted above | 9078 | }) catch unreachable; // capacity asserted above |
| 9257 | const decoration_type, const location_or_descriptor_set, const descriptor_binding = if (key.decoration) |decoration| switch (decoration) { | 9079 | const decoration_type, const location_or_descriptor_set, const descriptor_binding = if (key.decoration) |decoration| switch (decoration) { |
| 9258 | .location => |location| .{ Tag.Extern.Flags.DecorationType.location, location, undefined }, | 9080 | .location => |location| .{ Tag.Extern.Flags.DecorationType.location, location, undefined }, |
| ... | @@ -9266,7 +9088,6 @@ pub fn getExtern( | ... | @@ -9266,7 +9088,6 @@ pub fn getExtern( |
| 9266 | .flags = .{ | 9088 | .flags = .{ |
| 9267 | .linkage = key.linkage, | 9089 | .linkage = key.linkage, |
| 9268 | .visibility = key.visibility, | 9090 | .visibility = key.visibility, |
| 9269 | .is_threadlocal = key.is_threadlocal, | ||
| 9270 | .is_dll_import = key.is_dll_import, | 9091 | .is_dll_import = key.is_dll_import, |
| 9271 | .relocation = key.relocation, | 9092 | .relocation = key.relocation, |
| 9272 | .decoration_type = decoration_type, | 9093 | .decoration_type = decoration_type, |
| ... | @@ -9846,14 +9667,16 @@ fn finishFuncInstance( | ... | @@ -9846,14 +9667,16 @@ fn finishFuncInstance( |
| 9846 | const nav_name = try ip.getOrPutStringFmt(gpa, io, tid, "{f}__anon_{d}", .{ | 9667 | const nav_name = try ip.getOrPutStringFmt(gpa, io, tid, "{f}__anon_{d}", .{ |
| 9847 | fn_owner_nav.name.fmt(ip), @intFromEnum(func_index), | 9668 | fn_owner_nav.name.fmt(ip), @intFromEnum(func_index), |
| 9848 | }, .no_embedded_nulls); | 9669 | }, .no_embedded_nulls); |
| 9849 | const nav_index = try ip.createNav(gpa, io, tid, .{ | 9670 | const nav_fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, io, tid, nav_name); |
| 9850 | .name = nav_name, | 9671 | const nav_index = try ip.createNav(gpa, io, tid, nav_name, nav_fqn, .{ |
| 9851 | .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, io, tid, nav_name), | 9672 | .type = ip.typeOf(func_index), |
| 9852 | .val = func_index, | 9673 | .@"align" = fn_owner_nav.resolved.?.@"align", |
| 9853 | .is_const = fn_owner_nav.status.fully_resolved.is_const, | 9674 | .@"linksection" = fn_owner_nav.resolved.?.@"linksection", |
| 9854 | .alignment = fn_owner_nav.status.fully_resolved.alignment, | 9675 | .@"addrspace" = fn_owner_nav.resolved.?.@"addrspace", |
| 9855 | .@"linksection" = fn_owner_nav.status.fully_resolved.@"linksection", | 9676 | .@"const" = true, |
| 9856 | .@"addrspace" = fn_owner_nav.status.fully_resolved.@"addrspace", | 9677 | .@"threadlocal" = false, |
| 9678 | .is_extern_decl = false, | ||
| 9679 | .value = func_index, | ||
| 9857 | }); | 9680 | }); |
| 9858 | 9681 | ||
| 9859 | // Populate the owner_nav field which was left undefined until now. | 9682 | // Populate the owner_nav field which was left undefined until now. |
| ... | @@ -10616,20 +10439,6 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index { | ... | @@ -10616,20 +10439,6 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index { |
| 10616 | return ip.indexToKey(ty).error_union_type.payload_type; | 10439 | return ip.indexToKey(ty).error_union_type.payload_type; |
| 10617 | } | 10440 | } |
| 10618 | 10441 | ||
| 10619 | /// The is only legal because the initializer is not part of the hash. | ||
| 10620 | pub fn mutateVarInit(ip: *InternPool, io: Io, index: Index, init_index: Index) void { | ||
| 10621 | const unwrapped_index = index.unwrap(ip); | ||
| 10622 | |||
| 10623 | const local = ip.getLocal(unwrapped_index.tid); | ||
| 10624 | local.mutate.extra.mutex.lockUncancelable(io); | ||
| 10625 | defer local.mutate.extra.mutex.unlock(io); | ||
| 10626 | |||
| 10627 | const extra_items = local.shared.extra.view().items(.@"0"); | ||
| 10628 | const item = unwrapped_index.getItem(ip); | ||
| 10629 | assert(item.tag == .variable); | ||
| 10630 | @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release); | ||
| 10631 | } | ||
| 10632 | |||
| 10633 | pub fn dump(ip: *const InternPool) void { | 10442 | pub fn dump(ip: *const InternPool) void { |
| 10634 | var buffer: [4096]u8 = undefined; | 10443 | var buffer: [4096]u8 = undefined; |
| 10635 | const stderr = std.debug.lockStderr(&buffer); | 10444 | const stderr = std.debug.lockStderr(&buffer); |
| ... | @@ -10969,7 +10778,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo | ... | @@ -10969,7 +10778,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo |
| 10969 | .float_c_longdouble_f80 => @sizeOf(Float80), | 10778 | .float_c_longdouble_f80 => @sizeOf(Float80), |
| 10970 | .float_c_longdouble_f128 => @sizeOf(Float128), | 10779 | .float_c_longdouble_f128 => @sizeOf(Float128), |
| 10971 | .float_comptime_float => @sizeOf(Float128), | 10780 | .float_comptime_float => @sizeOf(Float128), |
| 10972 | .variable, .threadlocal_variable => @sizeOf(Tag.Variable), | ||
| 10973 | .@"extern" => @sizeOf(Tag.Extern), | 10781 | .@"extern" => @sizeOf(Tag.Extern), |
| 10974 | .func_decl => @sizeOf(Tag.FuncDecl), | 10782 | .func_decl => @sizeOf(Tag.FuncDecl), |
| 10975 | .func_instance => b: { | 10783 | .func_instance => b: { |
| ... | @@ -11089,8 +10897,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { | ... | @@ -11089,8 +10897,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void { |
| 11089 | .float_c_longdouble_f80, | 10897 | .float_c_longdouble_f80, |
| 11090 | .float_c_longdouble_f128, | 10898 | .float_c_longdouble_f128, |
| 11091 | .float_comptime_float, | 10899 | .float_comptime_float, |
| 11092 | .variable, | ||
| 11093 | .threadlocal_variable, | ||
| 11094 | .@"extern", | 10900 | .@"extern", |
| 11095 | .func_decl, | 10901 | .func_decl, |
| 11096 | .func_instance, | 10902 | .func_instance, |
| ... | @@ -11175,8 +10981,24 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator, | ... | @@ -11175,8 +10981,24 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator, |
| 11175 | 10981 | ||
| 11176 | pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav { | 10982 | pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav { |
| 11177 | const unwrapped = index.unwrap(ip); | 10983 | const unwrapped = index.unwrap(ip); |
| 11178 | const navs = ip.getLocalShared(unwrapped.tid).navs.acquire(); | 10984 | const view = ip.getLocalShared(unwrapped.tid).navs.acquire().view(); |
| 11179 | return navs.view().get(unwrapped.index).unpack(); | 10985 | // We can't just call `view.get(unwrapped.index)`, because a concurrent call to `resolveNav` |
| 10986 | // could be writing to fields, making a non-atomic load illegal. Instead, atomically load | ||
| 10987 | // each field. We don't need any ordering guarantees because if we need to see (e.g.) the | ||
| 10988 | // resolved type of a `Nav`, that information should have already been released to our caller. | ||
| 10989 | const repr: Nav.Repr = .{ | ||
| 10990 | // Load the first few fields non-atomically---they are never mutated after `Nav` creation. | ||
| 10991 | .name = view.items(.name)[unwrapped.index], | ||
| 10992 | .fqn = view.items(.fqn)[unwrapped.index], | ||
| 10993 | .analysis_namespace = view.items(.analysis_namespace)[unwrapped.index], | ||
| 10994 | .analysis_zir_index = view.items(.analysis_zir_index)[unwrapped.index], | ||
| 10995 | // The last few fields are populated by `resolveNav` so must be loaded atomically. | ||
| 10996 | .type = @atomicLoad(InternPool.Index, &view.items(.type)[unwrapped.index], .monotonic), | ||
| 10997 | .value = @atomicLoad(InternPool.Index, &view.items(.value)[unwrapped.index], .monotonic), | ||
| 10998 | .@"linksection" = @atomicLoad(OptionalNullTerminatedString, &view.items(.@"linksection")[unwrapped.index], .monotonic), | ||
| 10999 | .bits = @atomicLoad(Nav.Repr.Bits, &view.items(.bits)[unwrapped.index], .monotonic), | ||
| 11000 | }; | ||
| 11001 | return repr.unpack(); | ||
| 11180 | } | 11002 | } |
| 11181 | 11003 | ||
| 11182 | pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace { | 11004 | pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace { |
| ... | @@ -11220,15 +11042,9 @@ fn createNav( | ... | @@ -11220,15 +11042,9 @@ fn createNav( |
| 11220 | gpa: Allocator, | 11042 | gpa: Allocator, |
| 11221 | io: Io, | 11043 | io: Io, |
| 11222 | tid: Zcu.PerThread.Id, | 11044 | tid: Zcu.PerThread.Id, |
| 11223 | opts: struct { | 11045 | name: NullTerminatedString, |
| 11224 | name: NullTerminatedString, | 11046 | fqn: NullTerminatedString, |
| 11225 | fqn: NullTerminatedString, | 11047 | resolved: @typeInfo(@FieldType(Nav, "resolved")).optional.child, |
| 11226 | val: InternPool.Index, | ||
| 11227 | is_const: bool, | ||
| 11228 | alignment: Alignment, | ||
| 11229 | @"linksection": OptionalNullTerminatedString, | ||
| 11230 | @"addrspace": std.builtin.AddressSpace, | ||
| 11231 | }, | ||
| 11232 | ) Allocator.Error!Nav.Index { | 11048 | ) Allocator.Error!Nav.Index { |
| 11233 | const navs = ip.getLocal(tid).getMutableNavs(gpa, io); | 11049 | const navs = ip.getLocal(tid).getMutableNavs(gpa, io); |
| 11234 | const index_unwrapped: Nav.Index.Unwrapped = .{ | 11050 | const index_unwrapped: Nav.Index.Unwrapped = .{ |
| ... | @@ -11236,16 +11052,10 @@ fn createNav( | ... | @@ -11236,16 +11052,10 @@ fn createNav( |
| 11236 | .index = navs.mutate.len, | 11052 | .index = navs.mutate.len, |
| 11237 | }; | 11053 | }; |
| 11238 | try navs.append(Nav.pack(.{ | 11054 | try navs.append(Nav.pack(.{ |
| 11239 | .name = opts.name, | 11055 | .name = name, |
| 11240 | .fqn = opts.fqn, | 11056 | .fqn = fqn, |
| 11241 | .analysis = null, | 11057 | .analysis = null, |
| 11242 | .status = .{ .fully_resolved = .{ | 11058 | .resolved = resolved, |
| 11243 | .val = opts.val, | ||
| 11244 | .is_const = opts.is_const, | ||
| 11245 | .alignment = opts.alignment, | ||
| 11246 | .@"linksection" = opts.@"linksection", | ||
| 11247 | .@"addrspace" = opts.@"addrspace", | ||
| 11248 | } }, | ||
| 11249 | })); | 11059 | })); |
| 11250 | return index_unwrapped.wrap(ip); | 11060 | return index_unwrapped.wrap(ip); |
| 11251 | } | 11061 | } |
| ... | @@ -11279,27 +11089,19 @@ pub fn createDeclNav( | ... | @@ -11279,27 +11089,19 @@ pub fn createDeclNav( |
| 11279 | .zir_index = zir_index, | 11089 | .zir_index = zir_index, |
| 11280 | .wanted = false, | 11090 | .wanted = false, |
| 11281 | }, | 11091 | }, |
| 11282 | .status = .unresolved, | 11092 | .resolved = null, |
| 11283 | })); | 11093 | })); |
| 11284 | 11094 | ||
| 11285 | return nav; | 11095 | return nav; |
| 11286 | } | 11096 | } |
| 11287 | 11097 | ||
| 11288 | /// Resolve the type of a `Nav` with an analysis owner. | 11098 | /// Resolve the type (and possibly the value) of a `Nav` with an analysis owner. |
| 11289 | /// If its status is already `resolved`, the old value is discarded. | 11099 | /// If its status is already `resolved`, the old value is discarded. |
| 11290 | pub fn resolveNavType( | 11100 | pub fn resolveNav( |
| 11291 | ip: *InternPool, | 11101 | ip: *InternPool, |
| 11292 | io: Io, | 11102 | io: Io, |
| 11293 | nav: Nav.Index, | 11103 | nav: Nav.Index, |
| 11294 | resolved: struct { | 11104 | resolved: @typeInfo(@FieldType(Nav, "resolved")).optional.child, |
| 11295 | type: InternPool.Index, | ||
| 11296 | is_const: bool, | ||
| 11297 | alignment: Alignment, | ||
| 11298 | @"linksection": OptionalNullTerminatedString, | ||
| 11299 | @"addrspace": std.builtin.AddressSpace, | ||
| 11300 | is_threadlocal: bool, | ||
| 11301 | is_extern_decl: bool, | ||
| 11302 | }, | ||
| 11303 | ) void { | 11105 | ) void { |
| 11304 | const unwrapped = nav.unwrap(ip); | 11106 | const unwrapped = nav.unwrap(ip); |
| 11305 | 11107 | ||
| ... | @@ -11311,65 +11113,45 @@ pub fn resolveNavType( | ... | @@ -11311,65 +11113,45 @@ pub fn resolveNavType( |
| 11311 | 11113 | ||
| 11312 | const nav_analysis_namespace = navs.items(.analysis_namespace); | 11114 | const nav_analysis_namespace = navs.items(.analysis_namespace); |
| 11313 | const nav_analysis_zir_index = navs.items(.analysis_zir_index); | 11115 | const nav_analysis_zir_index = navs.items(.analysis_zir_index); |
| 11314 | const nav_types = navs.items(.type_or_val); | 11116 | const nav_types = navs.items(.type); |
| 11117 | const nav_values = navs.items(.value); | ||
| 11315 | const nav_linksections = navs.items(.@"linksection"); | 11118 | const nav_linksections = navs.items(.@"linksection"); |
| 11316 | const nav_bits = navs.items(.bits); | 11119 | const nav_bits = navs.items(.bits); |
| 11317 | 11120 | ||
| 11318 | assert(nav_analysis_namespace[unwrapped.index] != .none); | 11121 | assert(nav_analysis_namespace[unwrapped.index] != .none); |
| 11319 | assert(nav_analysis_zir_index[unwrapped.index] != .none); | 11122 | assert(nav_analysis_zir_index[unwrapped.index] != .none); |
| 11320 | 11123 | ||
| 11321 | @atomicStore(InternPool.Index, &nav_types[unwrapped.index], resolved.type, .release); | 11124 | @atomicStore( |
| 11322 | @atomicStore(OptionalNullTerminatedString, &nav_linksections[unwrapped.index], resolved.@"linksection", .release); | 11125 | OptionalNullTerminatedString, |
| 11323 | 11126 | &nav_linksections[unwrapped.index], | |
| 11324 | var bits = nav_bits[unwrapped.index]; | 11127 | resolved.@"linksection", |
| 11325 | bits.status = if (resolved.is_extern_decl) .type_resolved_extern_decl else .type_resolved; | 11128 | .monotonic, |
| 11326 | bits.is_const = resolved.is_const; | 11129 | ); |
| 11327 | bits.alignment = resolved.alignment; | ||
| 11328 | bits.@"addrspace" = resolved.@"addrspace"; | ||
| 11329 | bits.is_threadlocal = resolved.is_threadlocal; | ||
| 11330 | @atomicStore(Nav.Repr.Bits, &nav_bits[unwrapped.index], bits, .release); | ||
| 11331 | } | ||
| 11332 | |||
| 11333 | /// Resolve the value of a `Nav` with an analysis owner. | ||
| 11334 | /// If its status is already `resolved`, the old value is discarded. | ||
| 11335 | pub fn resolveNavValue( | ||
| 11336 | ip: *InternPool, | ||
| 11337 | io: Io, | ||
| 11338 | nav: Nav.Index, | ||
| 11339 | resolved: struct { | ||
| 11340 | val: InternPool.Index, | ||
| 11341 | is_const: bool, | ||
| 11342 | alignment: Alignment, | ||
| 11343 | @"linksection": OptionalNullTerminatedString, | ||
| 11344 | @"addrspace": std.builtin.AddressSpace, | ||
| 11345 | }, | ||
| 11346 | ) void { | ||
| 11347 | const unwrapped = nav.unwrap(ip); | ||
| 11348 | |||
| 11349 | const local = ip.getLocal(unwrapped.tid); | ||
| 11350 | local.mutate.extra.mutex.lockUncancelable(io); | ||
| 11351 | defer local.mutate.extra.mutex.unlock(io); | ||
| 11352 | |||
| 11353 | const navs = local.shared.navs.view(); | ||
| 11354 | |||
| 11355 | const nav_analysis_namespace = navs.items(.analysis_namespace); | ||
| 11356 | const nav_analysis_zir_index = navs.items(.analysis_zir_index); | ||
| 11357 | const nav_vals = navs.items(.type_or_val); | ||
| 11358 | const nav_linksections = navs.items(.@"linksection"); | ||
| 11359 | const nav_bits = navs.items(.bits); | ||
| 11360 | |||
| 11361 | assert(nav_analysis_namespace[unwrapped.index] != .none); | ||
| 11362 | assert(nav_analysis_zir_index[unwrapped.index] != .none); | ||
| 11363 | 11130 | ||
| 11364 | @atomicStore(InternPool.Index, &nav_vals[unwrapped.index], resolved.val, .release); | 11131 | const bits = &nav_bits[unwrapped.index]; |
| 11365 | @atomicStore(OptionalNullTerminatedString, &nav_linksections[unwrapped.index], resolved.@"linksection", .release); | 11132 | assert(@atomicLoad(Nav.Repr.Bits, bits, .monotonic).want_analysis); // otherwise we wouldn't be resolving `nav` at all |
| 11133 | @atomicStore(Nav.Repr.Bits, bits, .{ | ||
| 11134 | .@"align" = resolved.@"align", | ||
| 11135 | .@"addrspace" = resolved.@"addrspace", | ||
| 11136 | .@"const" = resolved.@"const", | ||
| 11137 | .@"threadlocal" = resolved.@"threadlocal", | ||
| 11138 | .is_extern_decl = resolved.is_extern_decl, | ||
| 11139 | .want_analysis = true, // asserted above that this is already `true` | ||
| 11140 | }, .monotonic); | ||
| 11141 | |||
| 11142 | @atomicStore( | ||
| 11143 | InternPool.Index, | ||
| 11144 | &nav_types[unwrapped.index], | ||
| 11145 | resolved.type, | ||
| 11146 | .monotonic, | ||
| 11147 | ); | ||
| 11366 | 11148 | ||
| 11367 | var bits = nav_bits[unwrapped.index]; | 11149 | @atomicStore( |
| 11368 | bits.status = .fully_resolved; | 11150 | InternPool.Index, |
| 11369 | bits.is_const = resolved.is_const; | 11151 | &nav_values[unwrapped.index], |
| 11370 | bits.alignment = resolved.alignment; | 11152 | resolved.value, |
| 11371 | bits.@"addrspace" = resolved.@"addrspace"; | 11153 | .monotonic, |
| 11372 | @atomicStore(Nav.Repr.Bits, &nav_bits[unwrapped.index], bits, .release); | 11154 | ); |
| 11373 | } | 11155 | } |
| 11374 | 11156 | ||
| 11375 | pub fn createNamespace( | 11157 | pub fn createNamespace( |
| ... | @@ -11841,8 +11623,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { | ... | @@ -11841,8 +11623,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 11841 | .error_set_error, | 11623 | .error_set_error, |
| 11842 | .error_union_error, | 11624 | .error_union_error, |
| 11843 | .enum_tag, | 11625 | .enum_tag, |
| 11844 | .variable, | ||
| 11845 | .threadlocal_variable, | ||
| 11846 | .@"extern", | 11626 | .@"extern", |
| 11847 | .func_decl, | 11627 | .func_decl, |
| 11848 | .func_instance, | 11628 | .func_instance, |
| ... | @@ -11949,11 +11729,7 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index { | ... | @@ -11949,11 +11729,7 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index { |
| 11949 | } | 11729 | } |
| 11950 | 11730 | ||
| 11951 | pub fn isUndef(ip: *const InternPool, val: Index) bool { | 11731 | pub fn isUndef(ip: *const InternPool, val: Index) bool { |
| 11952 | return val == .undef or val.unwrap(ip).getTag(ip) == .undef; | 11732 | return val.unwrap(ip).getTag(ip) == .undef; |
| 11953 | } | ||
| 11954 | |||
| 11955 | pub fn isVariable(ip: *const InternPool, val: Index) bool { | ||
| 11956 | return val.unwrap(ip).getTag(ip) == .variable; | ||
| 11957 | } | 11733 | } |
| 11958 | 11734 | ||
| 11959 | pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag { | 11735 | pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag { |
| ... | @@ -12220,8 +11996,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { | ... | @@ -12220,8 +11996,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId { |
| 12220 | .float_c_longdouble_f80, | 11996 | .float_c_longdouble_f80, |
| 12221 | .float_c_longdouble_f128, | 11997 | .float_c_longdouble_f128, |
| 12222 | .float_comptime_float, | 11998 | .float_comptime_float, |
| 12223 | .variable, | ||
| 12224 | .threadlocal_variable, | ||
| 12225 | .@"extern", | 11999 | .@"extern", |
| 12226 | .func_decl, | 12000 | .func_decl, |
| 12227 | .func_instance, | 12001 | .func_instance, |
| ... | @@ -13001,11 +12775,17 @@ pub fn setWantNavAnalysis(ip: *InternPool, io: Io, nav_index: Nav.Index) bool { | ... | @@ -13001,11 +12775,17 @@ pub fn setWantNavAnalysis(ip: *InternPool, io: Io, nav_index: Nav.Index) bool { |
| 13001 | return false; | 12775 | return false; |
| 13002 | } | 12776 | } |
| 13003 | 12777 | ||
| 13004 | const bits = &navs.items(.bits)[unwrapped.index]; | 12778 | // Mutate `bits` atomically so that we don't introduce an illegal data race with `getNav`. |
| 13005 | if (bits.want_analysis) { | 12779 | const old_bits = @atomicRmw( |
| 13006 | return false; | 12780 | Nav.Repr.Bits, |
| 13007 | } else { | 12781 | &navs.items(.bits)[unwrapped.index], |
| 13008 | bits.want_analysis = true; | 12782 | .Or, |
| 13009 | return true; | 12783 | mask: { |
| 13010 | } | 12784 | var mask: Nav.Repr.Bits = @bitCast(@as(u16, 0)); |
| 12785 | mask.want_analysis = true; | ||
| 12786 | break :mask mask; | ||
| 12787 | }, | ||
| 12788 | .monotonic, | ||
| 12789 | ); | ||
| 12790 | return !old_bits.want_analysis; | ||
| 13011 | } | 12791 | } |
src/Sema.zig+60-57| ... | @@ -2276,28 +2276,26 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) ?Value { | ... | @@ -2276,28 +2276,26 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) ?Value { |
| 2276 | assert(inst != .none); | 2276 | assert(inst != .none); |
| 2277 | 2277 | ||
| 2278 | if (inst.toInterned()) |ip_index| { | 2278 | if (inst.toInterned()) |ip_index| { |
| 2279 | const val: Value = .fromInterned(ip_index); | 2279 | return .fromInterned(ip_index); |
| 2280 | assert(val.getVariable(zcu) == null); | ||
| 2281 | return val; | ||
| 2282 | } else { | ||
| 2283 | // Runtime-known value. | ||
| 2284 | const air_tags = sema.air_instructions.items(.tag); | ||
| 2285 | switch (air_tags[@intFromEnum(inst.toIndex().?)]) { | ||
| 2286 | .inferred_alloc => unreachable, // assertion failure | ||
| 2287 | .inferred_alloc_comptime => unreachable, // assertion failure | ||
| 2288 | else => {}, | ||
| 2289 | } | ||
| 2290 | // LLVM fails to eliminate this `classify` call in ReleaseFast, which hurts performance, so | ||
| 2291 | // we must explicitly check for `std.debug.runtime_safety`. | ||
| 2292 | if (std.debug.runtime_safety) switch (sema.typeOf(inst).classify(zcu)) { | ||
| 2293 | .no_possible_value => unreachable, // values of this type do not exist | ||
| 2294 | .one_possible_value => unreachable, // the value should be comptime-known | ||
| 2295 | .partially_comptime => unreachable, // the value should be comptime-known | ||
| 2296 | .fully_comptime => unreachable, // the value should be comptime-known | ||
| 2297 | .runtime => {}, | ||
| 2298 | }; | ||
| 2299 | return null; | ||
| 2300 | } | 2280 | } |
| 2281 | |||
| 2282 | // Runtime-known value. We'll be returning `null`, but first, some assertions. | ||
| 2283 | const air_tags = sema.air_instructions.items(.tag); | ||
| 2284 | switch (air_tags[@intFromEnum(inst.toIndex().?)]) { | ||
| 2285 | .inferred_alloc => unreachable, // assertion failure | ||
| 2286 | .inferred_alloc_comptime => unreachable, // assertion failure | ||
| 2287 | else => {}, | ||
| 2288 | } | ||
| 2289 | // LLVM fails to eliminate this `classify` call in ReleaseFast, which hurts performance, so | ||
| 2290 | // we must explicitly check for `std.debug.runtime_safety`. | ||
| 2291 | if (std.debug.runtime_safety) switch (sema.typeOf(inst).classify(zcu)) { | ||
| 2292 | .no_possible_value => unreachable, // values of this type do not exist | ||
| 2293 | .one_possible_value => unreachable, // the value should be comptime-known | ||
| 2294 | .partially_comptime => unreachable, // the value should be comptime-known | ||
| 2295 | .fully_comptime => unreachable, // the value should be comptime-known | ||
| 2296 | .runtime => {}, | ||
| 2297 | }; | ||
| 2298 | return null; | ||
| 2301 | } | 2299 | } |
| 2302 | 2300 | ||
| 2303 | /// Like `resolveValue`, but emits an error if the value is not comptime-known. | 2301 | /// Like `resolveValue`, but emits an error if the value is not comptime-known. |
| ... | @@ -5738,8 +5736,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -5738,8 +5736,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 5738 | .uav => |uav| .{ .uav = uav.val }, | 5736 | .uav => |uav| .{ .uav = uav.val }, |
| 5739 | .nav => |orig_nav| target: { | 5737 | .nav => |orig_nav| target: { |
| 5740 | try sema.ensureNavResolved(block, src, orig_nav, .fully); | 5738 | try sema.ensureNavResolved(block, src, orig_nav, .fully); |
| 5741 | const export_nav = switch (ip.indexToKey(ip.getNav(orig_nav).status.fully_resolved.val)) { | 5739 | const export_nav = switch (ip.indexToKey(ip.getNav(orig_nav).resolved.?.value)) { |
| 5742 | .variable => |v| v.owner_nav, | ||
| 5743 | .@"extern" => |e| e.owner_nav, | 5740 | .@"extern" => |e| e.owner_nav, |
| 5744 | .func => |f| f.owner_nav, | 5741 | .func => |f| f.owner_nav, |
| 5745 | else => orig_nav, | 5742 | else => orig_nav, |
| ... | @@ -5778,7 +5775,7 @@ pub fn analyzeExportSelfNav( | ... | @@ -5778,7 +5775,7 @@ pub fn analyzeExportSelfNav( |
| 5778 | const ip = &zcu.intern_pool; | 5775 | const ip = &zcu.intern_pool; |
| 5779 | 5776 | ||
| 5780 | const orig_nav = sema.owner.unwrap().nav_val; | 5777 | const orig_nav = sema.owner.unwrap().nav_val; |
| 5781 | const export_val: Value = .fromInterned(ip.getNav(orig_nav).status.fully_resolved.val); | 5778 | const export_val: Value = .fromInterned(ip.getNav(orig_nav).resolved.?.value); |
| 5782 | const export_ty = export_val.typeOf(zcu); | 5779 | const export_ty = export_val.typeOf(zcu); |
| 5783 | 5780 | ||
| 5784 | if (!export_ty.validateExtern(.other, zcu)) { | 5781 | if (!export_ty.validateExtern(.other, zcu)) { |
| ... | @@ -5792,7 +5789,6 @@ pub fn analyzeExportSelfNav( | ... | @@ -5792,7 +5789,6 @@ pub fn analyzeExportSelfNav( |
| 5792 | } | 5789 | } |
| 5793 | 5790 | ||
| 5794 | const export_nav = switch (ip.indexToKey(export_val.toIntern())) { | 5791 | const export_nav = switch (ip.indexToKey(export_val.toIntern())) { |
| 5795 | .variable => |v| v.owner_nav, | ||
| 5796 | .@"extern" => |e| e.owner_nav, | 5792 | .@"extern" => |e| e.owner_nav, |
| 5797 | .func => |f| export_nav: { | 5793 | .func => |f| export_nav: { |
| 5798 | assert(export_ty.fnHasRuntimeBits(zcu)); // otherwise `validateExtern` failed above | 5794 | assert(export_ty.fnHasRuntimeBits(zcu)); // otherwise `validateExtern` failed above |
| ... | @@ -30005,7 +30001,7 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: | ... | @@ -30005,7 +30001,7 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: |
| 30005 | 30001 | ||
| 30006 | const nav = ip.getNav(nav_index); | 30002 | const nav = ip.getNav(nav_index); |
| 30007 | if (nav.analysis == null) { | 30003 | if (nav.analysis == null) { |
| 30008 | assert(nav.status == .fully_resolved); | 30004 | assert(nav.resolved.?.value != .none); |
| 30009 | return; | 30005 | return; |
| 30010 | } | 30006 | } |
| 30011 | 30007 | ||
| ... | @@ -30066,11 +30062,20 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde | ... | @@ -30066,11 +30062,20 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde |
| 30066 | try sema.ensureNavResolved(block, src, orig_nav_index, if (is_ref) .type else .fully); | 30062 | try sema.ensureNavResolved(block, src, orig_nav_index, if (is_ref) .type else .fully); |
| 30067 | 30063 | ||
| 30068 | const nav_index = nav: { | 30064 | const nav_index = nav: { |
| 30069 | if (ip.getNav(orig_nav_index).isExternOrFn(ip)) { | 30065 | const orig_nav = ip.getNav(orig_nav_index); |
| 30070 | // Getting a pointer to this `Nav` might mean we actually get a pointer to something else! | 30066 | if (orig_nav.resolved.?.is_extern_decl or ip.zigTypeTag(orig_nav.resolved.?.type) == .@"fn") { |
| 30071 | // We need to resolve the value to know for sure. | 30067 | // A pointer to this `Nav` might actually be encoded as a pointer to a different `Nav` |
| 30072 | if (is_ref) try sema.ensureNavResolved(block, src, orig_nav_index, .fully); | 30068 | // because this is either an `extern` definition or an `extern` alias. (The latter case |
| 30073 | switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) { | 30069 | // is unsolved language weirdness; see https://github.com/ziglang/zig/issues/21027.) To |
| 30070 | // know for sure how to encode this pointer, we need to check the *value* of this `Nav`. | ||
| 30071 | const orig_nav_value = switch (is_ref) { | ||
| 30072 | false => orig_nav.resolved.?.value, | ||
| 30073 | true => orig_val: { | ||
| 30074 | try sema.ensureNavResolved(block, src, orig_nav_index, .fully); | ||
| 30075 | break :orig_val ip.getNav(orig_nav_index).resolved.?.value; | ||
| 30076 | }, | ||
| 30077 | }; | ||
| 30078 | switch (ip.indexToKey(orig_nav_value)) { | ||
| 30074 | .func => |f| break :nav f.owner_nav, | 30079 | .func => |f| break :nav f.owner_nav, |
| 30075 | .@"extern" => |e| break :nav e.owner_nav, | 30080 | .@"extern" => |e| break :nav e.owner_nav, |
| 30076 | else => {}, | 30081 | else => {}, |
| ... | @@ -30079,33 +30084,31 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde | ... | @@ -30079,33 +30084,31 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde |
| 30079 | break :nav orig_nav_index; | 30084 | break :nav orig_nav_index; |
| 30080 | }; | 30085 | }; |
| 30081 | 30086 | ||
| 30082 | const nav_status = ip.getNav(nav_index).status; | 30087 | const nav_resolved = ip.getNav(nav_index).resolved.?; |
| 30083 | 30088 | ||
| 30084 | const is_runtime = switch (nav_status) { | 30089 | const is_runtime: bool = runtime: { |
| 30085 | .unresolved => unreachable, | 30090 | if (nav_resolved.@"threadlocal") break :runtime true; |
| 30086 | // dllimports go straight to `fully_resolved`; the only option is threadlocal | 30091 | if (nav_resolved.value == .none) { |
| 30087 | .type_resolved => |r| r.is_threadlocal, | 30092 | // This didn't come from `@extern`, so even if extern it couldn't be dllimport or pcrel. |
| 30088 | .fully_resolved => |r| switch (ip.indexToKey(r.val)) { | 30093 | break :runtime false; |
| 30089 | .@"extern" => |e| e.is_threadlocal or e.is_dll_import or switch (e.relocation) { | 30094 | } |
| 30090 | .any => false, | 30095 | const @"extern" = switch (ip.indexToKey(nav_resolved.value)) { |
| 30091 | .pcrel => true, | 30096 | .@"extern" => |e| e, |
| 30092 | }, | 30097 | else => break :runtime false, |
| 30093 | .variable => |v| v.is_threadlocal, | 30098 | }; |
| 30094 | else => false, | 30099 | if (@"extern".is_dll_import) break :runtime true; |
| 30095 | }, | 30100 | break :runtime switch (@"extern".relocation) { |
| 30101 | .any => false, | ||
| 30102 | .pcrel => true, | ||
| 30103 | }; | ||
| 30096 | }; | 30104 | }; |
| 30097 | 30105 | ||
| 30098 | const ty, const alignment, const @"addrspace", const is_const = switch (nav_status) { | ||
| 30099 | .unresolved => unreachable, | ||
| 30100 | .type_resolved => |r| .{ r.type, r.alignment, r.@"addrspace", r.is_const }, | ||
| 30101 | .fully_resolved => |r| .{ ip.typeOf(r.val), r.alignment, r.@"addrspace", r.is_const }, | ||
| 30102 | }; | ||
| 30103 | const ptr_ty = try pt.ptrType(.{ | 30106 | const ptr_ty = try pt.ptrType(.{ |
| 30104 | .child = ty, | 30107 | .child = nav_resolved.type, |
| 30105 | .flags = .{ | 30108 | .flags = .{ |
| 30106 | .alignment = alignment, | 30109 | .alignment = nav_resolved.@"align", |
| 30107 | .is_const = is_const, | 30110 | .is_const = nav_resolved.@"const", |
| 30108 | .address_space = @"addrspace", | 30111 | .address_space = nav_resolved.@"addrspace", |
| 30109 | }, | 30112 | }, |
| 30110 | }); | 30113 | }); |
| 30111 | 30114 | ||
| ... | @@ -30140,7 +30143,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i | ... | @@ -30140,7 +30143,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i |
| 30140 | // If it is, we can resolve the *value*, and queue analysis as needed. | 30143 | // If it is, we can resolve the *value*, and queue analysis as needed. |
| 30141 | 30144 | ||
| 30142 | try sema.ensureNavResolved(block, src, nav_index, .type); | 30145 | try sema.ensureNavResolved(block, src, nav_index, .type); |
| 30143 | const nav_ty: Type = .fromInterned(ip.getNav(nav_index).typeOf(ip)); | 30146 | const nav_ty: Type = .fromInterned(ip.getNav(nav_index).resolved.?.type); |
| 30144 | if (nav_ty.zigTypeTag(zcu) != .@"fn") return; | 30147 | if (nav_ty.zigTypeTag(zcu) != .@"fn") return; |
| 30145 | if (!nav_ty.fnHasRuntimeBits(zcu)) return; | 30148 | if (!nav_ty.fnHasRuntimeBits(zcu)) return; |
| 30146 | 30149 | ||
| ... | @@ -34006,7 +34009,7 @@ pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError | ... | @@ -34006,7 +34009,7 @@ pub fn getBuiltin(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError |
| 34006 | } | 34009 | } |
| 34007 | 34010 | ||
| 34008 | pub const NavPtrModifiers = struct { | 34011 | pub const NavPtrModifiers = struct { |
| 34009 | alignment: Alignment, | 34012 | @"align": Alignment, |
| 34010 | @"linksection": InternPool.OptionalNullTerminatedString, | 34013 | @"linksection": InternPool.OptionalNullTerminatedString, |
| 34011 | @"addrspace": std.builtin.AddressSpace, | 34014 | @"addrspace": std.builtin.AddressSpace, |
| 34012 | }; | 34015 | }; |
| ... | @@ -34029,7 +34032,7 @@ pub fn resolveNavPtrModifiers( | ... | @@ -34029,7 +34032,7 @@ pub fn resolveNavPtrModifiers( |
| 34029 | const section_src = block.src(.{ .node_offset_var_decl_section = .zero }); | 34032 | const section_src = block.src(.{ .node_offset_var_decl_section = .zero }); |
| 34030 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = .zero }); | 34033 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = .zero }); |
| 34031 | 34034 | ||
| 34032 | const alignment: InternPool.Alignment = a: { | 34035 | const @"align": InternPool.Alignment = a: { |
| 34033 | const align_body = zir_decl.align_body orelse break :a .none; | 34036 | const align_body = zir_decl.align_body orelse break :a .none; |
| 34034 | const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst); | 34037 | const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst); |
| 34035 | break :a try sema.analyzeAsAlign(block, align_src, align_ref); | 34038 | break :a try sema.analyzeAsAlign(block, align_src, align_ref); |
| ... | @@ -34067,7 +34070,7 @@ pub fn resolveNavPtrModifiers( | ... | @@ -34067,7 +34070,7 @@ pub fn resolveNavPtrModifiers( |
| 34067 | }; | 34070 | }; |
| 34068 | 34071 | ||
| 34069 | return .{ | 34072 | return .{ |
| 34070 | .alignment = alignment, | 34073 | .@"align" = @"align", |
| 34071 | .@"linksection" = @"linksection", | 34074 | .@"linksection" = @"linksection", |
| 34072 | .@"addrspace" = @"addrspace", | 34075 | .@"addrspace" = @"addrspace", |
| 34073 | }; | 34076 | }; |
src/Sema/bitcast.zig-1| ... | @@ -253,7 +253,6 @@ const UnpackValueBits = struct { | ... | @@ -253,7 +253,6 @@ const UnpackValueBits = struct { |
| 253 | .func_type, | 253 | .func_type, |
| 254 | .error_set_type, | 254 | .error_set_type, |
| 255 | .inferred_error_set_type, | 255 | .inferred_error_set_type, |
| 256 | .variable, | ||
| 257 | .@"extern", | 256 | .@"extern", |
| 258 | .func, | 257 | .func, |
| 259 | .err, | 258 | .err, |
src/Sema/comptime_ptr_access.zig+10-12| ... | @@ -225,19 +225,17 @@ fn loadComptimePtrInner( | ... | @@ -225,19 +225,17 @@ fn loadComptimePtrInner( |
| 225 | }; | 225 | }; |
| 226 | 226 | ||
| 227 | const base_val: MutableValue = switch (ptr.base_addr) { | 227 | const base_val: MutableValue = switch (ptr.base_addr) { |
| 228 | .nav => |nav| val: { | 228 | .nav => |nav_id| val: { |
| 229 | try sema.ensureNavResolved(block, src, nav, .fully); | 229 | try sema.ensureNavResolved(block, src, nav_id, .fully); |
| 230 | const val = ip.getNav(nav).status.fully_resolved.val; | 230 | const nav = ip.getNav(nav_id); |
| 231 | switch (ip.indexToKey(val)) { | 231 | if (!nav.resolved.?.@"const") return .runtime_load; |
| 232 | .variable => return .runtime_load, | 232 | // We let `.@"extern"` through here if it's a fn. This allows aliasing `extern fn`s. |
| 233 | // We let `.@"extern"` through here if it's a function. | 233 | if (ip.indexToKey(nav.resolved.?.value) == .@"extern" and |
| 234 | // This allows you to alias `extern fn`s. | 234 | Type.fromInterned(nav.resolved.?.type).zigTypeTag(zcu) != .@"fn") |
| 235 | .@"extern" => |e| if (Type.fromInterned(e.ty).zigTypeTag(zcu) == .@"fn") | 235 | { |
| 236 | break :val .{ .interned = val } | 236 | return .runtime_load; |
| 237 | else | ||
| 238 | return .runtime_load, | ||
| 239 | else => break :val .{ .interned = val }, | ||
| 240 | } | 237 | } |
| 238 | break :val .{ .interned = nav.resolved.?.value }; | ||
| 241 | }, | 239 | }, |
| 242 | .comptime_alloc => |alloc_index| sema.getComptimeAlloc(alloc_index).val, | 240 | .comptime_alloc => |alloc_index| sema.getComptimeAlloc(alloc_index).val, |
| 243 | .uav => |uav| .{ .interned = uav.val }, | 241 | .uav => |uav| .{ .interned = uav.val }, |
src/Sema/type_resolution.zig-1| ... | @@ -115,7 +115,6 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons | ... | @@ -115,7 +115,6 @@ fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *cons |
| 115 | // values, not types | 115 | // values, not types |
| 116 | .undef, | 116 | .undef, |
| 117 | .simple_value, | 117 | .simple_value, |
| 118 | .variable, | ||
| 119 | .@"extern", | 118 | .@"extern", |
| 120 | .func, | 119 | .func, |
| 121 | .int, | 120 | .int, |
src/Type.zig-10| ... | @@ -239,7 +239,6 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { | ... | @@ -239,7 +239,6 @@ pub fn classify(start_ty: Type, zcu: *const Zcu) Class { |
| 239 | // values, not types | 239 | // values, not types |
| 240 | .undef, | 240 | .undef, |
| 241 | .simple_value, | 241 | .simple_value, |
| 242 | .variable, | ||
| 243 | .@"extern", | 242 | .@"extern", |
| 244 | .func, | 243 | .func, |
| 245 | .int, | 244 | .int, |
| ... | @@ -675,7 +674,6 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari | ... | @@ -675,7 +674,6 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari |
| 675 | 674 | ||
| 676 | // values, not types | 675 | // values, not types |
| 677 | .simple_value, | 676 | .simple_value, |
| 678 | .variable, | ||
| 679 | .@"extern", | 677 | .@"extern", |
| 680 | .func, | 678 | .func, |
| 681 | .int, | 679 | .int, |
| ... | @@ -814,7 +812,6 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { | ... | @@ -814,7 +812,6 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool { |
| 814 | // values, not types | 812 | // values, not types |
| 815 | .undef, | 813 | .undef, |
| 816 | .simple_value, | 814 | .simple_value, |
| 817 | .variable, | ||
| 818 | .@"extern", | 815 | .@"extern", |
| 819 | .func, | 816 | .func, |
| 820 | .int, | 817 | .int, |
| ... | @@ -1046,7 +1043,6 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { | ... | @@ -1046,7 +1043,6 @@ pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment { |
| 1046 | // values, not types | 1043 | // values, not types |
| 1047 | .undef, | 1044 | .undef, |
| 1048 | .simple_value, | 1045 | .simple_value, |
| 1049 | .variable, | ||
| 1050 | .@"extern", | 1046 | .@"extern", |
| 1051 | .func, | 1047 | .func, |
| 1052 | .int, | 1048 | .int, |
| ... | @@ -1187,7 +1183,6 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1187,7 +1183,6 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 { |
| 1187 | // values, not types | 1183 | // values, not types |
| 1188 | .undef, | 1184 | .undef, |
| 1189 | .simple_value, | 1185 | .simple_value, |
| 1190 | .variable, | ||
| 1191 | .@"extern", | 1186 | .@"extern", |
| 1192 | .func, | 1187 | .func, |
| 1193 | .int, | 1188 | .int, |
| ... | @@ -1311,7 +1306,6 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { | ... | @@ -1311,7 +1306,6 @@ pub fn bitSize(ty: Type, zcu: *const Zcu) u64 { |
| 1311 | // values, not types | 1306 | // values, not types |
| 1312 | .undef, | 1307 | .undef, |
| 1313 | .simple_value, | 1308 | .simple_value, |
| 1314 | .variable, | ||
| 1315 | .@"extern", | 1309 | .@"extern", |
| 1316 | .func, | 1310 | .func, |
| 1317 | .int, | 1311 | .int, |
| ... | @@ -1867,7 +1861,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { | ... | @@ -1867,7 +1861,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType { |
| 1867 | // values, not types | 1861 | // values, not types |
| 1868 | .undef, | 1862 | .undef, |
| 1869 | .simple_value, | 1863 | .simple_value, |
| 1870 | .variable, | ||
| 1871 | .@"extern", | 1864 | .@"extern", |
| 1872 | .func, | 1865 | .func, |
| 1873 | .int, | 1866 | .int, |
| ... | @@ -2162,7 +2155,6 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { | ... | @@ -2162,7 +2155,6 @@ pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value { |
| 2162 | // values, not types | 2155 | // values, not types |
| 2163 | .undef, | 2156 | .undef, |
| 2164 | .simple_value, | 2157 | .simple_value, |
| 2165 | .variable, | ||
| 2166 | .@"extern", | 2158 | .@"extern", |
| 2167 | .func, | 2159 | .func, |
| 2168 | .int, | 2160 | .int, |
| ... | @@ -3284,7 +3276,6 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { | ... | @@ -3284,7 +3276,6 @@ pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void { |
| 3284 | 3276 | ||
| 3285 | // values, not types | 3277 | // values, not types |
| 3286 | .simple_value, | 3278 | .simple_value, |
| 3287 | .variable, | ||
| 3288 | .@"extern", | 3279 | .@"extern", |
| 3289 | .func, | 3280 | .func, |
| 3290 | .int, | 3281 | .int, |
| ... | @@ -3362,7 +3353,6 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn | ... | @@ -3362,7 +3353,6 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn |
| 3362 | 3353 | ||
| 3363 | // values, not types | 3354 | // values, not types |
| 3364 | .simple_value, | 3355 | .simple_value, |
| 3365 | .variable, | ||
| 3366 | .@"extern", | 3356 | .@"extern", |
| 3367 | .func, | 3357 | .func, |
| 3368 | .int, | 3358 | .int, |
src/Value.zig+1-9| ... | @@ -176,13 +176,6 @@ pub fn getFunction(val: Value, zcu: *Zcu) ?InternPool.Key.Func { | ... | @@ -176,13 +176,6 @@ pub fn getFunction(val: Value, zcu: *Zcu) ?InternPool.Key.Func { |
| 176 | }; | 176 | }; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | pub fn getVariable(val: Value, mod: *Zcu) ?InternPool.Key.Variable { | ||
| 180 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | ||
| 181 | .variable => |variable| variable, | ||
| 182 | else => null, | ||
| 183 | }; | ||
| 184 | } | ||
| 185 | |||
| 186 | /// Asserts the value is a (defined) integer and it fits in a u64. | 179 | /// Asserts the value is a (defined) integer and it fits in a u64. |
| 187 | pub fn toUnsignedInt(val: Value, zcu: *const Zcu) u64 { | 180 | pub fn toUnsignedInt(val: Value, zcu: *const Zcu) u64 { |
| 188 | return getUnsignedInt(val, zcu).?; | 181 | return getUnsignedInt(val, zcu).?; |
| ... | @@ -808,7 +801,6 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool { | ... | @@ -808,7 +801,6 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool { |
| 808 | pub fn pointerNav(val: Value, zcu: *const Zcu) ?InternPool.Nav.Index { | 801 | pub fn pointerNav(val: Value, zcu: *const Zcu) ?InternPool.Nav.Index { |
| 809 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 802 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 810 | // TODO: these 3 cases are weird; these aren't pointer values! | 803 | // TODO: these 3 cases are weird; these aren't pointer values! |
| 811 | .variable => |v| v.owner_nav, | ||
| 812 | .@"extern" => |e| e.owner_nav, | 804 | .@"extern" => |e| e.owner_nav, |
| 813 | .func => |func| func.owner_nav, | 805 | .func => |func| func.owner_nav, |
| 814 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | 806 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { |
| ... | @@ -2539,7 +2531,7 @@ pub fn intFitsInType( | ... | @@ -2539,7 +2531,7 @@ pub fn intFitsInType( |
| 2539 | .zero_usize, .zero_u8 => return true, | 2531 | .zero_usize, .zero_u8 => return true, |
| 2540 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { | 2532 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 2541 | .undef => return true, | 2533 | .undef => return true, |
| 2542 | .variable, .@"extern", .func, .ptr => { | 2534 | .@"extern", .func, .ptr => { |
| 2543 | const target = zcu.getTarget(); | 2535 | const target = zcu.getTarget(); |
| 2544 | const ptr_bits = target.ptrBitWidth(); | 2536 | const ptr_bits = target.ptrBitWidth(); |
| 2545 | return switch (info.signedness) { | 2537 | return switch (info.signedness) { |
src/Zcu.zig+9-15| ... | @@ -723,11 +723,7 @@ pub const Exported = union(enum) { | ... | @@ -723,11 +723,7 @@ pub const Exported = union(enum) { |
| 723 | 723 | ||
| 724 | pub fn getAlign(exported: Exported, zcu: *Zcu) Alignment { | 724 | pub fn getAlign(exported: Exported, zcu: *Zcu) Alignment { |
| 725 | return switch (exported) { | 725 | return switch (exported) { |
| 726 | .nav => |nav| switch (zcu.intern_pool.getNav(nav).status) { | 726 | .nav => |nav| zcu.intern_pool.getNav(nav).resolved.?.@"align", |
| 727 | .unresolved => unreachable, | ||
| 728 | .type_resolved => |r| r.alignment, | ||
| 729 | .fully_resolved => |r| r.alignment, | ||
| 730 | }, | ||
| 731 | .uav => .none, | 727 | .uav => .none, |
| 732 | }; | 728 | }; |
| 733 | } | 729 | } |
| ... | @@ -4252,8 +4248,8 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag | ... | @@ -4252,8 +4248,8 @@ fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanag |
| 4252 | } | 4248 | } |
| 4253 | } | 4249 | } |
| 4254 | // Non-fatal AstGen errors could mean this test decl failed | 4250 | // Non-fatal AstGen errors could mean this test decl failed |
| 4255 | if (nav.status == .fully_resolved) { | 4251 | if (nav.resolved != null and nav.resolved.?.value != .none) { |
| 4256 | const gop = try units.getOrPut(gpa, .wrap(.{ .func = nav.status.fully_resolved.val })); | 4252 | const gop = try units.getOrPut(gpa, .wrap(.{ .func = nav.resolved.?.value })); |
| 4257 | if (!gop.found_existing) gop.value_ptr.* = referencer; | 4253 | if (!gop.found_existing) gop.value_ptr.* = referencer; |
| 4258 | } | 4254 | } |
| 4259 | } | 4255 | } |
| ... | @@ -4419,7 +4415,7 @@ pub fn navSrcLine(zcu: *Zcu, nav_index: InternPool.Nav.Index) u32 { | ... | @@ -4419,7 +4415,7 @@ pub fn navSrcLine(zcu: *Zcu, nav_index: InternPool.Nav.Index) u32 { |
| 4419 | } | 4415 | } |
| 4420 | 4416 | ||
| 4421 | pub fn navValue(zcu: *const Zcu, nav_index: InternPool.Nav.Index) Value { | 4417 | pub fn navValue(zcu: *const Zcu, nav_index: InternPool.Nav.Index) Value { |
| 4422 | return Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.fully_resolved.val); | 4418 | return .fromInterned(zcu.intern_pool.getNav(nav_index).resolved.?.value); |
| 4423 | } | 4419 | } |
| 4424 | 4420 | ||
| 4425 | pub fn navFileScopeIndex(zcu: *Zcu, nav: InternPool.Nav.Index) File.Index { | 4421 | pub fn navFileScopeIndex(zcu: *Zcu, nav: InternPool.Nav.Index) File.Index { |
| ... | @@ -4431,14 +4427,12 @@ pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File { | ... | @@ -4431,14 +4427,12 @@ pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File { |
| 4431 | return zcu.fileByIndex(zcu.navFileScopeIndex(nav)); | 4427 | return zcu.fileByIndex(zcu.navFileScopeIndex(nav)); |
| 4432 | } | 4428 | } |
| 4433 | 4429 | ||
| 4434 | pub fn navAlignment(zcu: *Zcu, nav_index: InternPool.Nav.Index) InternPool.Alignment { | 4430 | pub fn navAlignment(zcu: *Zcu, nav_id: InternPool.Nav.Index) InternPool.Alignment { |
| 4435 | const ty: Type, const alignment = switch (zcu.intern_pool.getNav(nav_index).status) { | 4431 | const resolved = zcu.intern_pool.getNav(nav_id).resolved.?; |
| 4436 | .unresolved => unreachable, | 4432 | return switch (resolved.@"align") { |
| 4437 | .type_resolved => |r| .{ .fromInterned(r.type), r.alignment }, | 4433 | else => |a| a, |
| 4438 | .fully_resolved => |r| .{ Value.fromInterned(r.val).typeOf(zcu), r.alignment }, | 4434 | .none => Type.fromInterned(resolved.type).abiAlignment(zcu), |
| 4439 | }; | 4435 | }; |
| 4440 | if (alignment != .none) return alignment; | ||
| 4441 | return ty.abiAlignment(zcu); | ||
| 4442 | } | 4436 | } |
| 4443 | 4437 | ||
| 4444 | pub fn fmtAnalUnit(zcu: *Zcu, unit: AnalUnit) std.fmt.Alt(FormatAnalUnit, formatAnalUnit) { | 4438 | pub fn fmtAnalUnit(zcu: *Zcu, unit: AnalUnit) std.fmt.Alt(FormatAnalUnit, formatAnalUnit) { |
src/Zcu/PerThread.zig+76-110| ... | @@ -1584,10 +1584,6 @@ pub fn ensureNavValUpToDate( | ... | @@ -1584,10 +1584,6 @@ pub fn ensureNavValUpToDate( |
| 1584 | 1584 | ||
| 1585 | try zcu.ensureNavValAnalysisQueued(nav_id); | 1585 | try zcu.ensureNavValAnalysisQueued(nav_id); |
| 1586 | 1586 | ||
| 1587 | // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the | ||
| 1588 | // status is `.unresolved`, which indicates that the value is outdated because it has *never* | ||
| 1589 | // been analyzed so far. | ||
| 1590 | // | ||
| 1591 | // Note that if the unit is PO, we pessimistically assume that it *does* require re-analysis, to | 1587 | // Note that if the unit is PO, we pessimistically assume that it *does* require re-analysis, to |
| 1592 | // ensure that the unit is definitely up-to-date when this function returns. This mechanism could | 1588 | // ensure that the unit is definitely up-to-date when this function returns. This mechanism could |
| 1593 | // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by | 1589 | // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by |
| ... | @@ -1603,7 +1599,7 @@ pub fn ensureNavValUpToDate( | ... | @@ -1603,7 +1599,7 @@ pub fn ensureNavValUpToDate( |
| 1603 | } else { | 1599 | } else { |
| 1604 | // We can trust the current information about this unit. | 1600 | // We can trust the current information about this unit. |
| 1605 | if (prev_failed) return error.AnalysisFail; | 1601 | if (prev_failed) return error.AnalysisFail; |
| 1606 | assert(nav.status == .fully_resolved); | 1602 | assert(nav.resolved.?.value != .none); |
| 1607 | return; | 1603 | return; |
| 1608 | } | 1604 | } |
| 1609 | 1605 | ||
| ... | @@ -1740,7 +1736,7 @@ fn analyzeNavVal( | ... | @@ -1740,7 +1736,7 @@ fn analyzeNavVal( |
| 1740 | const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: { | 1736 | const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: { |
| 1741 | // Since we have a type body, the type is resolved separately! | 1737 | // Since we have a type body, the type is resolved separately! |
| 1742 | try sema.ensureNavResolved(&block, init_src, nav_id, .type); | 1738 | try sema.ensureNavResolved(&block, init_src, nav_id, .type); |
| 1743 | break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip)); | 1739 | break :ty .fromInterned(ip.getNav(nav_id).resolved.?.type); |
| 1744 | } else null; | 1740 | } else null; |
| 1745 | 1741 | ||
| 1746 | const final_val: ?Value = if (zir_decl.value_body) |value_body| val: { | 1742 | const final_val: ?Value = if (zir_decl.value_body) |value_body| val: { |
| ... | @@ -1786,14 +1782,12 @@ fn analyzeNavVal( | ... | @@ -1786,14 +1782,12 @@ fn analyzeNavVal( |
| 1786 | const modifiers: Sema.NavPtrModifiers = if (zir_decl.type_body != null) m: { | 1782 | const modifiers: Sema.NavPtrModifiers = if (zir_decl.type_body != null) m: { |
| 1787 | // `analyzeNavType` (from the `ensureNavTypeUpToDate` call above) has already populated this data into | 1783 | // `analyzeNavType` (from the `ensureNavTypeUpToDate` call above) has already populated this data into |
| 1788 | // the `Nav`. Load the new one, and pull the modifiers out. | 1784 | // the `Nav`. Load the new one, and pull the modifiers out. |
| 1789 | switch (ip.getNav(nav_id).status) { | 1785 | const r = ip.getNav(nav_id).resolved.?; |
| 1790 | .unresolved => unreachable, // `analyzeNavType` will never leave us in this state | 1786 | break :m .{ |
| 1791 | inline .type_resolved, .fully_resolved => |r| break :m .{ | 1787 | .@"align" = r.@"align", |
| 1792 | .alignment = r.alignment, | 1788 | .@"linksection" = r.@"linksection", |
| 1793 | .@"linksection" = r.@"linksection", | 1789 | .@"addrspace" = r.@"addrspace", |
| 1794 | .@"addrspace" = r.@"addrspace", | 1790 | }; |
| 1795 | }, | ||
| 1796 | } | ||
| 1797 | } else m: { | 1791 | } else m: { |
| 1798 | // `analyzeNavType` is essentially a stub which calls us. We are responsible for resolving this data. | 1792 | // `analyzeNavType` is essentially a stub which calls us. We are responsible for resolving this data. |
| 1799 | break :m try sema.resolveNavPtrModifiers(&block, zir_decl, inst_resolved.inst, nav_ty); | 1793 | break :m try sema.resolveNavPtrModifiers(&block, zir_decl, inst_resolved.inst, nav_ty); |
| ... | @@ -1803,15 +1797,7 @@ fn analyzeNavVal( | ... | @@ -1803,15 +1797,7 @@ fn analyzeNavVal( |
| 1803 | // This isn't necessarily the same as `final_val`! | 1797 | // This isn't necessarily the same as `final_val`! |
| 1804 | 1798 | ||
| 1805 | const nav_val: Value = switch (zir_decl.linkage) { | 1799 | const nav_val: Value = switch (zir_decl.linkage) { |
| 1806 | .normal, .@"export" => switch (zir_decl.kind) { | 1800 | .normal, .@"export" => final_val.?, |
| 1807 | .@"var" => .fromInterned(try pt.intern(.{ .variable = .{ | ||
| 1808 | .ty = nav_ty.toIntern(), | ||
| 1809 | .init = final_val.?.toIntern(), | ||
| 1810 | .owner_nav = nav_id, | ||
| 1811 | .is_threadlocal = zir_decl.is_threadlocal, | ||
| 1812 | } })), | ||
| 1813 | else => final_val.?, | ||
| 1814 | }, | ||
| 1815 | .@"extern" => val: { | 1801 | .@"extern" => val: { |
| 1816 | assert(final_val == null); // extern decls do not have a value body | 1802 | assert(final_val == null); // extern decls do not have a value body |
| 1817 | const lib_name: ?[]const u8 = if (zir_decl.lib_name != .empty) l: { | 1803 | const lib_name: ?[]const u8 = if (zir_decl.lib_name != .empty) l: { |
| ... | @@ -1832,7 +1818,7 @@ fn analyzeNavVal( | ... | @@ -1832,7 +1818,7 @@ fn analyzeNavVal( |
| 1832 | .relocation = .any, | 1818 | .relocation = .any, |
| 1833 | .decoration = null, | 1819 | .decoration = null, |
| 1834 | .is_const = is_const, | 1820 | .is_const = is_const, |
| 1835 | .alignment = modifiers.alignment, | 1821 | .alignment = modifiers.@"align", |
| 1836 | .@"addrspace" = modifiers.@"addrspace", | 1822 | .@"addrspace" = modifiers.@"addrspace", |
| 1837 | .zir_index = old_nav.analysis.?.zir_index, // `declaration` instruction | 1823 | .zir_index = old_nav.analysis.?.zir_index, // `declaration` instruction |
| 1838 | .owner_nav = undefined, // ignored by `getExtern` | 1824 | .owner_nav = undefined, // ignored by `getExtern` |
| ... | @@ -1852,11 +1838,7 @@ fn analyzeNavVal( | ... | @@ -1852,11 +1838,7 @@ fn analyzeNavVal( |
| 1852 | 1838 | ||
| 1853 | const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) { | 1839 | const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) { |
| 1854 | .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen | 1840 | .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen |
| 1855 | .variable => |v| .{ v.owner_nav == nav_id, false }, | 1841 | .@"extern" => .{ false, nav_ty.zigTypeTag(zcu) == .@"fn" and zir_decl.linkage == .@"extern" }, |
| 1856 | .@"extern" => |e| .{ | ||
| 1857 | false, | ||
| 1858 | Type.fromInterned(e.ty).zigTypeTag(zcu) == .@"fn" and zir_decl.linkage == .@"extern", | ||
| 1859 | }, | ||
| 1860 | else => .{ true, false }, | 1842 | else => .{ true, false }, |
| 1861 | }; | 1843 | }; |
| 1862 | 1844 | ||
| ... | @@ -1895,23 +1877,22 @@ fn analyzeNavVal( | ... | @@ -1895,23 +1877,22 @@ fn analyzeNavVal( |
| 1895 | info.last_update_gen = zcu.generation; | 1877 | info.last_update_gen = zcu.generation; |
| 1896 | info.deps.clearRetainingCapacity(); | 1878 | info.deps.clearRetainingCapacity(); |
| 1897 | } | 1879 | } |
| 1898 | const type_changed: bool = switch (old_nav.status) { | 1880 | const type_changed: bool = if (old_nav.resolved) |r| r.type != nav_ty.toIntern() else true; |
| 1899 | .unresolved => true, | ||
| 1900 | .type_resolved => |old| old.type != nav_ty.toIntern(), | ||
| 1901 | .fully_resolved => |old| ip.typeOf(old.val) != nav_ty.toIntern(), | ||
| 1902 | }; | ||
| 1903 | if (type_changed) { | 1881 | if (type_changed) { |
| 1904 | try zcu.markDependeeOutdated(.marked_po, .{ .nav_ty = nav_id }); | 1882 | try zcu.markDependeeOutdated(.marked_po, .{ .nav_ty = nav_id }); |
| 1905 | } else { | 1883 | } else { |
| 1906 | try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav_id }); | 1884 | try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav_id }); |
| 1907 | } | 1885 | } |
| 1908 | } | 1886 | } |
| 1909 | ip.resolveNavValue(io, nav_id, .{ | 1887 | ip.resolveNav(io, nav_id, .{ |
| 1910 | .val = nav_val.toIntern(), | 1888 | .type = nav_ty.toIntern(), |
| 1911 | .is_const = is_const, | 1889 | .@"align" = modifiers.@"align", |
| 1912 | .alignment = modifiers.alignment, | ||
| 1913 | .@"linksection" = modifiers.@"linksection", | 1890 | .@"linksection" = modifiers.@"linksection", |
| 1914 | .@"addrspace" = modifiers.@"addrspace", | 1891 | .@"addrspace" = modifiers.@"addrspace", |
| 1892 | .@"const" = is_const, | ||
| 1893 | .@"threadlocal" = zir_decl.is_threadlocal, | ||
| 1894 | .is_extern_decl = zir_decl.linkage == .@"extern", | ||
| 1895 | .value = nav_val.toIntern(), | ||
| 1915 | }); | 1896 | }); |
| 1916 | 1897 | ||
| 1917 | if (zir_decl.linkage == .@"export") { | 1898 | if (zir_decl.linkage == .@"export") { |
| ... | @@ -1943,9 +1924,10 @@ fn analyzeNavVal( | ... | @@ -1943,9 +1924,10 @@ fn analyzeNavVal( |
| 1943 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); | 1924 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); |
| 1944 | } | 1925 | } |
| 1945 | 1926 | ||
| 1946 | return switch (old_nav.status) { | 1927 | return if (old_nav.resolved) |old_resolved| .{ |
| 1947 | .unresolved, .type_resolved => .{ .val_changed = true }, | 1928 | .val_changed = old_resolved.value != nav_val.toIntern(), |
| 1948 | .fully_resolved => |old| .{ .val_changed = old.val != nav_val.toIntern() }, | 1929 | } else .{ |
| 1930 | .val_changed = true, | ||
| 1949 | }; | 1931 | }; |
| 1950 | } | 1932 | } |
| 1951 | 1933 | ||
| ... | @@ -1971,10 +1953,6 @@ pub fn ensureNavTypeUpToDate( | ... | @@ -1971,10 +1953,6 @@ pub fn ensureNavTypeUpToDate( |
| 1971 | 1953 | ||
| 1972 | try zcu.ensureNavValAnalysisQueued(nav_id); | 1954 | try zcu.ensureNavValAnalysisQueued(nav_id); |
| 1973 | 1955 | ||
| 1974 | // Determine whether or not this `Nav`'s type is outdated. This also includes checking if the | ||
| 1975 | // status is `.unresolved`, which indicates that the value is outdated because it has *never* | ||
| 1976 | // been analyzed so far. | ||
| 1977 | // | ||
| 1978 | // Note that if the unit is PO, we pessimistically assume that it *does* require re-analysis, to | 1956 | // Note that if the unit is PO, we pessimistically assume that it *does* require re-analysis, to |
| 1979 | // ensure that the unit is definitely up-to-date when this function returns. This mechanism could | 1957 | // ensure that the unit is definitely up-to-date when this function returns. This mechanism could |
| 1980 | // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by | 1958 | // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by |
| ... | @@ -1990,7 +1968,7 @@ pub fn ensureNavTypeUpToDate( | ... | @@ -1990,7 +1968,7 @@ pub fn ensureNavTypeUpToDate( |
| 1990 | } else { | 1968 | } else { |
| 1991 | // We can trust the current information about this unit. | 1969 | // We can trust the current information about this unit. |
| 1992 | if (prev_failed) return error.AnalysisFail; | 1970 | if (prev_failed) return error.AnalysisFail; |
| 1993 | assert(nav.status != .unresolved); | 1971 | assert(nav.resolved != null); |
| 1994 | return; | 1972 | return; |
| 1995 | } | 1973 | } |
| 1996 | 1974 | ||
| ... | @@ -2124,24 +2102,16 @@ fn analyzeNavType( | ... | @@ -2124,24 +2102,16 @@ fn analyzeNavType( |
| 2124 | // the previous update. As such, after this call, we will be able to determine whether the | 2102 | // the previous update. As such, after this call, we will be able to determine whether the |
| 2125 | // type changed. | 2103 | // type changed. |
| 2126 | try sema.ensureNavResolved(&block, init_src, nav_id, .fully); | 2104 | try sema.ensureNavResolved(&block, init_src, nav_id, .fully); |
| 2127 | const new = ip.getNav(nav_id).status.fully_resolved; | 2105 | const new = ip.getNav(nav_id).resolved.?; |
| 2128 | const new_is_extern_decl = ip.indexToKey(new.val) == .@"extern"; | 2106 | return if (old_nav.resolved) |old| .{ |
| 2129 | const changed = switch (old_nav.status) { | 2107 | .type_changed = old.type != new.type or |
| 2130 | .unresolved => true, | 2108 | old.@"align" != new.@"align" or |
| 2131 | .type_resolved => |r| r.type != ip.typeOf(new.val) or | 2109 | old.@"linksection" != new.@"linksection" or |
| 2132 | r.alignment != new.alignment or | 2110 | old.@"addrspace" != new.@"addrspace" or |
| 2133 | r.@"linksection" != new.@"linksection" or | 2111 | old.@"const" != new.@"const" or |
| 2134 | r.@"addrspace" != new.@"addrspace" or | 2112 | old.@"threadlocal" != new.@"threadlocal" or |
| 2135 | r.is_const != new.is_const or | 2113 | old.is_extern_decl != new.is_extern_decl, |
| 2136 | r.is_extern_decl != new_is_extern_decl, | 2114 | } else .{ .type_changed = true }; |
| 2137 | .fully_resolved => |r| ip.typeOf(r.val) != ip.typeOf(new.val) or | ||
| 2138 | r.alignment != new.alignment or | ||
| 2139 | r.@"linksection" != new.@"linksection" or | ||
| 2140 | r.@"addrspace" != new.@"addrspace" or | ||
| 2141 | r.is_const != new.is_const or | ||
| 2142 | (old_nav.getExtern(ip) != null) != new_is_extern_decl, | ||
| 2143 | }; | ||
| 2144 | return .{ .type_changed = changed }; | ||
| 2145 | }; | 2115 | }; |
| 2146 | 2116 | ||
| 2147 | block.comptime_reason = .{ .reason = .{ | 2117 | block.comptime_reason = .{ .reason = .{ |
| ... | @@ -2169,37 +2139,34 @@ fn analyzeNavType( | ... | @@ -2169,37 +2139,34 @@ fn analyzeNavType( |
| 2169 | 2139 | ||
| 2170 | const is_extern_decl = zir_decl.linkage == .@"extern"; | 2140 | const is_extern_decl = zir_decl.linkage == .@"extern"; |
| 2171 | 2141 | ||
| 2172 | // Now for the question of the day: are the type and modifiers the same as before? | 2142 | // Now for the question of the day: are the type and modifiers the same as before? If they are, |
| 2173 | // If they are, then we should actually keep the `Nav` as `fully_resolved` if it currently is. | 2143 | // then we should actually avoid calling `ip.resolveNav`. This is because `analyzeNavVal` will |
| 2174 | // That's because `analyzeNavVal` will later want to look at the resolved value to figure out | 2144 | // later wanmt to look at the resolved *value* to figure out whether *that* has changed: if we |
| 2175 | // whether it's changed: if we threw that data away now, it would have to assume that the value | 2145 | // threw that data away now, it would have to assume the value *had* changed even if it actually |
| 2176 | // had changed, potentially spinning off loads of unnecessary re-analysis! | 2146 | // hadn't, which could spin off a bunch of unnecessary re-analysis! OTOH, if the type *has* |
| 2177 | const changed = switch (old_nav.status) { | 2147 | // changed, then we obviously know that the value will also have changed, so resetting the value |
| 2178 | .unresolved => true, | 2148 | // to `.none` is fine in that case. |
| 2179 | .type_resolved => |r| r.type != resolved_ty.toIntern() or | 2149 | const changed: bool = if (old_nav.resolved) |old| changed: { |
| 2180 | r.alignment != modifiers.alignment or | 2150 | break :changed old.type != resolved_ty.toIntern() or |
| 2181 | r.@"linksection" != modifiers.@"linksection" or | 2151 | old.@"align" != modifiers.@"align" or |
| 2182 | r.@"addrspace" != modifiers.@"addrspace" or | 2152 | old.@"linksection" != modifiers.@"linksection" or |
| 2183 | r.is_const != is_const or | 2153 | old.@"addrspace" != modifiers.@"addrspace" or |
| 2184 | r.is_extern_decl != is_extern_decl, | 2154 | old.@"const" != is_const or |
| 2185 | .fully_resolved => |r| ip.typeOf(r.val) != resolved_ty.toIntern() or | 2155 | old.@"threadlocal" != zir_decl.is_threadlocal or |
| 2186 | r.alignment != modifiers.alignment or | 2156 | old.is_extern_decl != is_extern_decl; |
| 2187 | r.@"linksection" != modifiers.@"linksection" or | 2157 | } else true; |
| 2188 | r.@"addrspace" != modifiers.@"addrspace" or | ||
| 2189 | r.is_const != is_const or | ||
| 2190 | (old_nav.getExtern(ip) != null) != is_extern_decl, | ||
| 2191 | }; | ||
| 2192 | 2158 | ||
| 2193 | if (!changed) return .{ .type_changed = false }; | 2159 | if (!changed) return .{ .type_changed = false }; |
| 2194 | 2160 | ||
| 2195 | ip.resolveNavType(io, nav_id, .{ | 2161 | ip.resolveNav(io, nav_id, .{ |
| 2196 | .type = resolved_ty.toIntern(), | 2162 | .type = resolved_ty.toIntern(), |
| 2197 | .is_const = is_const, | 2163 | .@"align" = modifiers.@"align", |
| 2198 | .alignment = modifiers.alignment, | ||
| 2199 | .@"linksection" = modifiers.@"linksection", | 2164 | .@"linksection" = modifiers.@"linksection", |
| 2200 | .@"addrspace" = modifiers.@"addrspace", | 2165 | .@"addrspace" = modifiers.@"addrspace", |
| 2201 | .is_threadlocal = zir_decl.is_threadlocal, | 2166 | .@"const" = is_const, |
| 2167 | .@"threadlocal" = zir_decl.is_threadlocal, | ||
| 2202 | .is_extern_decl = is_extern_decl, | 2168 | .is_extern_decl = is_extern_decl, |
| 2169 | .value = .none, | ||
| 2203 | }); | 2170 | }); |
| 2204 | 2171 | ||
| 2205 | return .{ .type_changed = true }; | 2172 | return .{ .type_changed = true }; |
| ... | @@ -3358,13 +3325,13 @@ fn analyzeFuncBodyInner( | ... | @@ -3358,13 +3325,13 @@ fn analyzeFuncBodyInner( |
| 3358 | 3325 | ||
| 3359 | if (func.generic_owner == .none) { | 3326 | if (func.generic_owner == .none) { |
| 3360 | try pt.ensureNavValUpToDate(func.owner_nav, reason); | 3327 | try pt.ensureNavValUpToDate(func.owner_nav, reason); |
| 3361 | if (ip.getNav(func.owner_nav).status.fully_resolved.val != func_index) { | 3328 | if (ip.getNav(func.owner_nav).resolved.?.value != func_index) { |
| 3362 | return error.AnalysisFail; | 3329 | return error.AnalysisFail; |
| 3363 | } | 3330 | } |
| 3364 | } else { | 3331 | } else { |
| 3365 | const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; | 3332 | const go_nav = zcu.funcInfo(func.generic_owner).owner_nav; |
| 3366 | try pt.ensureNavValUpToDate(go_nav, reason); | 3333 | try pt.ensureNavValUpToDate(go_nav, reason); |
| 3367 | if (ip.getNav(go_nav).status.fully_resolved.val != func.generic_owner) { | 3334 | if (ip.getNav(go_nav).resolved.?.value != func.generic_owner) { |
| 3368 | return error.AnalysisFail; | 3335 | return error.AnalysisFail; |
| 3369 | } | 3336 | } |
| 3370 | } | 3337 | } |
| ... | @@ -3757,9 +3724,9 @@ fn processExportsInner( | ... | @@ -3757,9 +3724,9 @@ fn processExportsInner( |
| 3757 | if (zcu.failed_analysis.contains(unit)) break :failed true; | 3724 | if (zcu.failed_analysis.contains(unit)) break :failed true; |
| 3758 | if (zcu.transitive_failed_analysis.contains(unit)) break :failed true; | 3725 | if (zcu.transitive_failed_analysis.contains(unit)) break :failed true; |
| 3759 | } | 3726 | } |
| 3760 | const val = switch (nav.status) { | 3727 | const val: Value = switch ((nav.resolved orelse break :failed true).value) { |
| 3761 | .unresolved, .type_resolved => break :failed true, | 3728 | .none => break :failed true, |
| 3762 | .fully_resolved => |r| Value.fromInterned(r.val), | 3729 | else => |val| .fromInterned(val), |
| 3763 | }; | 3730 | }; |
| 3764 | // If the value is a function, we also need to check if that function succeeded analysis. | 3731 | // If the value is a function, we also need to check if that function succeeded analysis. |
| 3765 | if (val.typeOf(zcu).zigTypeTag(zcu) == .@"fn") { | 3732 | if (val.typeOf(zcu).zigTypeTag(zcu) == .@"fn") { |
| ... | @@ -3805,14 +3772,16 @@ pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -3805,14 +3772,16 @@ pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { |
| 3805 | if (builtin_root_type == .none) return; // `@import("builtin")` never analyzed | 3772 | if (builtin_root_type == .none) return; // `@import("builtin")` never analyzed |
| 3806 | const builtin_namespace = Type.fromInterned(builtin_root_type).getNamespace(zcu).unwrap().?; | 3773 | const builtin_namespace = Type.fromInterned(builtin_root_type).getNamespace(zcu).unwrap().?; |
| 3807 | // We know that the namespace has a `test_functions`... | 3774 | // We know that the namespace has a `test_functions`... |
| 3808 | const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted( | 3775 | const test_fns_nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted( |
| 3809 | try ip.getOrPutString(gpa, io, pt.tid, "test_functions", .no_embedded_nulls), | 3776 | try ip.getOrPutString(gpa, io, pt.tid, "test_functions", .no_embedded_nulls), |
| 3810 | Zcu.Namespace.NameAdapter{ .zcu = zcu }, | 3777 | Zcu.Namespace.NameAdapter{ .zcu = zcu }, |
| 3811 | ).?; | 3778 | ).?; |
| 3779 | const test_fns_nav = ip.getNav(test_fns_nav_index); | ||
| 3812 | // ...but it might not be populated, so let's check that! | 3780 | // ...but it might not be populated, so let's check that! |
| 3813 | if (zcu.failed_analysis.contains(.wrap(.{ .nav_val = nav_index })) or | 3781 | if (zcu.failed_analysis.contains(.wrap(.{ .nav_val = test_fns_nav_index })) or |
| 3814 | zcu.transitive_failed_analysis.contains(.wrap(.{ .nav_val = nav_index })) or | 3782 | zcu.transitive_failed_analysis.contains(.wrap(.{ .nav_val = test_fns_nav_index })) or |
| 3815 | ip.getNav(nav_index).status != .fully_resolved) | 3783 | test_fns_nav.resolved == null or |
| 3784 | test_fns_nav.resolved.?.value == .none) | ||
| 3816 | { | 3785 | { |
| 3817 | // The value of `builtin.test_functions` was either never referenced, or failed analysis. | 3786 | // The value of `builtin.test_functions` was either never referenced, or failed analysis. |
| 3818 | // Either way, we don't need to do anything. | 3787 | // Either way, we don't need to do anything. |
| ... | @@ -3822,8 +3791,7 @@ pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -3822,8 +3791,7 @@ pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { |
| 3822 | // Okay, `builtin.test_functions` is (potentially) referenced and valid. Our job now is to swap | 3791 | // Okay, `builtin.test_functions` is (potentially) referenced and valid. Our job now is to swap |
| 3823 | // its placeholder `&.{}` value for the actual list of all test functions. | 3792 | // its placeholder `&.{}` value for the actual list of all test functions. |
| 3824 | 3793 | ||
| 3825 | const test_fns_val = zcu.navValue(nav_index); | 3794 | const test_fn_ty = Type.fromInterned(test_fns_nav.resolved.?.type).slicePtrFieldType(zcu).childType(zcu); |
| 3826 | const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); | ||
| 3827 | 3795 | ||
| 3828 | const array_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = array: { | 3796 | const array_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = array: { |
| 3829 | // Add zcu.test_functions to an array decl then make the test_functions | 3797 | // Add zcu.test_functions to an array decl then make the test_functions |
| ... | @@ -3914,10 +3882,12 @@ pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -3914,10 +3882,12 @@ pub fn populateTestFunctions(pt: Zcu.PerThread) Allocator.Error!void { |
| 3914 | } }), | 3882 | } }), |
| 3915 | .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(), | 3883 | .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(), |
| 3916 | } }); | 3884 | } }); |
| 3917 | ip.mutateVarInit(io, test_fns_val.toIntern(), new_init); | 3885 | var new_resolved_test_fns = test_fns_nav.resolved.?; |
| 3886 | new_resolved_test_fns.value = new_init; | ||
| 3887 | ip.resolveNav(io, test_fns_nav_index, new_resolved_test_fns); | ||
| 3918 | } | 3888 | } |
| 3919 | // The linker thread is not running, so we actually need to dispatch this task directly. | 3889 | // The linker thread is not running, so we actually need to dispatch this task directly. |
| 3920 | @import("../link.zig").linkTestFunctionsNav(pt, nav_index); | 3890 | @import("../link.zig").linkTestFunctionsNav(pt, test_fns_nav_index); |
| 3921 | } | 3891 | } |
| 3922 | 3892 | ||
| 3923 | /// Stores an error in `pt.zcu.failed_files` for this file, and sets the file | 3893 | /// Stores an error in `pt.zcu.failed_files` for this file, and sets the file |
| ... | @@ -4402,17 +4372,13 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 { | ... | @@ -4402,17 +4372,13 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 { |
| 4402 | pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Error!Type { | 4372 | pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Error!Type { |
| 4403 | const zcu = pt.zcu; | 4373 | const zcu = pt.zcu; |
| 4404 | const ip = &zcu.intern_pool; | 4374 | const ip = &zcu.intern_pool; |
| 4405 | const ty, const alignment, const @"addrspace", const is_const = switch (ip.getNav(nav_id).status) { | 4375 | const resolved_nav = ip.getNav(nav_id).resolved.?; |
| 4406 | .unresolved => unreachable, | ||
| 4407 | .type_resolved => |r| .{ r.type, r.alignment, r.@"addrspace", r.is_const }, | ||
| 4408 | .fully_resolved => |r| .{ ip.typeOf(r.val), r.alignment, r.@"addrspace", r.is_const }, | ||
| 4409 | }; | ||
| 4410 | return pt.ptrType(.{ | 4376 | return pt.ptrType(.{ |
| 4411 | .child = ty, | 4377 | .child = resolved_nav.type, |
| 4412 | .flags = .{ | 4378 | .flags = .{ |
| 4413 | .alignment = alignment, | 4379 | .alignment = resolved_nav.@"align", |
| 4414 | .address_space = @"addrspace", | 4380 | .address_space = resolved_nav.@"addrspace", |
| 4415 | .is_const = is_const, | 4381 | .is_const = resolved_nav.@"const", |
| 4416 | }, | 4382 | }, |
| 4417 | }); | 4383 | }); |
| 4418 | } | 4384 | } |
src/codegen.zig+6-6| ... | @@ -352,7 +352,6 @@ pub fn generateSymbol( | ... | @@ -352,7 +352,6 @@ pub fn generateSymbol( |
| 352 | else => unreachable, | 352 | else => unreachable, |
| 353 | }), | 353 | }), |
| 354 | }, | 354 | }, |
| 355 | .variable, | ||
| 356 | .@"extern", | 355 | .@"extern", |
| 357 | .func, | 356 | .func, |
| 358 | .enum_literal, | 357 | .enum_literal, |
| ... | @@ -787,7 +786,7 @@ fn lowerNavRef( | ... | @@ -787,7 +786,7 @@ fn lowerNavRef( |
| 787 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; | 786 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 788 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); | 787 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 789 | const is_obj = lf.comp.config.output_mode == .Obj; | 788 | const is_obj = lf.comp.config.output_mode == .Obj; |
| 790 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); | 789 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).resolved.?.type); |
| 791 | 790 | ||
| 792 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) and ip.getNav(nav_index).getExtern(ip) == null) { | 791 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) and ip.getNav(nav_index).getExtern(ip) == null) { |
| 793 | try w.splatByteAll(0xaa, ptr_width_bytes); | 792 | try w.splatByteAll(0xaa, ptr_width_bytes); |
| ... | @@ -876,10 +875,11 @@ pub fn genNavRef( | ... | @@ -876,10 +875,11 @@ pub fn genNavRef( |
| 876 | const nav = ip.getNav(nav_index); | 875 | const nav = ip.getNav(nav_index); |
| 877 | log.debug("genNavRef({f})", .{nav.fqn.fmt(ip)}); | 876 | log.debug("genNavRef({f})", .{nav.fqn.fmt(ip)}); |
| 878 | 877 | ||
| 879 | const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e| | 878 | const is_threadlocal = nav.resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded; |
| 880 | .{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded } | 879 | const lib_name, const linkage = if (nav.getExtern(ip)) |e| |
| 880 | .{ e.lib_name, e.linkage } | ||
| 881 | else | 881 | else |
| 882 | .{ .none, .internal, false }; | 882 | .{ .none, .internal }; |
| 883 | if (lf.cast(.elf)) |elf_file| { | 883 | if (lf.cast(.elf)) |elf_file| { |
| 884 | const zo = elf_file.zigObjectPtr().?; | 884 | const zo = elf_file.zigObjectPtr().?; |
| 885 | switch (linkage) { | 885 | switch (linkage) { |
| ... | @@ -1038,7 +1038,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo | ... | @@ -1038,7 +1038,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo |
| 1038 | 1038 | ||
| 1039 | .nav => |nav_index| { | 1039 | .nav => |nav_index| { |
| 1040 | const nav = ip.getNav(nav_index); | 1040 | const nav = ip.getNav(nav_index); |
| 1041 | const nav_ty: Type = .fromInterned(nav.typeOf(ip)); | 1041 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); |
| 1042 | if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) { | 1042 | if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) { |
| 1043 | return .{ .lea_nav = nav_index }; | 1043 | return .{ .lea_nav = nav_index }; |
| 1044 | } else { | 1044 | } else { |
src/codegen/aarch64/Mir.zig+1-1| ... | @@ -69,7 +69,7 @@ pub fn emit( | ... | @@ -69,7 +69,7 @@ pub fn emit( |
| 69 | const target = &mod.resolved_target.result; | 69 | const target = &mod.resolved_target.result; |
| 70 | mir_log.debug("{f}:", .{nav.fqn.fmt(ip)}); | 70 | mir_log.debug("{f}:", .{nav.fqn.fmt(ip)}); |
| 71 | 71 | ||
| 72 | const func_align = switch (nav.status.fully_resolved.alignment) { | 72 | const func_align = switch (nav.resolved.?.@"align") { |
| 73 | .none => switch (mod.optimize_mode) { | 73 | .none => switch (mod.optimize_mode) { |
| 74 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), | 74 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), |
| 75 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 75 | .ReleaseSmall => target_util.minFunctionAlignment(target), |
src/codegen/aarch64/Select.zig+2-4| ... | @@ -7207,7 +7207,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -7207,7 +7207,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 7207 | const ptr_ra = try ptr_vi.value.defReg(isel) orelse break :unused; | 7207 | const ptr_ra = try ptr_vi.value.defReg(isel) orelse break :unused; |
| 7208 | 7208 | ||
| 7209 | const ty_nav = air.data(air.inst_index).ty_nav; | 7209 | const ty_nav = air.data(air.inst_index).ty_nav; |
| 7210 | if (ZigType.fromInterned(ip.getNav(ty_nav.nav).typeOf(ip)).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) { | 7210 | if (ZigType.fromInterned(ip.getNav(ty_nav.nav).resolved.?.type).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) { |
| 7211 | false => { | 7211 | false => { |
| 7212 | try isel.nav_relocs.append(gpa, .{ | 7212 | try isel.nav_relocs.append(gpa, .{ |
| 7213 | .nav = ty_nav.nav, | 7213 | .nav = ty_nav.nav, |
| ... | @@ -10577,7 +10577,6 @@ pub const Value = struct { | ... | @@ -10577,7 +10577,6 @@ pub const Value = struct { |
| 10577 | => continue :type_key .{ .simple_type = .anyerror }, | 10577 | => continue :type_key .{ .simple_type = .anyerror }, |
| 10578 | .undef, | 10578 | .undef, |
| 10579 | .simple_value, | 10579 | .simple_value, |
| 10580 | .variable, | ||
| 10581 | .@"extern", | 10580 | .@"extern", |
| 10582 | .func, | 10581 | .func, |
| 10583 | .int, | 10582 | .int, |
| ... | @@ -10914,7 +10913,7 @@ pub const Value = struct { | ... | @@ -10914,7 +10913,7 @@ pub const Value = struct { |
| 10914 | .ptr => |ptr| { | 10913 | .ptr => |ptr| { |
| 10915 | assert(offset == 0 and size == 8); | 10914 | assert(offset == 0 and size == 8); |
| 10916 | break :free switch (ptr.base_addr) { | 10915 | break :free switch (ptr.base_addr) { |
| 10917 | .nav => |nav| if (ZigType.fromInterned(ip.getNav(nav).typeOf(ip)).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) { | 10916 | .nav => |nav| if (ZigType.fromInterned(ip.getNav(nav).resolved.?.type).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) { |
| 10918 | false => { | 10917 | false => { |
| 10919 | try isel.nav_relocs.append(zcu.gpa, .{ | 10918 | try isel.nav_relocs.append(zcu.gpa, .{ |
| 10920 | .nav = nav, | 10919 | .nav = nav, |
| ... | @@ -12300,7 +12299,6 @@ pub const CallAbiIterator = struct { | ... | @@ -12300,7 +12299,6 @@ pub const CallAbiIterator = struct { |
| 12300 | => continue :type_key .{ .simple_type = .anyerror }, | 12299 | => continue :type_key .{ .simple_type = .anyerror }, |
| 12301 | .undef, | 12300 | .undef, |
| 12302 | .simple_value, | 12301 | .simple_value, |
| 12303 | .variable, | ||
| 12304 | .@"extern", | 12302 | .@"extern", |
| 12305 | .func, | 12303 | .func, |
| 12306 | .int, | 12304 | .int, |
src/codegen/c.zig+31-41| ... | @@ -669,11 +669,9 @@ pub const DeclGen = struct { | ... | @@ -669,11 +669,9 @@ pub const DeclGen = struct { |
| 669 | return dg.renderUndefValue(w, ptr_ty, location); | 669 | return dg.renderUndefValue(w, ptr_ty, location); |
| 670 | } | 670 | } |
| 671 | 671 | ||
| 672 | // Chase function values in order to be able to reference the original function. | ||
| 673 | switch (ip.indexToKey(uav.val)) { | 672 | switch (ip.indexToKey(uav.val)) { |
| 674 | .variable => unreachable, | 673 | .func => unreachable, |
| 675 | .func => |func| return dg.renderNav(w, func.owner_nav, location), | 674 | .@"extern" => unreachable, |
| 676 | .@"extern" => |@"extern"| return dg.renderNav(w, @"extern".owner_nav, location), | ||
| 677 | else => {}, | 675 | else => {}, |
| 678 | } | 676 | } |
| 679 | 677 | ||
| ... | @@ -721,10 +719,9 @@ pub const DeclGen = struct { | ... | @@ -721,10 +719,9 @@ pub const DeclGen = struct { |
| 721 | const ip = &zcu.intern_pool; | 719 | const ip = &zcu.intern_pool; |
| 722 | 720 | ||
| 723 | // Chase function values in order to be able to reference the original function. | 721 | // Chase function values in order to be able to reference the original function. |
| 724 | const owner_nav = switch (ip.getNav(nav_index).status) { | 722 | const owner_nav = switch (ip.getNav(nav_index).resolved.?.value) { |
| 725 | .unresolved => unreachable, | 723 | .none => nav_index, // this can't be an extern or a function |
| 726 | .type_resolved => nav_index, // this can't be an extern or a function | 724 | else => |value| switch (ip.indexToKey(value)) { |
| 727 | .fully_resolved => |r| switch (ip.indexToKey(r.val)) { | ||
| 728 | .func => |f| f.owner_nav, | 725 | .func => |f| f.owner_nav, |
| 729 | .@"extern" => |e| e.owner_nav, | 726 | .@"extern" => |e| e.owner_nav, |
| 730 | else => nav_index, | 727 | else => nav_index, |
| ... | @@ -732,7 +729,7 @@ pub const DeclGen = struct { | ... | @@ -732,7 +729,7 @@ pub const DeclGen = struct { |
| 732 | }; | 729 | }; |
| 733 | 730 | ||
| 734 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | 731 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 735 | const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip)); | 732 | const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).resolved.?.type); |
| 736 | const ptr_ty = try pt.navPtrType(owner_nav); | 733 | const ptr_ty = try pt.navPtrType(owner_nav); |
| 737 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { | 734 | if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { |
| 738 | return dg.renderUndefValue(w, ptr_ty, location); | 735 | return dg.renderUndefValue(w, ptr_ty, location); |
| ... | @@ -924,7 +921,6 @@ pub const DeclGen = struct { | ... | @@ -924,7 +921,6 @@ pub const DeclGen = struct { |
| 924 | .false => try w.writeAll("false"), | 921 | .false => try w.writeAll("false"), |
| 925 | .true => try w.writeAll("true"), | 922 | .true => try w.writeAll("true"), |
| 926 | }, | 923 | }, |
| 927 | .variable, | ||
| 928 | .@"extern", | 924 | .@"extern", |
| 929 | .func, | 925 | .func, |
| 930 | .enum_literal, | 926 | .enum_literal, |
| ... | @@ -1575,7 +1571,6 @@ pub const DeclGen = struct { | ... | @@ -1575,7 +1571,6 @@ pub const DeclGen = struct { |
| 1575 | 1571 | ||
| 1576 | .undef, | 1572 | .undef, |
| 1577 | .simple_value, | 1573 | .simple_value, |
| 1578 | .variable, | ||
| 1579 | .@"extern", | 1574 | .@"extern", |
| 1580 | .func, | 1575 | .func, |
| 1581 | .int, | 1576 | .int, |
| ... | @@ -2276,13 +2271,13 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E | ... | @@ -2276,13 +2271,13 @@ pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) E |
| 2276 | try f.dg.renderFunctionSignature( | 2271 | try f.dg.renderFunctionSignature( |
| 2277 | fwd_decl_writer, | 2272 | fwd_decl_writer, |
| 2278 | nav_val, | 2273 | nav_val, |
| 2279 | nav.status.fully_resolved.alignment, | 2274 | nav.resolved.?.@"align", |
| 2280 | .forward_decl, | 2275 | .forward_decl, |
| 2281 | .{ .nav = nav_index }, | 2276 | .{ .nav = nav_index }, |
| 2282 | ); | 2277 | ); |
| 2283 | try fwd_decl_writer.writeAll(";\n"); | 2278 | try fwd_decl_writer.writeAll(";\n"); |
| 2284 | 2279 | ||
| 2285 | if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s| | 2280 | if (nav.resolved.?.@"linksection".toSlice(ip)) |s| |
| 2286 | try header_writer.print("zig_linksection_fn({f}) ", .{fmtStringLiteral(s, null)}); | 2281 | try header_writer.print("zig_linksection_fn({f}) ", .{fmtStringLiteral(s, null)}); |
| 2287 | try f.dg.renderFunctionSignature( | 2282 | try f.dg.renderFunctionSignature( |
| 2288 | header_writer, | 2283 | header_writer, |
| ... | @@ -2360,28 +2355,26 @@ pub fn genDecl(dg: *DeclGen, w: *Writer) Error!void { | ... | @@ -2360,28 +2355,26 @@ pub fn genDecl(dg: *DeclGen, w: *Writer) Error!void { |
| 2360 | const zcu = pt.zcu; | 2355 | const zcu = pt.zcu; |
| 2361 | const ip = &zcu.intern_pool; | 2356 | const ip = &zcu.intern_pool; |
| 2362 | const nav = ip.getNav(dg.owner_nav.unwrap().?); | 2357 | const nav = ip.getNav(dg.owner_nav.unwrap().?); |
| 2363 | const nav_ty: Type = .fromInterned(nav.typeOf(ip)); | 2358 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); |
| 2364 | 2359 | ||
| 2365 | const is_const: bool, const is_threadlocal: bool, const init_val: Value = switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 2360 | if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return; |
| 2366 | else => .{ true, false, .fromInterned(nav.status.fully_resolved.val) }, | ||
| 2367 | .variable => |v| .{ false, v.is_threadlocal, .fromInterned(v.init) }, | ||
| 2368 | .@"extern" => return, | ||
| 2369 | }; | ||
| 2370 | 2361 | ||
| 2371 | if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s| { | 2362 | const init_val: Value = .fromInterned(nav.resolved.?.value); |
| 2363 | |||
| 2364 | if (nav.resolved.?.@"linksection".toSlice(ip)) |s| { | ||
| 2372 | try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)}); | 2365 | try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)}); |
| 2373 | } | 2366 | } |
| 2374 | 2367 | ||
| 2375 | // We don't bother underaligning---it's unnecessary and hurts compatibility. | 2368 | // We don't bother underaligning---it's unnecessary and hurts compatibility. |
| 2376 | const a = nav.status.fully_resolved.alignment; | 2369 | const a = nav.resolved.?.@"align"; |
| 2377 | if (a != .none and a.compareStrict(.gt, nav_ty.abiAlignment(zcu))) { | 2370 | if (a != .none and a.compareStrict(.gt, nav_ty.abiAlignment(zcu))) { |
| 2378 | try w.print("zig_align({d}) ", .{a.toByteUnits().?}); | 2371 | try w.print("zig_align({d}) ", .{a.toByteUnits().?}); |
| 2379 | } | 2372 | } |
| 2380 | 2373 | ||
| 2381 | try genDeclValue(dg, w, .{ | 2374 | try genDeclValue(dg, w, .{ |
| 2382 | .name = .{ .nav = dg.owner_nav.unwrap().? }, | 2375 | .name = .{ .nav = dg.owner_nav.unwrap().? }, |
| 2383 | .@"const" = is_const, | 2376 | .@"const" = nav.resolved.?.@"const", |
| 2384 | .@"threadlocal" = is_threadlocal, | 2377 | .@"threadlocal" = nav.resolved.?.@"threadlocal", |
| 2385 | .init_val = init_val, | 2378 | .init_val = init_val, |
| 2386 | }); | 2379 | }); |
| 2387 | } | 2380 | } |
| ... | @@ -2393,19 +2386,18 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { | ... | @@ -2393,19 +2386,18 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { |
| 2393 | const zcu = pt.zcu; | 2386 | const zcu = pt.zcu; |
| 2394 | const ip = &zcu.intern_pool; | 2387 | const ip = &zcu.intern_pool; |
| 2395 | const nav = ip.getNav(dg.owner_nav.unwrap().?); | 2388 | const nav = ip.getNav(dg.owner_nav.unwrap().?); |
| 2396 | const nav_ty: Type = .fromInterned(nav.typeOf(ip)); | 2389 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); |
| 2397 | 2390 | ||
| 2398 | const is_const: bool, const is_threadlocal: bool, const init_val: Value = switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 2391 | const init_val: Value = switch (ip.indexToKey(nav.resolved.?.value)) { |
| 2399 | else => .{ true, false, .fromInterned(nav.status.fully_resolved.val) }, | 2392 | else => .fromInterned(nav.resolved.?.value), |
| 2400 | .variable => |v| .{ false, v.is_threadlocal, .fromInterned(v.init) }, | ||
| 2401 | 2393 | ||
| 2402 | .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) { | 2394 | .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) { |
| 2403 | .@"fn" => { | 2395 | .@"fn" => { |
| 2404 | try w.writeAll("zig_extern "); | 2396 | try w.writeAll("zig_extern "); |
| 2405 | try dg.renderFunctionSignature( | 2397 | try dg.renderFunctionSignature( |
| 2406 | w, | 2398 | w, |
| 2407 | Value.fromInterned(nav.status.fully_resolved.val), | 2399 | .fromInterned(nav.resolved.?.value), |
| 2408 | nav.status.fully_resolved.alignment, | 2400 | nav.resolved.?.@"align", |
| 2409 | .forward_decl, | 2401 | .forward_decl, |
| 2410 | .{ .@"export" = .{ | 2402 | .{ .@"export" = .{ |
| 2411 | .main_name = nav.name, | 2403 | .main_name = nav.name, |
| ... | @@ -2422,15 +2414,15 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { | ... | @@ -2422,15 +2414,15 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { |
| 2422 | .weak => try w.print("zig_extern zig_weak_linkage zig_visibility({t}) ", .{@"extern".visibility}), | 2414 | .weak => try w.print("zig_extern zig_weak_linkage zig_visibility({t}) ", .{@"extern".visibility}), |
| 2423 | .link_once => return dg.fail("TODO: CBE: implement linkonce linkage?", .{}), | 2415 | .link_once => return dg.fail("TODO: CBE: implement linkonce linkage?", .{}), |
| 2424 | } | 2416 | } |
| 2425 | if (@"extern".is_threadlocal and !dg.mod.single_threaded) { | 2417 | if (nav.resolved.?.@"threadlocal" and !dg.mod.single_threaded) { |
| 2426 | try w.writeAll("zig_threadlocal "); | 2418 | try w.writeAll("zig_threadlocal "); |
| 2427 | } | 2419 | } |
| 2428 | try dg.renderTypeAndName( | 2420 | try dg.renderTypeAndName( |
| 2429 | w, | 2421 | w, |
| 2430 | .fromInterned(nav.typeOf(ip)), | 2422 | .fromInterned(nav.resolved.?.type), |
| 2431 | .{ .nav = dg.owner_nav.unwrap().? }, | 2423 | .{ .nav = dg.owner_nav.unwrap().? }, |
| 2432 | .{ .@"const" = @"extern".is_const }, | 2424 | .{ .@"const" = nav.resolved.?.@"const" }, |
| 2433 | nav.getAlignment(), | 2425 | nav.resolved.?.@"align", |
| 2434 | ); | 2426 | ); |
| 2435 | try w.writeAll(";\n"); | 2427 | try w.writeAll(";\n"); |
| 2436 | return; | 2428 | return; |
| ... | @@ -2439,15 +2431,15 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { | ... | @@ -2439,15 +2431,15 @@ pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void { |
| 2439 | }; | 2431 | }; |
| 2440 | 2432 | ||
| 2441 | // We don't bother underaligning---it's unnecessary and hurts compatibility. | 2433 | // We don't bother underaligning---it's unnecessary and hurts compatibility. |
| 2442 | const a = nav.status.fully_resolved.alignment; | 2434 | const a = nav.resolved.?.@"align"; |
| 2443 | if (a != .none and a.compareStrict(.gt, nav_ty.abiAlignment(zcu))) { | 2435 | if (a != .none and a.compareStrict(.gt, nav_ty.abiAlignment(zcu))) { |
| 2444 | try w.print("zig_align({d}) ", .{a.toByteUnits().?}); | 2436 | try w.print("zig_align({d}) ", .{a.toByteUnits().?}); |
| 2445 | } | 2437 | } |
| 2446 | 2438 | ||
| 2447 | try genDeclValueFwd(dg, w, .{ | 2439 | try genDeclValueFwd(dg, w, .{ |
| 2448 | .name = .{ .nav = dg.owner_nav.unwrap().? }, | 2440 | .name = .{ .nav = dg.owner_nav.unwrap().? }, |
| 2449 | .@"const" = is_const, | 2441 | .@"const" = nav.resolved.?.@"const", |
| 2450 | .@"threadlocal" = is_threadlocal, | 2442 | .@"threadlocal" = nav.resolved.?.@"threadlocal", |
| 2451 | .init_val = init_val, | 2443 | .init_val = init_val, |
| 2452 | }); | 2444 | }); |
| 2453 | } | 2445 | } |
| ... | @@ -2514,11 +2506,9 @@ pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indic | ... | @@ -2514,11 +2506,9 @@ pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indic |
| 2514 | ); | 2506 | ); |
| 2515 | try w.writeAll(";\n"); | 2507 | try w.writeAll(";\n"); |
| 2516 | }; | 2508 | }; |
| 2517 | const is_const = switch (ip.indexToKey(exported_val.toIntern())) { | 2509 | const is_const = switch (exported) { |
| 2518 | .func => unreachable, | 2510 | .nav => |nav| ip.getNav(nav).resolved.?.@"const", |
| 2519 | .@"extern" => |@"extern"| @"extern".is_const, | 2511 | .uav => true, |
| 2520 | .variable => false, | ||
| 2521 | else => true, | ||
| 2522 | }; | 2512 | }; |
| 2523 | for (export_indices) |export_index| { | 2513 | for (export_indices) |export_index| { |
| 2524 | const @"export" = export_index.ptr(zcu); | 2514 | const @"export" = export_index.ptr(zcu); |
src/codegen/c/type.zig-1| ... | @@ -990,7 +990,6 @@ pub const CType = union(enum) { | ... | @@ -990,7 +990,6 @@ pub const CType = union(enum) { |
| 990 | // values, not types | 990 | // values, not types |
| 991 | .undef, | 991 | .undef, |
| 992 | .simple_value, | 992 | .simple_value, |
| 993 | .variable, | ||
| 994 | .@"extern", | 993 | .@"extern", |
| 995 | .func, | 994 | .func, |
| 996 | .int, | 995 | .int, |
src/codegen/llvm.zig+27-34| ... | @@ -1279,7 +1279,7 @@ pub const Object = struct { | ... | @@ -1279,7 +1279,7 @@ pub const Object = struct { |
| 1279 | } }, &o.builder); | 1279 | } }, &o.builder); |
| 1280 | } | 1280 | } |
| 1281 | 1281 | ||
| 1282 | if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |section| | 1282 | if (nav.resolved.?.@"linksection".toSlice(ip)) |section| |
| 1283 | function_index.setSection(try o.builder.string(section), &o.builder); | 1283 | function_index.setSection(try o.builder.string(section), &o.builder); |
| 1284 | 1284 | ||
| 1285 | var deinit_wip = true; | 1285 | var deinit_wip = true; |
| ... | @@ -1487,7 +1487,7 @@ pub const Object = struct { | ... | @@ -1487,7 +1487,7 @@ pub const Object = struct { |
| 1487 | const file = try o.getDebugFile(pt, file_scope); | 1487 | const file = try o.getDebugFile(pt, file_scope); |
| 1488 | 1488 | ||
| 1489 | const line_number = zcu.navSrcLine(func.owner_nav) + 1; | 1489 | const line_number = zcu.navSrcLine(func.owner_nav) + 1; |
| 1490 | const is_internal_linkage = ip.indexToKey(nav.status.fully_resolved.val) != .@"extern"; | 1490 | const is_internal_linkage = ip.indexToKey(nav.resolved.?.value) != .@"extern"; |
| 1491 | const debug_decl_type = try o.getDebugType(pt, fn_ty); | 1491 | const debug_decl_type = try o.getDebugType(pt, fn_ty); |
| 1492 | 1492 | ||
| 1493 | const subprogram = try o.builder.debugSubprogram( | 1493 | const subprogram = try o.builder.debugSubprogram( |
| ... | @@ -1662,7 +1662,7 @@ pub const Object = struct { | ... | @@ -1662,7 +1662,7 @@ pub const Object = struct { |
| 1662 | .elf, .wasm => break :coff_export_flags, | 1662 | .elf, .wasm => break :coff_export_flags, |
| 1663 | .coff => |*coff| coff, | 1663 | .coff => |*coff| coff, |
| 1664 | }; | 1664 | }; |
| 1665 | if (!ip.isFunctionType(ip.getNav(nav_index).typeOf(ip))) break :coff_export_flags; | 1665 | if (!ip.isFunctionType(ip.getNav(nav_index).resolved.?.type)) break :coff_export_flags; |
| 1666 | const flags = &coff.lld_export_flags; | 1666 | const flags = &coff.lld_export_flags; |
| 1667 | for (export_indices) |export_index| { | 1667 | for (export_indices) |export_index| { |
| 1668 | const name = export_index.ptr(zcu).opts.name; | 1668 | const name = export_index.ptr(zcu).opts.name; |
| ... | @@ -2677,7 +2677,7 @@ pub const Object = struct { | ... | @@ -2677,7 +2677,7 @@ pub const Object = struct { |
| 2677 | const gpa = o.gpa; | 2677 | const gpa = o.gpa; |
| 2678 | const nav = ip.getNav(nav_index); | 2678 | const nav = ip.getNav(nav_index); |
| 2679 | const owner_mod = zcu.navFileScope(nav_index).mod.?; | 2679 | const owner_mod = zcu.navFileScope(nav_index).mod.?; |
| 2680 | const ty: Type = .fromInterned(nav.typeOf(ip)); | 2680 | const ty: Type = .fromInterned(nav.resolved.?.type); |
| 2681 | const gop = try o.nav_map.getOrPut(gpa, nav_index); | 2681 | const gop = try o.nav_map.getOrPut(gpa, nav_index); |
| 2682 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; | 2682 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; |
| 2683 | 2683 | ||
| ... | @@ -2692,7 +2692,7 @@ pub const Object = struct { | ... | @@ -2692,7 +2692,7 @@ pub const Object = struct { |
| 2692 | const function_index = try o.builder.addFunction( | 2692 | const function_index = try o.builder.addFunction( |
| 2693 | try o.lowerType(pt, ty), | 2693 | try o.lowerType(pt, ty), |
| 2694 | try o.builder.strtabString((if (is_extern) nav.name else nav.fqn).toSlice(ip)), | 2694 | try o.builder.strtabString((if (is_extern) nav.name else nav.fqn).toSlice(ip)), |
| 2695 | toLlvmAddressSpace(nav.getAddrspace(), target), | 2695 | toLlvmAddressSpace(nav.resolved.?.@"addrspace", target), |
| 2696 | ); | 2696 | ); |
| 2697 | gop.value_ptr.* = function_index.ptrConst(&o.builder).global; | 2697 | gop.value_ptr.* = function_index.ptrConst(&o.builder).global; |
| 2698 | 2698 | ||
| ... | @@ -2809,8 +2809,8 @@ pub const Object = struct { | ... | @@ -2809,8 +2809,8 @@ pub const Object = struct { |
| 2809 | } | 2809 | } |
| 2810 | } | 2810 | } |
| 2811 | 2811 | ||
| 2812 | if (nav.getAlignment() != .none) | 2812 | if (nav.resolved.?.@"align" != .none) |
| 2813 | function_index.setAlignment(nav.getAlignment().toLlvm(), &o.builder); | 2813 | function_index.setAlignment(nav.resolved.?.@"align".toLlvm(), &o.builder); |
| 2814 | 2814 | ||
| 2815 | // Function attributes that are independent of analysis results of the function body. | 2815 | // Function attributes that are independent of analysis results of the function body. |
| 2816 | try o.addCommonFnAttributes( | 2816 | try o.addCommonFnAttributes( |
| ... | @@ -2951,15 +2951,12 @@ pub const Object = struct { | ... | @@ -2951,15 +2951,12 @@ pub const Object = struct { |
| 2951 | const zcu = pt.zcu; | 2951 | const zcu = pt.zcu; |
| 2952 | const ip = &zcu.intern_pool; | 2952 | const ip = &zcu.intern_pool; |
| 2953 | const nav = ip.getNav(nav_index); | 2953 | const nav = ip.getNav(nav_index); |
| 2954 | const linkage: std.builtin.GlobalLinkage, const visibility: Builder.Visibility, const is_threadlocal, const is_dll_import = switch (nav.status) { | 2954 | const linkage: std.builtin.GlobalLinkage, const visibility: Builder.Visibility, const is_dll_import: bool = switch (nav.resolved.?.value) { |
| 2955 | .unresolved => unreachable, | 2955 | .none => .{ .internal, .default, false }, // this is a source declaration which is *not* marked `extern` |
| 2956 | .fully_resolved => |r| switch (ip.indexToKey(r.val)) { | 2956 | else => |val| switch (ip.indexToKey(val)) { |
| 2957 | .variable => |variable| .{ .internal, .default, variable.is_threadlocal, false }, | 2957 | else => .{ .internal, .default, false }, |
| 2958 | .@"extern" => |@"extern"| .{ @"extern".linkage, .fromSymbolVisibility(@"extern".visibility), @"extern".is_threadlocal, @"extern".is_dll_import }, | 2958 | .@"extern" => |e| .{ e.linkage, .fromSymbolVisibility(e.visibility), e.is_dll_import }, |
| 2959 | else => .{ .internal, .default, false, false }, | ||
| 2960 | }, | 2959 | }, |
| 2961 | // This means it's a source declaration which is not `extern`! | ||
| 2962 | .type_resolved => |r| .{ .internal, .default, r.is_threadlocal, false }, | ||
| 2963 | }; | 2960 | }; |
| 2964 | 2961 | ||
| 2965 | const variable_index = try o.builder.addVariable( | 2962 | const variable_index = try o.builder.addVariable( |
| ... | @@ -2968,8 +2965,8 @@ pub const Object = struct { | ... | @@ -2968,8 +2965,8 @@ pub const Object = struct { |
| 2968 | .strong, .weak => nav.name, | 2965 | .strong, .weak => nav.name, |
| 2969 | .link_once => unreachable, | 2966 | .link_once => unreachable, |
| 2970 | }.toSlice(ip)), | 2967 | }.toSlice(ip)), |
| 2971 | try o.lowerType(pt, Type.fromInterned(nav.typeOf(ip))), | 2968 | try o.lowerType(pt, .fromInterned(nav.resolved.?.type)), |
| 2972 | toLlvmGlobalAddressSpace(nav.getAddrspace(), zcu.getTarget()), | 2969 | toLlvmGlobalAddressSpace(nav.resolved.?.@"addrspace", zcu.getTarget()), |
| 2973 | ); | 2970 | ); |
| 2974 | gop.value_ptr.* = variable_index.ptrConst(&o.builder).global; | 2971 | gop.value_ptr.* = variable_index.ptrConst(&o.builder).global; |
| 2975 | 2972 | ||
| ... | @@ -2987,7 +2984,7 @@ pub const Object = struct { | ... | @@ -2987,7 +2984,7 @@ pub const Object = struct { |
| 2987 | .link_once => unreachable, | 2984 | .link_once => unreachable, |
| 2988 | }, &o.builder); | 2985 | }, &o.builder); |
| 2989 | variable_index.setUnnamedAddr(.default, &o.builder); | 2986 | variable_index.setUnnamedAddr(.default, &o.builder); |
| 2990 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.?.single_threaded) | 2987 | if (nav.resolved.?.@"threadlocal" and !zcu.navFileScope(nav_index).mod.?.single_threaded) |
| 2991 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 2988 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 2992 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); | 2989 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); |
| 2993 | }, | 2990 | }, |
| ... | @@ -3422,7 +3419,6 @@ pub const Object = struct { | ... | @@ -3422,7 +3419,6 @@ pub const Object = struct { |
| 3422 | // values, not types | 3419 | // values, not types |
| 3423 | .undef, | 3420 | .undef, |
| 3424 | .simple_value, | 3421 | .simple_value, |
| 3425 | .variable, | ||
| 3426 | .@"extern", | 3422 | .@"extern", |
| 3427 | .func, | 3423 | .func, |
| 3428 | .int, | 3424 | .int, |
| ... | @@ -3553,9 +3549,7 @@ pub const Object = struct { | ... | @@ -3553,9 +3549,7 @@ pub const Object = struct { |
| 3553 | .false => .false, | 3549 | .false => .false, |
| 3554 | .true => .true, | 3550 | .true => .true, |
| 3555 | }, | 3551 | }, |
| 3556 | .variable, | 3552 | .enum_literal => unreachable, // non-runtime value |
| 3557 | .enum_literal, | ||
| 3558 | => unreachable, // non-runtime values | ||
| 3559 | .@"extern" => |@"extern"| { | 3553 | .@"extern" => |@"extern"| { |
| 3560 | const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav); | 3554 | const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav); |
| 3561 | return function_index.ptrConst(&o.builder).global.toConst(); | 3555 | return function_index.ptrConst(&o.builder).global.toConst(); |
| ... | @@ -4131,7 +4125,7 @@ pub const Object = struct { | ... | @@ -4131,7 +4125,7 @@ pub const Object = struct { |
| 4131 | 4125 | ||
| 4132 | const nav = ip.getNav(nav_index); | 4126 | const nav = ip.getNav(nav_index); |
| 4133 | 4127 | ||
| 4134 | const nav_ty = Type.fromInterned(nav.typeOf(ip)); | 4128 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); |
| 4135 | const ptr_ty = try pt.navPtrType(nav_index); | 4129 | const ptr_ty = try pt.navPtrType(nav_index); |
| 4136 | 4130 | ||
| 4137 | if (nav.getExtern(ip) == null and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { | 4131 | if (nav.getExtern(ip) == null and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) { |
| ... | @@ -4145,7 +4139,7 @@ pub const Object = struct { | ... | @@ -4145,7 +4139,7 @@ pub const Object = struct { |
| 4145 | 4139 | ||
| 4146 | const llvm_val = try o.builder.convConst( | 4140 | const llvm_val = try o.builder.convConst( |
| 4147 | llvm_global.toConst(), | 4141 | llvm_global.toConst(), |
| 4148 | try o.builder.ptrType(toLlvmAddressSpace(nav.getAddrspace(), zcu.getTarget())), | 4142 | try o.builder.ptrType(toLlvmAddressSpace(nav.resolved.?.@"addrspace", zcu.getTarget())), |
| 4149 | ); | 4143 | ); |
| 4150 | 4144 | ||
| 4151 | return o.builder.convConst(llvm_val, try o.lowerType(pt, ptr_ty)); | 4145 | return o.builder.convConst(llvm_val, try o.lowerType(pt, ptr_ty)); |
| ... | @@ -4398,14 +4392,13 @@ pub const NavGen = struct { | ... | @@ -4398,14 +4392,13 @@ pub const NavGen = struct { |
| 4398 | const ip = &zcu.intern_pool; | 4392 | const ip = &zcu.intern_pool; |
| 4399 | const nav_index = ng.nav_index; | 4393 | const nav_index = ng.nav_index; |
| 4400 | const nav = ip.getNav(nav_index); | 4394 | const nav = ip.getNav(nav_index); |
| 4401 | const resolved = nav.status.fully_resolved; | 4395 | const resolved = nav.resolved.?; |
| 4402 | 4396 | ||
| 4403 | const lib_name, const linkage, const visibility: Builder.Visibility, const is_threadlocal, const is_dll_import, const is_const, const init_val, const owner_nav = switch (ip.indexToKey(resolved.val)) { | 4397 | const lib_name, const linkage, const visibility: Builder.Visibility, const is_dll_import, const init_val, const owner_nav = switch (ip.indexToKey(resolved.value)) { |
| 4404 | .variable => |variable| .{ .none, .internal, .default, variable.is_threadlocal, false, false, variable.init, variable.owner_nav }, | 4398 | else => .{ .none, .internal, .default, false, resolved.value, nav_index }, |
| 4405 | .@"extern" => |@"extern"| .{ @"extern".lib_name, @"extern".linkage, .fromSymbolVisibility(@"extern".visibility), @"extern".is_threadlocal, @"extern".is_dll_import, @"extern".is_const, .none, @"extern".owner_nav }, | 4399 | .@"extern" => |e| .{ e.lib_name, e.linkage, .fromSymbolVisibility(e.visibility), e.is_dll_import, .none, e.owner_nav }, |
| 4406 | else => .{ .none, .internal, .default, false, false, true, resolved.val, nav_index }, | ||
| 4407 | }; | 4400 | }; |
| 4408 | const ty = Type.fromInterned(nav.typeOf(ip)); | 4401 | const ty: Type = .fromInterned(nav.resolved.?.type); |
| 4409 | 4402 | ||
| 4410 | if (linkage != .internal and ip.isFunctionType(ty.toIntern())) { | 4403 | if (linkage != .internal and ip.isFunctionType(ty.toIntern())) { |
| 4411 | const function_index = try o.resolveLlvmFunction(pt, owner_nav); | 4404 | const function_index = try o.resolveLlvmFunction(pt, owner_nav); |
| ... | @@ -4448,7 +4441,7 @@ pub const NavGen = struct { | ... | @@ -4448,7 +4441,7 @@ pub const NavGen = struct { |
| 4448 | variable_index.setAlignment(zcu.navAlignment(nav_index).toLlvm(), &o.builder); | 4441 | variable_index.setAlignment(zcu.navAlignment(nav_index).toLlvm(), &o.builder); |
| 4449 | if (resolved.@"linksection".toSlice(ip)) |section| | 4442 | if (resolved.@"linksection".toSlice(ip)) |section| |
| 4450 | variable_index.setSection(try o.builder.string(section), &o.builder); | 4443 | variable_index.setSection(try o.builder.string(section), &o.builder); |
| 4451 | if (is_const) variable_index.setMutability(.constant, &o.builder); | 4444 | if (resolved.@"const") variable_index.setMutability(.constant, &o.builder); |
| 4452 | try variable_index.setInitializer(switch (init_val) { | 4445 | try variable_index.setInitializer(switch (init_val) { |
| 4453 | .none => .no_init, | 4446 | .none => .no_init, |
| 4454 | else => try o.lowerValue(pt, init_val), | 4447 | else => try o.lowerValue(pt, init_val), |
| ... | @@ -4457,7 +4450,7 @@ pub const NavGen = struct { | ... | @@ -4457,7 +4450,7 @@ pub const NavGen = struct { |
| 4457 | 4450 | ||
| 4458 | const file_scope = zcu.navFileScopeIndex(nav_index); | 4451 | const file_scope = zcu.navFileScopeIndex(nav_index); |
| 4459 | const mod = zcu.fileByIndex(file_scope).mod.?; | 4452 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| 4460 | if (is_threadlocal and !mod.single_threaded) | 4453 | if (resolved.@"threadlocal" and !mod.single_threaded) |
| 4461 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 4454 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 4462 | 4455 | ||
| 4463 | const line_number = zcu.navSrcLine(nav_index) + 1; | 4456 | const line_number = zcu.navSrcLine(nav_index) + 1; |
| ... | @@ -5475,7 +5468,7 @@ pub const FuncGen = struct { | ... | @@ -5475,7 +5468,7 @@ pub const FuncGen = struct { |
| 5475 | _ = try self.wip.retVoid(); | 5468 | _ = try self.wip.retVoid(); |
| 5476 | return; | 5469 | return; |
| 5477 | } | 5470 | } |
| 5478 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?; | 5471 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).resolved.?.type)).?; |
| 5479 | if (!ret_ty.hasRuntimeBits(zcu)) { | 5472 | if (!ret_ty.hasRuntimeBits(zcu)) { |
| 5480 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { | 5473 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { |
| 5481 | // Functions with an empty error set are emitted with an error code | 5474 | // Functions with an empty error set are emitted with an error code |
| ... | @@ -5540,7 +5533,7 @@ pub const FuncGen = struct { | ... | @@ -5540,7 +5533,7 @@ pub const FuncGen = struct { |
| 5540 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5533 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5541 | const ptr_ty = self.typeOf(un_op); | 5534 | const ptr_ty = self.typeOf(un_op); |
| 5542 | const ret_ty = ptr_ty.childType(zcu); | 5535 | const ret_ty = ptr_ty.childType(zcu); |
| 5543 | const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?; | 5536 | const fn_info = zcu.typeToFunc(.fromInterned(ip.getNav(self.ng.nav_index).resolved.?.type)).?; |
| 5544 | if (!ret_ty.hasRuntimeBits(zcu)) { | 5537 | if (!ret_ty.hasRuntimeBits(zcu)) { |
| 5545 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { | 5538 | if (Type.fromInterned(fn_info.return_type).isError(zcu)) { |
| 5546 | // Functions with an empty error set are emitted with an error code | 5539 | // Functions with an empty error set are emitted with an error code |
src/codegen/spirv/CodeGen.zig+39-58| ... | @@ -256,7 +256,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { | ... | @@ -256,7 +256,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 256 | .global => { | 256 | .global => { |
| 257 | const key = ip.indexToKey(val.toIntern()).@"extern"; | 257 | const key = ip.indexToKey(val.toIntern()).@"extern"; |
| 258 | 258 | ||
| 259 | const storage_class = cg.module.storageClass(nav.getAddrspace()); | 259 | const storage_class = cg.module.storageClass(nav.resolved.?.@"addrspace"); |
| 260 | assert(storage_class != .generic); // These should be instance globals | 260 | assert(storage_class != .generic); // These should be instance globals |
| 261 | 261 | ||
| 262 | const ty_id = try cg.resolveType(ty, .indirect); | 262 | const ty_id = try cg.resolveType(ty, .indirect); |
| ... | @@ -314,64 +314,47 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { | ... | @@ -314,64 +314,47 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 314 | try cg.module.debugName(result_id, nav.fqn.toSlice(ip)); | 314 | try cg.module.debugName(result_id, nav.fqn.toSlice(ip)); |
| 315 | }, | 315 | }, |
| 316 | .invocation_global => { | 316 | .invocation_global => { |
| 317 | const maybe_init_val: ?Value = switch (ip.indexToKey(val.toIntern())) { | ||
| 318 | .func => unreachable, | ||
| 319 | .variable => |variable| .fromInterned(variable.init), | ||
| 320 | .@"extern" => null, | ||
| 321 | else => val, | ||
| 322 | }; | ||
| 323 | |||
| 324 | const ty_id = try cg.resolveType(ty, .indirect); | 317 | const ty_id = try cg.resolveType(ty, .indirect); |
| 325 | const ptr_ty_id = try cg.module.ptrType(ty_id, .function); | 318 | const ptr_ty_id = try cg.module.ptrType(ty_id, .function); |
| 326 | 319 | ||
| 327 | if (maybe_init_val) |init_val| { | 320 | // TODO: Combine with resolveAnonDecl? |
| 328 | // TODO: Combine with resolveAnonDecl? | 321 | const void_ty_id = try cg.resolveType(.void, .direct); |
| 329 | const void_ty_id = try cg.resolveType(.void, .direct); | 322 | const initializer_proto_ty_id = try cg.module.functionType(void_ty_id, &.{}); |
| 330 | const initializer_proto_ty_id = try cg.module.functionType(void_ty_id, &.{}); | ||
| 331 | |||
| 332 | const initializer_id = cg.module.allocId(); | ||
| 333 | try cg.prologue.emit(gpa, .OpFunction, .{ | ||
| 334 | .id_result_type = try cg.resolveType(.void, .direct), | ||
| 335 | .id_result = initializer_id, | ||
| 336 | .function_control = .{}, | ||
| 337 | .function_type = initializer_proto_ty_id, | ||
| 338 | }); | ||
| 339 | 323 | ||
| 340 | const root_block_id = cg.module.allocId(); | 324 | const initializer_id = cg.module.allocId(); |
| 341 | try cg.prologue.emit(gpa, .OpLabel, .{ | 325 | try cg.prologue.emit(gpa, .OpFunction, .{ |
| 342 | .id_result = root_block_id, | 326 | .id_result_type = try cg.resolveType(.void, .direct), |
| 343 | }); | 327 | .id_result = initializer_id, |
| 344 | cg.block_label = root_block_id; | 328 | .function_control = .{}, |
| 329 | .function_type = initializer_proto_ty_id, | ||
| 330 | }); | ||
| 345 | 331 | ||
| 346 | const val_id = try cg.constant(ty, init_val, .indirect); | 332 | const root_block_id = cg.module.allocId(); |
| 347 | try cg.body.emit(gpa, .OpStore, .{ | 333 | try cg.prologue.emit(gpa, .OpLabel, .{ |
| 348 | .pointer = result_id, | 334 | .id_result = root_block_id, |
| 349 | .object = val_id, | 335 | }); |
| 350 | }); | 336 | cg.block_label = root_block_id; |
| 351 | 337 | ||
| 352 | try cg.body.emit(gpa, .OpReturn, {}); | 338 | const val_id = try cg.constant(ty, val, .indirect); |
| 353 | try cg.body.emit(gpa, .OpFunctionEnd, {}); | 339 | try cg.body.emit(gpa, .OpStore, .{ |
| 354 | try cg.module.sections.functions.append(gpa, cg.prologue); | 340 | .pointer = result_id, |
| 355 | try cg.module.sections.functions.append(gpa, cg.body); | 341 | .object = val_id, |
| 342 | }); | ||
| 356 | 343 | ||
| 357 | try cg.module.debugNameFmt(initializer_id, "initializer of {f}", .{nav.fqn.fmt(ip)}); | 344 | try cg.body.emit(gpa, .OpReturn, {}); |
| 345 | try cg.body.emit(gpa, .OpFunctionEnd, {}); | ||
| 346 | try cg.module.sections.functions.append(gpa, cg.prologue); | ||
| 347 | try cg.module.sections.functions.append(gpa, cg.body); | ||
| 358 | 348 | ||
| 359 | try cg.module.sections.globals.emit(gpa, .OpExtInst, .{ | 349 | try cg.module.debugNameFmt(initializer_id, "initializer of {f}", .{nav.fqn.fmt(ip)}); |
| 360 | .id_result_type = ptr_ty_id, | 350 | |
| 361 | .id_result = result_id, | 351 | try cg.module.sections.globals.emit(gpa, .OpExtInst, .{ |
| 362 | .set = try cg.module.importInstructionSet(.zig), | 352 | .id_result_type = ptr_ty_id, |
| 363 | .instruction = .{ .inst = @intFromEnum(spec.Zig.InvocationGlobal) }, | 353 | .id_result = result_id, |
| 364 | .id_ref_4 = &.{initializer_id}, | 354 | .set = try cg.module.importInstructionSet(.zig), |
| 365 | }); | 355 | .instruction = .{ .inst = @intFromEnum(spec.Zig.InvocationGlobal) }, |
| 366 | } else { | 356 | .id_ref_4 = &.{initializer_id}, |
| 367 | try cg.module.sections.globals.emit(gpa, .OpExtInst, .{ | 357 | }); |
| 368 | .id_result_type = ptr_ty_id, | ||
| 369 | .id_result = result_id, | ||
| 370 | .set = try cg.module.importInstructionSet(.zig), | ||
| 371 | .instruction = .{ .inst = @intFromEnum(spec.Zig.InvocationGlobal) }, | ||
| 372 | .id_ref_4 = &.{}, | ||
| 373 | }); | ||
| 374 | } | ||
| 375 | }, | 358 | }, |
| 376 | } | 359 | } |
| 377 | 360 | ||
| ... | @@ -810,7 +793,6 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id { | ... | @@ -810,7 +793,6 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id { |
| 810 | 793 | ||
| 811 | .undef => unreachable, // handled above | 794 | .undef => unreachable, // handled above |
| 812 | 795 | ||
| 813 | .variable, | ||
| 814 | .@"extern", | 796 | .@"extern", |
| 815 | .func, | 797 | .func, |
| 816 | .enum_literal, | 798 | .enum_literal, |
| ... | @@ -1170,12 +1152,11 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id { | ... | @@ -1170,12 +1152,11 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id { |
| 1170 | const ip = &zcu.intern_pool; | 1152 | const ip = &zcu.intern_pool; |
| 1171 | const ty_id = try cg.resolveType(ty, .direct); | 1153 | const ty_id = try cg.resolveType(ty, .direct); |
| 1172 | const nav = ip.getNav(nav_index); | 1154 | const nav = ip.getNav(nav_index); |
| 1173 | const nav_ty: Type = .fromInterned(nav.typeOf(ip)); | 1155 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); |
| 1174 | 1156 | ||
| 1175 | switch (nav.status) { | 1157 | switch (nav.resolved.?.value) { |
| 1176 | .unresolved => unreachable, | 1158 | .none => {}, // this is not a function or extern |
| 1177 | .type_resolved => {}, // this is not a function or extern | 1159 | else => |value| switch (ip.indexToKey(value)) { |
| 1178 | .fully_resolved => |r| switch (ip.indexToKey(r.val)) { | ||
| 1179 | .func => { | 1160 | .func => { |
| 1180 | // TODO: Properly lower function pointers. For now we are going to hack around it and | 1161 | // TODO: Properly lower function pointers. For now we are going to hack around it and |
| 1181 | // just generate an empty pointer. Function pointers are represented by a pointer to usize. | 1162 | // just generate an empty pointer. Function pointers are represented by a pointer to usize. |
| ... | @@ -1196,7 +1177,7 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id { | ... | @@ -1196,7 +1177,7 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id { |
| 1196 | const spv_decl_result_id = spv_decl.result_id; | 1177 | const spv_decl_result_id = spv_decl.result_id; |
| 1197 | assert(spv_decl.kind != .func); | 1178 | assert(spv_decl.kind != .func); |
| 1198 | 1179 | ||
| 1199 | const storage_class = cg.module.storageClass(nav.getAddrspace()); | 1180 | const storage_class = cg.module.storageClass(nav.resolved.?.@"addrspace"); |
| 1200 | try cg.addFunctionDep(spv_decl_index, storage_class); | 1181 | try cg.addFunctionDep(spv_decl_index, storage_class); |
| 1201 | 1182 | ||
| 1202 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); | 1183 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
src/codegen/spirv/Module.zig+2-2| ... | @@ -252,9 +252,9 @@ pub fn resolveNav(module: *Module, ip: *InternPool, nav_index: InternPool.Nav.In | ... | @@ -252,9 +252,9 @@ pub fn resolveNav(module: *Module, ip: *InternPool, nav_index: InternPool.Nav.In |
| 252 | if (!entry.found_existing) { | 252 | if (!entry.found_existing) { |
| 253 | const nav = ip.getNav(nav_index); | 253 | const nav = ip.getNav(nav_index); |
| 254 | // TODO: Extern fn? | 254 | // TODO: Extern fn? |
| 255 | const kind: Decl.Kind = if (ip.isFunctionType(nav.typeOf(ip))) | 255 | const kind: Decl.Kind = if (ip.isFunctionType(nav.resolved.?.type)) |
| 256 | .func | 256 | .func |
| 257 | else switch (nav.getAddrspace()) { | 257 | else switch (nav.resolved.?.@"addrspace") { |
| 258 | .generic => .invocation_global, | 258 | .generic => .invocation_global, |
| 259 | else => .global, | 259 | else => .global, |
| 260 | }; | 260 | }; |
src/codegen/wasm/CodeGen.zig+1-2| ... | @@ -575,7 +575,7 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { | ... | @@ -575,7 +575,7 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 575 | .nav_ref => |nav_ref| { | 575 | .nav_ref => |nav_ref| { |
| 576 | const zcu = cg.pt.zcu; | 576 | const zcu = cg.pt.zcu; |
| 577 | const ip = &zcu.intern_pool; | 577 | const ip = &zcu.intern_pool; |
| 578 | if (ip.getNav(nav_ref.nav_index).isFn(ip)) { | 578 | if (ip.zigTypeTag(ip.getNav(nav_ref.nav_index).resolved.?.type) == .@"fn") { |
| 579 | assert(nav_ref.offset == 0); | 579 | assert(nav_ref.offset == 0); |
| 580 | try cg.mir_indirect_function_set.put(cg.gpa, nav_ref.nav_index, {}); | 580 | try cg.mir_indirect_function_set.put(cg.gpa, nav_ref.nav_index, {}); |
| 581 | try cg.addInst(.{ .tag = .func_ref, .data = .{ .nav_index = nav_ref.nav_index } }); | 581 | try cg.addInst(.{ .tag = .func_ref, .data = .{ .nav_index = nav_ref.nav_index } }); |
| ... | @@ -4401,7 +4401,6 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { | ... | @@ -4401,7 +4401,6 @@ fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue { |
| 4401 | else => unreachable, | 4401 | else => unreachable, |
| 4402 | } }, | 4402 | } }, |
| 4403 | }, | 4403 | }, |
| 4404 | .variable, | ||
| 4405 | .@"extern", | 4404 | .@"extern", |
| 4406 | .func, | 4405 | .func, |
| 4407 | .enum_literal, | 4406 | .enum_literal, |
src/codegen/wasm/Emit.zig+1-1| ... | @@ -970,7 +970,7 @@ fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: | ... | @@ -970,7 +970,7 @@ fn navRefOff(wasm: *Wasm, code: *ArrayList(u8), data: Mir.NavRefOff, is_wasm32: |
| 970 | const ip = &zcu.intern_pool; | 970 | const ip = &zcu.intern_pool; |
| 971 | const gpa = comp.gpa; | 971 | const gpa = comp.gpa; |
| 972 | const is_obj = comp.config.output_mode == .Obj; | 972 | const is_obj = comp.config.output_mode == .Obj; |
| 973 | const nav_ty = ip.getNav(data.nav_index).typeOf(ip); | 973 | const nav_ty = ip.getNav(data.nav_index).resolved.?.type; |
| 974 | assert(!ip.isFunctionType(nav_ty)); | 974 | assert(!ip.isFunctionType(nav_ty)); |
| 975 | 975 | ||
| 976 | try code.ensureUnusedCapacity(gpa, 11); | 976 | try code.ensureUnusedCapacity(gpa, 11); |
src/codegen/x86_64/CodeGen.zig+2-2| ... | @@ -173046,7 +173046,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -173046,7 +173046,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 173046 | .runtime_nav_ptr => { | 173046 | .runtime_nav_ptr => { |
| 173047 | const ty_nav = air_datas[@intFromEnum(inst)].ty_nav; | 173047 | const ty_nav = air_datas[@intFromEnum(inst)].ty_nav; |
| 173048 | const nav = ip.getNav(ty_nav.nav); | 173048 | const nav = ip.getNav(ty_nav.nav); |
| 173049 | const is_threadlocal = zcu.comp.config.any_non_single_threaded and nav.isThreadlocal(ip); | 173049 | const is_threadlocal = zcu.comp.config.any_non_single_threaded and nav.resolved.?.@"threadlocal"; |
| 173050 | 173050 | ||
| 173051 | if (is_threadlocal) switch (cg.target.ofmt) { | 173051 | if (is_threadlocal) switch (cg.target.ofmt) { |
| 173052 | .elf => if (cg.mod.pic) { | 173052 | .elf => if (cg.mod.pic) { |
| ... | @@ -179146,7 +179146,7 @@ fn genSetMem( | ... | @@ -179146,7 +179146,7 @@ fn genSetMem( |
| 179146 | .off = disp, | 179146 | .off = disp, |
| 179147 | }).compare(.gte, src_align), | 179147 | }).compare(.gte, src_align), |
| 179148 | .table, .rip_inst, .lazy_sym, .extern_func => unreachable, | 179148 | .table, .rip_inst, .lazy_sym, .extern_func => unreachable, |
| 179149 | .nav => |nav| ip.getNav(nav).getAlignment().compare(.gte, src_align), | 179149 | .nav => |nav| ip.getNav(nav).resolved.?.@"align".compare(.gte, src_align), |
| 179150 | .uav => |uav| Type.fromInterned(uav.orig_ty).ptrAlignment(zcu).compare(.gte, src_align), | 179150 | .uav => |uav| Type.fromInterned(uav.orig_ty).ptrAlignment(zcu).compare(.gte, src_align), |
| 179151 | })).write(self, .{ | 179151 | })).write(self, .{ |
| 179152 | .base = base, | 179152 | .base = base, |
src/codegen/x86_64/Emit.zig+16-23| ... | @@ -115,33 +115,26 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -115,33 +115,26 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 115 | return error.EmitFail; | 115 | return error.EmitFail; |
| 116 | }, | 116 | }, |
| 117 | }; | 117 | }; |
| 118 | break :target switch (ip.getNav(nav).status) { | 118 | const resolved_nav = ip.getNav(nav).resolved.?; |
| 119 | .unresolved => unreachable, | 119 | if (resolved_nav.value != .none) switch (ip.indexToKey(resolved_nav.value)) { |
| 120 | .type_resolved => |type_resolved| .{ | 120 | .@"extern" => |@"extern"| break :target .{ |
| 121 | .index = sym_index, | 121 | .index = sym_index, |
| 122 | .is_extern = false, | 122 | .is_extern = switch (@"extern".visibility) { |
| 123 | .type = if (type_resolved.is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol, | 123 | .default => true, |
| 124 | }, | 124 | .hidden, .protected => false, |
| 125 | .fully_resolved => |fully_resolved| switch (ip.indexToKey(fully_resolved.val)) { | ||
| 126 | .@"extern" => |@"extern"| .{ | ||
| 127 | .index = sym_index, | ||
| 128 | .is_extern = switch (@"extern".visibility) { | ||
| 129 | .default => true, | ||
| 130 | .hidden, .protected => false, | ||
| 131 | }, | ||
| 132 | .type = if (@"extern".is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol, | ||
| 133 | .force_pcrel_direct = switch (@"extern".relocation) { | ||
| 134 | .any => false, | ||
| 135 | .pcrel => true, | ||
| 136 | }, | ||
| 137 | }, | 125 | }, |
| 138 | .variable => |variable| .{ | 126 | .type = if (resolved_nav.@"threadlocal" and comp.config.any_non_single_threaded) .tlv else .symbol, |
| 139 | .index = sym_index, | 127 | .force_pcrel_direct = switch (@"extern".relocation) { |
| 140 | .is_extern = false, | 128 | .any => false, |
| 141 | .type = if (variable.is_threadlocal and comp.config.any_non_single_threaded) .tlv else .symbol, | 129 | .pcrel => true, |
| 142 | }, | 130 | }, |
| 143 | else => .{ .index = sym_index, .is_extern = false, .type = .symbol }, | ||
| 144 | }, | 131 | }, |
| 132 | else => {}, | ||
| 133 | }; | ||
| 134 | break :target .{ | ||
| 135 | .index = sym_index, | ||
| 136 | .is_extern = false, | ||
| 137 | .type = if (resolved_nav.@"threadlocal" and comp.config.any_non_single_threaded) .tlv else .symbol, | ||
| 145 | }; | 138 | }; |
| 146 | }, | 139 | }, |
| 147 | .uav => |uav| .{ | 140 | .uav => |uav| .{ |
src/link.zig+1-1| ... | @@ -781,7 +781,7 @@ pub const File = struct { | ... | @@ -781,7 +781,7 @@ pub const File = struct { |
| 781 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void { | 781 | fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void { |
| 782 | assert(base.comp.zcu.?.llvm_object == null); | 782 | assert(base.comp.zcu.?.llvm_object == null); |
| 783 | const nav = pt.zcu.intern_pool.getNav(nav_index); | 783 | const nav = pt.zcu.intern_pool.getNav(nav_index); |
| 784 | assert(nav.status == .fully_resolved); | 784 | assert(nav.resolved.?.value != .none); |
| 785 | switch (base.tag) { | 785 | switch (base.tag) { |
| 786 | .lld => unreachable, | 786 | .lld => unreachable, |
| 787 | .plan9 => unreachable, | 787 | .plan9 => unreachable, |
src/link/C.zig+7-6| ... | @@ -534,11 +534,11 @@ pub fn updateNav( | ... | @@ -534,11 +534,11 @@ pub fn updateNav( |
| 534 | const ip = &zcu.intern_pool; | 534 | const ip = &zcu.intern_pool; |
| 535 | 535 | ||
| 536 | const nav = ip.getNav(nav_index); | 536 | const nav = ip.getNav(nav_index); |
| 537 | switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 537 | switch (ip.indexToKey(nav.resolved.?.value)) { |
| 538 | .func => return, | 538 | .func => return, |
| 539 | .@"extern" => {}, | 539 | .@"extern" => {}, |
| 540 | else => { | 540 | else => { |
| 541 | const nav_ty: Type = .fromInterned(nav.typeOf(ip)); | 541 | const nav_ty: Type = .fromInterned(nav.resolved.?.type); |
| 542 | if (!nav_ty.hasRuntimeBits(zcu)) { | 542 | if (!nav_ty.hasRuntimeBits(zcu)) { |
| 543 | if (c.navs.fetchSwapRemove(nav_index)) |kv| { | 543 | if (c.navs.fetchSwapRemove(nav_index)) |kv| { |
| 544 | var old_rendered = kv.value; | 544 | var old_rendered = kv.value; |
| ... | @@ -762,7 +762,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -762,7 +762,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 762 | { | 762 | { |
| 763 | const unit_references = try zcu.resolveReferences(); | 763 | const unit_references = try zcu.resolveReferences(); |
| 764 | for (c.navs.keys()) |nav| { | 764 | for (c.navs.keys()) |nav| { |
| 765 | const nav_val = ip.getNav(nav).status.fully_resolved.val; | 765 | const nav_val = ip.getNav(nav).resolved.?.value; |
| 766 | const check_unit: ?InternPool.AnalUnit = switch (ip.indexToKey(nav_val)) { | 766 | const check_unit: ?InternPool.AnalUnit = switch (ip.indexToKey(nav_val)) { |
| 767 | else => .wrap(.{ .nav_val = nav }), | 767 | else => .wrap(.{ .nav_val = nav }), |
| 768 | .func => .wrap(.{ .func = nav_val }), | 768 | .func => .wrap(.{ .func = nav_val }), |
| ... | @@ -1092,8 +1092,9 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -1092,8 +1092,9 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 1092 | // NAV forward declarations | 1092 | // NAV forward declarations |
| 1093 | for (need_navs.keys()) |nav| { | 1093 | for (need_navs.keys()) |nav| { |
| 1094 | if (c.exported_navs.contains(nav)) continue; // the export was the declaration | 1094 | if (c.exported_navs.contains(nav)) continue; // the export was the declaration |
| 1095 | if (ip.getNav(nav).getExtern(ip)) |e| { | 1095 | switch (ip.indexToKey(ip.getNav(nav).resolved.?.value)) { |
| 1096 | if (export_names.contains(e.name)) continue; | 1096 | .@"extern" => |e| if (export_names.contains(e.name)) continue, |
| 1097 | else => {}, | ||
| 1097 | } | 1098 | } |
| 1098 | const fwd_decl = c.navs.getPtr(nav).?.fwd_decl; | 1099 | const fwd_decl = c.navs.getPtr(nav).?.fwd_decl; |
| 1099 | f.appendBufAssumeCapacity(fwd_decl.get(c)); | 1100 | f.appendBufAssumeCapacity(fwd_decl.get(c)); |
| ... | @@ -1200,7 +1201,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog | ... | @@ -1200,7 +1201,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 1200 | const code = c.navs.getPtr(nav).?.code; | 1201 | const code = c.navs.getPtr(nav).?.code; |
| 1201 | if (code.len == 0) continue; | 1202 | if (code.len == 0) continue; |
| 1202 | if (!c.exported_navs.contains(nav)) { | 1203 | if (!c.exported_navs.contains(nav)) { |
| 1203 | const is_extern = ip.getNav(nav).getExtern(ip) != null; | 1204 | const is_extern = ip.indexToKey(ip.getNav(nav).resolved.?.value) == .@"extern"; |
| 1204 | f.appendBufAssumeCapacity(if (is_extern) "zig_extern " else "static "); | 1205 | f.appendBufAssumeCapacity(if (is_extern) "zig_extern " else "static "); |
| 1205 | } | 1206 | } |
| 1206 | f.appendBufAssumeCapacity(code.get(c)); | 1207 | f.appendBufAssumeCapacity(code.get(c)); |
src/link/Coff.zig+21-34| ... | @@ -1226,34 +1226,26 @@ pub fn globalSymbol(coff: *Coff, name: []const u8, lib_name: ?[]const u8) !Symbo | ... | @@ -1226,34 +1226,26 @@ pub fn globalSymbol(coff: *Coff, name: []const u8, lib_name: ?[]const u8) !Symbo |
| 1226 | fn navSection( | 1226 | fn navSection( |
| 1227 | coff: *Coff, | 1227 | coff: *Coff, |
| 1228 | zcu: *Zcu, | 1228 | zcu: *Zcu, |
| 1229 | nav_fr: @FieldType(@FieldType(InternPool.Nav, "status"), "fully_resolved"), | 1229 | nav_resolved: @typeInfo(@FieldType(InternPool.Nav, "resolved")).optional.child, |
| 1230 | ) !Symbol.Index { | 1230 | ) !Symbol.Index { |
| 1231 | const ip = &zcu.intern_pool; | 1231 | const ip = &zcu.intern_pool; |
| 1232 | const default: String, const attributes: ObjectSectionAttributes = | 1232 | const default: String, const attributes: ObjectSectionAttributes = |
| 1233 | switch (ip.indexToKey(nav_fr.val)) { | 1233 | if (nav_resolved.@"threadlocal" and coff.base.comp.config.any_non_single_threaded) .{ |
| 1234 | else => .{ .@".rdata", .{ .read = true } }, | 1234 | .@".tls$", .{ .read = true, .write = true }, |
| 1235 | .variable => |variable| if (variable.is_threadlocal and | 1235 | } else if (ip.isFunctionType(nav_resolved.type)) .{ |
| 1236 | coff.base.comp.config.any_non_single_threaded) | 1236 | .@".text", .{ .read = true, .execute = true }, |
| 1237 | .{ .@".tls$", .{ .read = true, .write = true } } | 1237 | } else if (nav_resolved.@"const") .{ |
| 1238 | else | 1238 | .@".rdata", .{ .read = true }, |
| 1239 | .{ .@".data", .{ .read = true, .write = true } }, | 1239 | } else .{ |
| 1240 | .@"extern" => |@"extern"| if (@"extern".is_threadlocal and | 1240 | .@".data", .{ .read = true, .write = true }, |
| 1241 | coff.base.comp.config.any_non_single_threaded) | ||
| 1242 | .{ .@".tls$", .{ .read = true, .write = true } } | ||
| 1243 | else if (ip.isFunctionType(@"extern".ty)) | ||
| 1244 | .{ .@".text", .{ .read = true, .execute = true } } | ||
| 1245 | else if (@"extern".is_const) | ||
| 1246 | .{ .@".rdata", .{ .read = true } } | ||
| 1247 | else | ||
| 1248 | .{ .@".data", .{ .read = true, .write = true } }, | ||
| 1249 | .func => .{ .@".text", .{ .read = true, .execute = true } }, | ||
| 1250 | }; | 1241 | }; |
| 1242 | |||
| 1251 | return (try coff.objectSectionMapIndex( | 1243 | return (try coff.objectSectionMapIndex( |
| 1252 | (try coff.getOrPutOptionalString(nav_fr.@"linksection".toSlice(ip))).unwrap() orelse default, | 1244 | (try coff.getOrPutOptionalString(nav_resolved.@"linksection".toSlice(ip))).unwrap() orelse default, |
| 1253 | switch (nav_fr.@"linksection") { | 1245 | switch (nav_resolved.@"linksection") { |
| 1254 | .none => coff.mf.flags.block_size, | 1246 | .none => coff.mf.flags.block_size, |
| 1255 | else => switch (nav_fr.alignment) { | 1247 | else => switch (nav_resolved.@"align") { |
| 1256 | .none => Type.fromInterned(ip.typeOf(nav_fr.val)).abiAlignment(zcu), | 1248 | .none => Type.fromInterned(ip.typeOf(nav_resolved.value)).abiAlignment(zcu), |
| 1257 | else => |alignment| alignment, | 1249 | else => |alignment| alignment, |
| 1258 | }.toStdMem(), | 1250 | }.toStdMem(), |
| 1259 | }, | 1251 | }, |
| ... | @@ -1536,20 +1528,15 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -1536,20 +1528,15 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 1536 | const ip = &zcu.intern_pool; | 1528 | const ip = &zcu.intern_pool; |
| 1537 | 1529 | ||
| 1538 | const nav = ip.getNav(nav_index); | 1530 | const nav = ip.getNav(nav_index); |
| 1539 | const nav_val = nav.status.fully_resolved.val; | 1531 | if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return; |
| 1540 | const nav_init = switch (ip.indexToKey(nav_val)) { | 1532 | if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) return; |
| 1541 | else => nav_val, | ||
| 1542 | .variable => |variable| variable.init, | ||
| 1543 | .@"extern", .func => .none, | ||
| 1544 | }; | ||
| 1545 | if (nav_init == .none or !Type.fromInterned(ip.typeOf(nav_init)).hasRuntimeBits(zcu)) return; | ||
| 1546 | 1533 | ||
| 1547 | const nmi = try coff.navMapIndex(zcu, nav_index); | 1534 | const nmi = try coff.navMapIndex(zcu, nav_index); |
| 1548 | const si = nmi.symbol(coff); | 1535 | const si = nmi.symbol(coff); |
| 1549 | const ni = ni: { | 1536 | const ni = ni: { |
| 1550 | switch (si.get(coff).ni) { | 1537 | switch (si.get(coff).ni) { |
| 1551 | .none => { | 1538 | .none => { |
| 1552 | const sec_si = try coff.navSection(zcu, nav.status.fully_resolved); | 1539 | const sec_si = try coff.navSection(zcu, nav.resolved.?); |
| 1553 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 1540 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 1554 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ | 1541 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ |
| 1555 | .alignment = zcu.navAlignment(nav_index).toStdMem(), | 1542 | .alignment = zcu.navAlignment(nav_index).toStdMem(), |
| ... | @@ -1576,7 +1563,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -1576,7 +1563,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 1576 | &coff.base, | 1563 | &coff.base, |
| 1577 | pt, | 1564 | pt, |
| 1578 | zcu.navSrcLoc(nav_index), | 1565 | zcu.navSrcLoc(nav_index), |
| 1579 | .fromInterned(nav_init), | 1566 | .fromInterned(nav.resolved.?.value), |
| 1580 | &nw.interface, | 1567 | &nw.interface, |
| 1581 | .{ .atom_index = @intFromEnum(si) }, | 1568 | .{ .atom_index = @intFromEnum(si) }, |
| 1582 | ) catch |err| switch (err) { | 1569 | ) catch |err| switch (err) { |
| ... | @@ -1587,7 +1574,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -1587,7 +1574,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 1587 | si.applyLocationRelocs(coff); | 1574 | si.applyLocationRelocs(coff); |
| 1588 | } | 1575 | } |
| 1589 | 1576 | ||
| 1590 | if (nav.status.fully_resolved.@"linksection".unwrap()) |_| { | 1577 | if (nav.resolved.?.@"linksection".unwrap()) |_| { |
| 1591 | try ni.resize(&coff.mf, gpa, si.get(coff).size); | 1578 | try ni.resize(&coff.mf, gpa, si.get(coff).size); |
| 1592 | var parent_ni = ni; | 1579 | var parent_ni = ni; |
| 1593 | while (true) { | 1580 | while (true) { |
| ... | @@ -1674,12 +1661,12 @@ fn updateFuncInner( | ... | @@ -1674,12 +1661,12 @@ fn updateFuncInner( |
| 1674 | const ni = ni: { | 1661 | const ni = ni: { |
| 1675 | switch (si.get(coff).ni) { | 1662 | switch (si.get(coff).ni) { |
| 1676 | .none => { | 1663 | .none => { |
| 1677 | const sec_si = try coff.navSection(zcu, nav.status.fully_resolved); | 1664 | const sec_si = try coff.navSection(zcu, nav.resolved.?); |
| 1678 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 1665 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 1679 | const mod = zcu.navFileScope(func.owner_nav).mod.?; | 1666 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 1680 | const target = &mod.resolved_target.result; | 1667 | const target = &mod.resolved_target.result; |
| 1681 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ | 1668 | const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ |
| 1682 | .alignment = switch (nav.status.fully_resolved.alignment) { | 1669 | .alignment = switch (nav.resolved.?.@"align") { |
| 1683 | .none => switch (mod.optimize_mode) { | 1670 | .none => switch (mod.optimize_mode) { |
| 1684 | .Debug, | 1671 | .Debug, |
| 1685 | .ReleaseSafe, | 1672 | .ReleaseSafe, |
src/link/Dwarf.zig+8-11| ... | @@ -2681,7 +2681,7 @@ fn initWipNavInner( | ... | @@ -2681,7 +2681,7 @@ fn initWipNavInner( |
| 2681 | } else try wip_nav.infoExprLoc(.{ .addr_reloc = sym_index }); | 2681 | } else try wip_nav.infoExprLoc(.{ .addr_reloc = sym_index }); |
| 2682 | }, | 2682 | }, |
| 2683 | .syntax => switch (ip.isFunctionType(@"extern".ty)) { | 2683 | .syntax => switch (ip.isFunctionType(@"extern".ty)) { |
| 2684 | false => continue :nav_val .{ .variable = undefined }, | 2684 | false => continue :nav_val .{ .undef = @"extern".ty }, |
| 2685 | true => { | 2685 | true => { |
| 2686 | const func_type = ip.indexToKey(@"extern".ty).func_type; | 2686 | const func_type = ip.indexToKey(@"extern".ty).func_type; |
| 2687 | const diw = &wip_nav.debug_info.writer; | 2687 | const diw = &wip_nav.debug_info.writer; |
| ... | @@ -2777,7 +2777,7 @@ fn initWipNavInner( | ... | @@ -2777,7 +2777,7 @@ fn initWipNavInner( |
| 2777 | wip_nav.func_high_pc = @intCast(diw.end); | 2777 | wip_nav.func_high_pc = @intCast(diw.end); |
| 2778 | try diw.writeInt(u32, 0, dwarf.endian); | 2778 | try diw.writeInt(u32, 0, dwarf.endian); |
| 2779 | const target = &mod.resolved_target.result; | 2779 | const target = &mod.resolved_target.result; |
| 2780 | try diw.writeUleb128(switch (nav.status.fully_resolved.alignment) { | 2780 | try diw.writeUleb128(switch (nav.resolved.?.@"align") { |
| 2781 | .none => target_info.defaultFunctionAlignment(target), | 2781 | .none => target_info.defaultFunctionAlignment(target), |
| 2782 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), | 2782 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), |
| 2783 | }.toByteUnits().?); | 2783 | }.toByteUnits().?); |
| ... | @@ -2845,7 +2845,7 @@ fn initWipNavInner( | ... | @@ -2845,7 +2845,7 @@ fn initWipNavInner( |
| 2845 | .@"const" => { | 2845 | .@"const" => { |
| 2846 | const const_ty_reloc_index = try wip_nav.refForward(); | 2846 | const const_ty_reloc_index = try wip_nav.refForward(); |
| 2847 | try wip_nav.infoExprLoc(loc); | 2847 | try wip_nav.infoExprLoc(loc); |
| 2848 | try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse | 2848 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 2849 | ty.abiAlignment(zcu).toByteUnits().?); | 2849 | ty.abiAlignment(zcu).toByteUnits().?); |
| 2850 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | 2850 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); |
| 2851 | wip_nav.finishForward(const_ty_reloc_index); | 2851 | wip_nav.finishForward(const_ty_reloc_index); |
| ... | @@ -2855,7 +2855,7 @@ fn initWipNavInner( | ... | @@ -2855,7 +2855,7 @@ fn initWipNavInner( |
| 2855 | .@"var" => { | 2855 | .@"var" => { |
| 2856 | try wip_nav.refType(ty); | 2856 | try wip_nav.refType(ty); |
| 2857 | try wip_nav.infoExprLoc(loc); | 2857 | try wip_nav.infoExprLoc(loc); |
| 2858 | try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse | 2858 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 2859 | ty.abiAlignment(zcu).toByteUnits().?); | 2859 | ty.abiAlignment(zcu).toByteUnits().?); |
| 2860 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | 2860 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); |
| 2861 | }, | 2861 | }, |
| ... | @@ -3028,10 +3028,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3028,10 +3028,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3028 | const zcu = pt.zcu; | 3028 | const zcu = pt.zcu; |
| 3029 | const ip = &zcu.intern_pool; | 3029 | const ip = &zcu.intern_pool; |
| 3030 | const nav_src_loc = zcu.navSrcLoc(nav_index); | 3030 | const nav_src_loc = zcu.navSrcLoc(nav_index); |
| 3031 | const nav_val = zcu.navValue(nav_index); | ||
| 3032 | 3031 | ||
| 3033 | const nav = ip.getNav(nav_index); | 3032 | const nav = ip.getNav(nav_index); |
| 3034 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; | 3033 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; |
| 3034 | const nav_val: Value = .fromInterned(nav.resolved.?.value); | ||
| 3035 | const file = zcu.fileByIndex(inst_info.file); | 3035 | const file = zcu.fileByIndex(inst_info.file); |
| 3036 | const decl = file.zir.?.getDeclaration(inst_info.inst); | 3036 | const decl = file.zir.?.getDeclaration(inst_info.inst); |
| 3037 | log.debug("updateComptimeNav({s}:{d}:{d} %{d} = {f})", .{ | 3037 | log.debug("updateComptimeNav({s}:{d}:{d} %{d} = {f})", .{ |
| ... | @@ -3127,9 +3127,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3127,9 +3127,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3127 | .aggregate, | 3127 | .aggregate, |
| 3128 | .un, | 3128 | .un, |
| 3129 | .bitpack, | 3129 | .bitpack, |
| 3130 | => .@"const", | 3130 | => if (nav.resolved.?.@"const") .@"const" else .@"var", |
| 3131 | |||
| 3132 | .variable => .@"var", | ||
| 3133 | 3131 | ||
| 3134 | .@"extern" => unreachable, | 3132 | .@"extern" => unreachable, |
| 3135 | 3133 | ||
| ... | @@ -3210,7 +3208,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3210,7 +3208,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3210 | const nav_ty = nav_val.typeOf(zcu); | 3208 | const nav_ty = nav_val.typeOf(zcu); |
| 3211 | try wip_nav.refType(nav_ty); | 3209 | try wip_nav.refType(nav_ty); |
| 3212 | try wip_nav.blockValue(nav_src_loc, nav_val); | 3210 | try wip_nav.blockValue(nav_src_loc, nav_val); |
| 3213 | try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse | 3211 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 3214 | nav_ty.abiAlignment(zcu).toByteUnits().?); | 3212 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3215 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | 3213 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); |
| 3216 | }, | 3214 | }, |
| ... | @@ -3240,7 +3238,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3240,7 +3238,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3240 | .@"extern", .@"export" => nav.name, | 3238 | .@"extern", .@"export" => nav.name, |
| 3241 | }.toSlice(ip)); | 3239 | }.toSlice(ip)); |
| 3242 | const nav_ty_reloc_index = try wip_nav.refForward(); | 3240 | const nav_ty_reloc_index = try wip_nav.refForward(); |
| 3243 | try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse | 3241 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 3244 | nav_ty.abiAlignment(zcu).toByteUnits().?); | 3242 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3245 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | 3243 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); |
| 3246 | if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val); | 3244 | if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val); |
| ... | @@ -4281,7 +4279,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -4281,7 +4279,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4281 | try wip_nav.refType(.null); | 4279 | try wip_nav.refType(.null); |
| 4282 | }, | 4280 | }, |
| 4283 | }, | 4281 | }, |
| 4284 | .variable => unreachable, // not a value | ||
| 4285 | .int => |int| { | 4282 | .int => |int| { |
| 4286 | try wip_nav.bigIntConstValue(.{ | 4283 | try wip_nav.bigIntConstValue(.{ |
| 4287 | .sdata = .sdata_comptime_value, | 4284 | .sdata = .sdata_comptime_value, |
src/link/Elf/ZigObject.zig+16-20| ... | @@ -1113,7 +1113,7 @@ pub fn getOrCreateMetadataForNav(self: *ZigObject, zcu: *Zcu, nav_index: InternP | ... | @@ -1113,7 +1113,7 @@ pub fn getOrCreateMetadataForNav(self: *ZigObject, zcu: *Zcu, nav_index: InternP |
| 1113 | if (!gop.found_existing) { | 1113 | if (!gop.found_existing) { |
| 1114 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); | 1114 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); |
| 1115 | const sym = self.symbol(symbol_index); | 1115 | const sym = self.symbol(symbol_index); |
| 1116 | if (ip.getNav(nav_index).isThreadlocal(ip) and zcu.comp.config.any_non_single_threaded) { | 1116 | if (ip.getNav(nav_index).resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded) { |
| 1117 | sym.flags.is_tls = true; | 1117 | sym.flags.is_tls = true; |
| 1118 | } | 1118 | } |
| 1119 | gop.value_ptr.* = .{ .symbol_index = symbol_index }; | 1119 | gop.value_ptr.* = .{ .symbol_index = symbol_index }; |
| ... | @@ -1143,9 +1143,10 @@ fn getNavShdrIndex( | ... | @@ -1143,9 +1143,10 @@ fn getNavShdrIndex( |
| 1143 | const gpa = elf_file.base.comp.gpa; | 1143 | const gpa = elf_file.base.comp.gpa; |
| 1144 | const ptr_size = elf_file.ptrWidthBytes(); | 1144 | const ptr_size = elf_file.ptrWidthBytes(); |
| 1145 | const ip = &zcu.intern_pool; | 1145 | const ip = &zcu.intern_pool; |
| 1146 | const nav_val = zcu.navValue(nav_index); | 1146 | const nav = ip.getNav(nav_index); |
| 1147 | const nav_val: Value = .fromInterned(nav.resolved.?.value); | ||
| 1147 | const is_func = ip.isFunctionType(nav_val.typeOf(zcu).toIntern()); | 1148 | const is_func = ip.isFunctionType(nav_val.typeOf(zcu).toIntern()); |
| 1148 | if (ip.getNav(nav_index).getLinkSection().unwrap()) |@"linksection"| { | 1149 | if (ip.getNav(nav_index).resolved.?.@"linksection".unwrap()) |@"linksection"| { |
| 1149 | const section_name = @"linksection".toSlice(ip); | 1150 | const section_name = @"linksection".toSlice(ip); |
| 1150 | if (elf_file.sectionByName(section_name)) |osec| { | 1151 | if (elf_file.sectionByName(section_name)) |osec| { |
| 1151 | if (is_func) { | 1152 | if (is_func) { |
| ... | @@ -1258,13 +1259,8 @@ fn getNavShdrIndex( | ... | @@ -1258,13 +1259,8 @@ fn getNavShdrIndex( |
| 1258 | self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec); | 1259 | self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec); |
| 1259 | return osec; | 1260 | return osec; |
| 1260 | } | 1261 | } |
| 1261 | const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | ||
| 1262 | .variable => |variable| .{ false, variable.is_threadlocal, variable.init }, | ||
| 1263 | .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none }, | ||
| 1264 | else => .{ true, false, nav_val.toIntern() }, | ||
| 1265 | }; | ||
| 1266 | const has_relocs = self.symbol(sym_index).atom(elf_file).?.relocs(elf_file).len > 0; | 1262 | const has_relocs = self.symbol(sym_index).atom(elf_file).?.relocs(elf_file).len > 0; |
| 1267 | if (is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) { | 1263 | if (nav.resolved.?.@"threadlocal" and elf_file.base.comp.config.any_non_single_threaded) { |
| 1268 | const is_bss = !has_relocs and for (code) |byte| { | 1264 | const is_bss = !has_relocs and for (code) |byte| { |
| 1269 | if (byte != 0) break false; | 1265 | if (byte != 0) break false; |
| 1270 | } else true; | 1266 | } else true; |
| ... | @@ -1291,7 +1287,7 @@ fn getNavShdrIndex( | ... | @@ -1291,7 +1287,7 @@ fn getNavShdrIndex( |
| 1291 | self.tdata_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".tdata"), osec); | 1287 | self.tdata_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".tdata"), osec); |
| 1292 | return osec; | 1288 | return osec; |
| 1293 | } | 1289 | } |
| 1294 | if (is_const) { | 1290 | if (nav.resolved.?.@"const") { |
| 1295 | if (self.data_relro_index) |symbol_index| | 1291 | if (self.data_relro_index) |symbol_index| |
| 1296 | return self.symbol(symbol_index).outputShndx(elf_file).?; | 1292 | return self.symbol(symbol_index).outputShndx(elf_file).?; |
| 1297 | const osec = try elf_file.addSection(.{ | 1293 | const osec = try elf_file.addSection(.{ |
| ... | @@ -1303,7 +1299,7 @@ fn getNavShdrIndex( | ... | @@ -1303,7 +1299,7 @@ fn getNavShdrIndex( |
| 1303 | self.data_relro_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data.rel.ro"), osec); | 1299 | self.data_relro_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".data.rel.ro"), osec); |
| 1304 | return osec; | 1300 | return osec; |
| 1305 | } | 1301 | } |
| 1306 | if (nav_init != .none and Value.fromInterned(nav_init).isUndef(zcu)) | 1302 | if (nav_val.isUndef(zcu)) |
| 1307 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { | 1303 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1308 | .Debug, .ReleaseSafe => { | 1304 | .Debug, .ReleaseSafe => { |
| 1309 | if (self.data_index) |symbol_index| | 1305 | if (self.data_index) |symbol_index| |
| ... | @@ -1378,7 +1374,7 @@ fn updateNavCode( | ... | @@ -1378,7 +1374,7 @@ fn updateNavCode( |
| 1378 | 1374 | ||
| 1379 | const mod = zcu.navFileScope(nav_index).mod.?; | 1375 | const mod = zcu.navFileScope(nav_index).mod.?; |
| 1380 | const target = &mod.resolved_target.result; | 1376 | const target = &mod.resolved_target.result; |
| 1381 | const required_alignment = switch (nav.status.fully_resolved.alignment) { | 1377 | const required_alignment = switch (nav.resolved.?.@"align") { |
| 1382 | .none => switch (mod.optimize_mode) { | 1378 | .none => switch (mod.optimize_mode) { |
| 1383 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), | 1379 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), |
| 1384 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 1380 | .ReleaseSmall => target_util.minFunctionAlignment(target), |
| ... | @@ -1647,16 +1643,17 @@ pub fn updateNav( | ... | @@ -1647,16 +1643,17 @@ pub fn updateNav( |
| 1647 | 1643 | ||
| 1648 | log.debug("updateNav {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); | 1644 | log.debug("updateNav {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1649 | 1645 | ||
| 1650 | const nav_init = switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 1646 | switch (ip.indexToKey(nav.resolved.?.value)) { |
| 1651 | .func => .none, | 1647 | else => {}, |
| 1652 | .variable => |variable| variable.init, | ||
| 1653 | .@"extern" => |@"extern"| { | 1648 | .@"extern" => |@"extern"| { |
| 1654 | const sym_index = try self.getGlobalSymbol( | 1649 | const sym_index = try self.getGlobalSymbol( |
| 1655 | elf_file, | 1650 | elf_file, |
| 1656 | nav.name.toSlice(ip), | 1651 | nav.name.toSlice(ip), |
| 1657 | @"extern".lib_name.toSlice(ip), | 1652 | @"extern".lib_name.toSlice(ip), |
| 1658 | ); | 1653 | ); |
| 1659 | if (@"extern".is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) self.symbol(sym_index).flags.is_tls = true; | 1654 | if (nav.resolved.?.@"threadlocal" and elf_file.base.comp.config.any_non_single_threaded) { |
| 1655 | self.symbol(sym_index).flags.is_tls = true; | ||
| 1656 | } | ||
| 1660 | if (self.dwarf) |*dwarf| { | 1657 | if (self.dwarf) |*dwarf| { |
| 1661 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index); | 1658 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index); |
| 1662 | defer debug_wip_nav.deinit(); | 1659 | defer debug_wip_nav.deinit(); |
| ... | @@ -1668,10 +1665,9 @@ pub fn updateNav( | ... | @@ -1668,10 +1665,9 @@ pub fn updateNav( |
| 1668 | } | 1665 | } |
| 1669 | return; | 1666 | return; |
| 1670 | }, | 1667 | }, |
| 1671 | else => nav.status.fully_resolved.val, | 1668 | } |
| 1672 | }; | ||
| 1673 | 1669 | ||
| 1674 | if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) { | 1670 | if (Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) { |
| 1675 | const sym_index = try self.getOrCreateMetadataForNav(zcu, nav_index); | 1671 | const sym_index = try self.getOrCreateMetadataForNav(zcu, nav_index); |
| 1676 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(self); | 1672 | self.symbol(sym_index).atom(elf_file).?.freeRelocs(self); |
| 1677 | 1673 | ||
| ... | @@ -1685,7 +1681,7 @@ pub fn updateNav( | ... | @@ -1685,7 +1681,7 @@ pub fn updateNav( |
| 1685 | &elf_file.base, | 1681 | &elf_file.base, |
| 1686 | pt, | 1682 | pt, |
| 1687 | zcu.navSrcLoc(nav_index), | 1683 | zcu.navSrcLoc(nav_index), |
| 1688 | Value.fromInterned(nav_init), | 1684 | .fromInterned(nav.resolved.?.value), |
| 1689 | &aw.writer, | 1685 | &aw.writer, |
| 1690 | .{ .atom_index = sym_index }, | 1686 | .{ .atom_index = sym_index }, |
| 1691 | ) catch |err| switch (err) { | 1687 | ) catch |err| switch (err) { |
src/link/Elf2.zig+19-41| ... | @@ -1876,32 +1876,15 @@ pub fn globalSymbol(elf: *Elf, opts: struct { | ... | @@ -1876,32 +1876,15 @@ pub fn globalSymbol(elf: *Elf, opts: struct { |
| 1876 | 1876 | ||
| 1877 | fn navType( | 1877 | fn navType( |
| 1878 | ip: *const InternPool, | 1878 | ip: *const InternPool, |
| 1879 | nav_status: @FieldType(InternPool.Nav, "status"), | 1879 | nav_resolved: @typeInfo(@FieldType(InternPool.Nav, "resolved")).optional.child, |
| 1880 | any_non_single_threaded: bool, | 1880 | any_non_single_threaded: bool, |
| 1881 | ) std.elf.STT { | 1881 | ) std.elf.STT { |
| 1882 | return switch (nav_status) { | 1882 | return if (any_non_single_threaded and nav_resolved.@"threadlocal") |
| 1883 | .unresolved => unreachable, | 1883 | .TLS |
| 1884 | .type_resolved => |tr| if (any_non_single_threaded and tr.is_threadlocal) | 1884 | else if (ip.isFunctionType(nav_resolved.type)) |
| 1885 | .TLS | 1885 | .FUNC |
| 1886 | else if (ip.isFunctionType(tr.type)) | 1886 | else |
| 1887 | .FUNC | 1887 | .OBJECT; |
| 1888 | else | ||
| 1889 | .OBJECT, | ||
| 1890 | .fully_resolved => |fr| switch (ip.indexToKey(fr.val)) { | ||
| 1891 | else => .OBJECT, | ||
| 1892 | .variable => |variable| if (any_non_single_threaded and variable.is_threadlocal) | ||
| 1893 | .TLS | ||
| 1894 | else | ||
| 1895 | .OBJECT, | ||
| 1896 | .@"extern" => |@"extern"| if (any_non_single_threaded and @"extern".is_threadlocal) | ||
| 1897 | .TLS | ||
| 1898 | else if (ip.isFunctionType(@"extern".ty)) | ||
| 1899 | .FUNC | ||
| 1900 | else | ||
| 1901 | .OBJECT, | ||
| 1902 | .func => .FUNC, | ||
| 1903 | }, | ||
| 1904 | }; | ||
| 1905 | } | 1888 | } |
| 1906 | fn namedSection(elf: *const Elf, name: []const u8) ?Symbol.Index { | 1889 | fn namedSection(elf: *const Elf, name: []const u8) ?Symbol.Index { |
| 1907 | if (std.mem.eql(u8, name, ".rodata") or | 1890 | if (std.mem.eql(u8, name, ".rodata") or |
| ... | @@ -1917,13 +1900,13 @@ fn namedSection(elf: *const Elf, name: []const u8) ?Symbol.Index { | ... | @@ -1917,13 +1900,13 @@ fn namedSection(elf: *const Elf, name: []const u8) ?Symbol.Index { |
| 1917 | fn navSection( | 1900 | fn navSection( |
| 1918 | elf: *Elf, | 1901 | elf: *Elf, |
| 1919 | ip: *const InternPool, | 1902 | ip: *const InternPool, |
| 1920 | nav_fr: @FieldType(@FieldType(InternPool.Nav, "status"), "fully_resolved"), | 1903 | nav_resolved: @typeInfo(@FieldType(InternPool.Nav, "resolved")).optional.child, |
| 1921 | ) Symbol.Index { | 1904 | ) Symbol.Index { |
| 1922 | if (nav_fr.@"linksection".toSlice(ip)) |@"linksection"| | 1905 | if (nav_resolved.@"linksection".toSlice(ip)) |@"linksection"| |
| 1923 | if (elf.namedSection(@"linksection")) |si| return si; | 1906 | if (elf.namedSection(@"linksection")) |si| return si; |
| 1924 | return switch (navType( | 1907 | return switch (navType( |
| 1925 | ip, | 1908 | ip, |
| 1926 | .{ .fully_resolved = nav_fr }, | 1909 | nav_resolved, |
| 1927 | elf.base.comp.config.any_non_single_threaded, | 1910 | elf.base.comp.config.any_non_single_threaded, |
| 1928 | )) { | 1911 | )) { |
| 1929 | else => unreachable, | 1912 | else => unreachable, |
| ... | @@ -1940,7 +1923,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavM | ... | @@ -1940,7 +1923,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavM |
| 1940 | const nav_gop = try elf.navs.getOrPut(gpa, nav_index); | 1923 | const nav_gop = try elf.navs.getOrPut(gpa, nav_index); |
| 1941 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{ | 1924 | if (!nav_gop.found_existing) nav_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{ |
| 1942 | .name = nav.fqn.toSlice(ip), | 1925 | .name = nav.fqn.toSlice(ip), |
| 1943 | .type = navType(ip, nav.status, elf.base.comp.config.any_non_single_threaded), | 1926 | .type = navType(ip, nav.resolved.?, elf.base.comp.config.any_non_single_threaded), |
| 1944 | }); | 1927 | }); |
| 1945 | return @enumFromInt(nav_gop.index); | 1928 | return @enumFromInt(nav_gop.index); |
| 1946 | } | 1929 | } |
| ... | @@ -1950,7 +1933,7 @@ pub fn navSymbol(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol. | ... | @@ -1950,7 +1933,7 @@ pub fn navSymbol(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol. |
| 1950 | if (nav.getExtern(ip)) |@"extern"| return elf.globalSymbol(.{ | 1933 | if (nav.getExtern(ip)) |@"extern"| return elf.globalSymbol(.{ |
| 1951 | .name = @"extern".name.toSlice(ip), | 1934 | .name = @"extern".name.toSlice(ip), |
| 1952 | .lib_name = @"extern".lib_name.toSlice(ip), | 1935 | .lib_name = @"extern".lib_name.toSlice(ip), |
| 1953 | .type = navType(ip, nav.status, elf.base.comp.config.any_non_single_threaded), | 1936 | .type = navType(ip, nav.resolved.?, elf.base.comp.config.any_non_single_threaded), |
| 1954 | .bind = switch (@"extern".linkage) { | 1937 | .bind = switch (@"extern".linkage) { |
| 1955 | .internal => .LOCAL, | 1938 | .internal => .LOCAL, |
| 1956 | .strong => .GLOBAL, | 1939 | .strong => .GLOBAL, |
| ... | @@ -2889,13 +2872,8 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) | ... | @@ -2889,13 +2872,8 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 2889 | const ip = &zcu.intern_pool; | 2872 | const ip = &zcu.intern_pool; |
| 2890 | 2873 | ||
| 2891 | const nav = ip.getNav(nav_index); | 2874 | const nav = ip.getNav(nav_index); |
| 2892 | const nav_val = nav.status.fully_resolved.val; | 2875 | if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return; |
| 2893 | const nav_init = switch (ip.indexToKey(nav_val)) { | 2876 | if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) return; |
| 2894 | else => nav_val, | ||
| 2895 | .variable => |variable| variable.init, | ||
| 2896 | .@"extern", .func => .none, | ||
| 2897 | }; | ||
| 2898 | if (nav_init == .none or !Type.fromInterned(ip.typeOf(nav_init)).hasRuntimeBits(zcu)) return; | ||
| 2899 | 2877 | ||
| 2900 | const nmi = try elf.navMapIndex(zcu, nav_index); | 2878 | const nmi = try elf.navMapIndex(zcu, nav_index); |
| 2901 | const si = nmi.symbol(elf); | 2879 | const si = nmi.symbol(elf); |
| ... | @@ -2904,7 +2882,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) | ... | @@ -2904,7 +2882,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 2904 | switch (sym.ni) { | 2882 | switch (sym.ni) { |
| 2905 | .none => { | 2883 | .none => { |
| 2906 | try elf.nodes.ensureUnusedCapacity(gpa, 1); | 2884 | try elf.nodes.ensureUnusedCapacity(gpa, 1); |
| 2907 | const sec_si = elf.navSection(ip, nav.status.fully_resolved); | 2885 | const sec_si = elf.navSection(ip, nav.resolved.?); |
| 2908 | const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ | 2886 | const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ |
| 2909 | .alignment = zcu.navAlignment(nav_index).toStdMem(), | 2887 | .alignment = zcu.navAlignment(nav_index).toStdMem(), |
| 2910 | .moved = true, | 2888 | .moved = true, |
| ... | @@ -2930,7 +2908,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) | ... | @@ -2930,7 +2908,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 2930 | &elf.base, | 2908 | &elf.base, |
| 2931 | pt, | 2909 | pt, |
| 2932 | zcu.navSrcLoc(nav_index), | 2910 | zcu.navSrcLoc(nav_index), |
| 2933 | .fromInterned(nav_init), | 2911 | .fromInterned(nav.resolved.?.value), |
| 2934 | &nw.interface, | 2912 | &nw.interface, |
| 2935 | .{ .atom_index = @intFromEnum(si) }, | 2913 | .{ .atom_index = @intFromEnum(si) }, |
| 2936 | ) catch |err| switch (err) { | 2914 | ) catch |err| switch (err) { |
| ... | @@ -3021,11 +2999,11 @@ fn updateFuncInner( | ... | @@ -3021,11 +2999,11 @@ fn updateFuncInner( |
| 3021 | switch (sym.ni) { | 2999 | switch (sym.ni) { |
| 3022 | .none => { | 3000 | .none => { |
| 3023 | try elf.nodes.ensureUnusedCapacity(gpa, 1); | 3001 | try elf.nodes.ensureUnusedCapacity(gpa, 1); |
| 3024 | const sec_si = elf.navSection(ip, nav.status.fully_resolved); | 3002 | const sec_si = elf.navSection(ip, nav.resolved.?); |
| 3025 | const mod = zcu.navFileScope(func.owner_nav).mod.?; | 3003 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 3026 | const target = &mod.resolved_target.result; | 3004 | const target = &mod.resolved_target.result; |
| 3027 | const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ | 3005 | const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ |
| 3028 | .alignment = switch (nav.status.fully_resolved.alignment) { | 3006 | .alignment = switch (nav.resolved.?.@"align") { |
| 3029 | .none => switch (mod.optimize_mode) { | 3007 | .none => switch (mod.optimize_mode) { |
| 3030 | .Debug, | 3008 | .Debug, |
| 3031 | .ReleaseSafe, | 3009 | .ReleaseSafe, |
| ... | @@ -3677,7 +3655,7 @@ fn updateExportsInner( | ... | @@ -3677,7 +3655,7 @@ fn updateExportsInner( |
| 3677 | const exported_si: Symbol.Index, const @"type": std.elf.STT = switch (exported) { | 3655 | const exported_si: Symbol.Index, const @"type": std.elf.STT = switch (exported) { |
| 3678 | .nav => |nav| .{ | 3656 | .nav => |nav| .{ |
| 3679 | try elf.navSymbol(zcu, nav), | 3657 | try elf.navSymbol(zcu, nav), |
| 3680 | navType(ip, ip.getNav(nav).status, elf.base.comp.config.any_non_single_threaded), | 3658 | navType(ip, ip.getNav(nav).resolved.?, elf.base.comp.config.any_non_single_threaded), |
| 3681 | }, | 3659 | }, |
| 3682 | .uav => |uav| .{ @enumFromInt(switch (try elf.lowerUav( | 3660 | .uav => |uav| .{ @enumFromInt(switch (try elf.lowerUav( |
| 3683 | pt, | 3661 | pt, |
src/link/MachO/ZigObject.zig+13-19| ... | @@ -877,15 +877,14 @@ pub fn updateNav( | ... | @@ -877,15 +877,14 @@ pub fn updateNav( |
| 877 | const ip = &zcu.intern_pool; | 877 | const ip = &zcu.intern_pool; |
| 878 | const nav = ip.getNav(nav_index); | 878 | const nav = ip.getNav(nav_index); |
| 879 | 879 | ||
| 880 | const nav_init = switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 880 | switch (ip.indexToKey(nav.resolved.?.value)) { |
| 881 | .func => .none, | 881 | else => {}, |
| 882 | .variable => |variable| variable.init, | ||
| 883 | .@"extern" => |@"extern"| { | 882 | .@"extern" => |@"extern"| { |
| 884 | // Extern variable gets a __got entry only | 883 | // Extern variable gets a __got entry only |
| 885 | const name = @"extern".name.toSlice(ip); | 884 | const name = @"extern".name.toSlice(ip); |
| 886 | const lib_name = @"extern".lib_name.toSlice(ip); | 885 | const lib_name = @"extern".lib_name.toSlice(ip); |
| 887 | const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name); | 886 | const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name); |
| 888 | if (@"extern".is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true; | 887 | if (nav.resolved.?.@"threadlocal" and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true; |
| 889 | if (self.dwarf) |*dwarf| { | 888 | if (self.dwarf) |*dwarf| { |
| 890 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index); | 889 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index); |
| 891 | defer debug_wip_nav.deinit(); | 890 | defer debug_wip_nav.deinit(); |
| ... | @@ -897,10 +896,9 @@ pub fn updateNav( | ... | @@ -897,10 +896,9 @@ pub fn updateNav( |
| 897 | } | 896 | } |
| 898 | return; | 897 | return; |
| 899 | }, | 898 | }, |
| 900 | else => nav.status.fully_resolved.val, | 899 | } |
| 901 | }; | ||
| 902 | 900 | ||
| 903 | if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) { | 901 | if (Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) { |
| 904 | const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index); | 902 | const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index); |
| 905 | self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file); | 903 | self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file); |
| 906 | 904 | ||
| ... | @@ -914,7 +912,7 @@ pub fn updateNav( | ... | @@ -914,7 +912,7 @@ pub fn updateNav( |
| 914 | &macho_file.base, | 912 | &macho_file.base, |
| 915 | pt, | 913 | pt, |
| 916 | zcu.navSrcLoc(nav_index), | 914 | zcu.navSrcLoc(nav_index), |
| 917 | Value.fromInterned(nav_init), | 915 | .fromInterned(nav.resolved.?.value), |
| 918 | &aw.writer, | 916 | &aw.writer, |
| 919 | .{ .atom_index = sym_index }, | 917 | .{ .atom_index = sym_index }, |
| 920 | ) catch |err| switch (err) { | 918 | ) catch |err| switch (err) { |
| ... | @@ -959,7 +957,7 @@ fn updateNavCode( | ... | @@ -959,7 +957,7 @@ fn updateNavCode( |
| 959 | 957 | ||
| 960 | const mod = zcu.navFileScope(nav_index).mod.?; | 958 | const mod = zcu.navFileScope(nav_index).mod.?; |
| 961 | const target = &mod.resolved_target.result; | 959 | const target = &mod.resolved_target.result; |
| 962 | const required_alignment = switch (nav.status.fully_resolved.alignment) { | 960 | const required_alignment = switch (nav.resolved.?.@"align") { |
| 963 | .none => switch (mod.optimize_mode) { | 961 | .none => switch (mod.optimize_mode) { |
| 964 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), | 962 | .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target), |
| 965 | .ReleaseSmall => target_util.minFunctionAlignment(target), | 963 | .ReleaseSmall => target_util.minFunctionAlignment(target), |
| ... | @@ -1167,14 +1165,10 @@ fn getNavOutputSection( | ... | @@ -1167,14 +1165,10 @@ fn getNavOutputSection( |
| 1167 | ) error{OutOfMemory}!u8 { | 1165 | ) error{OutOfMemory}!u8 { |
| 1168 | _ = self; | 1166 | _ = self; |
| 1169 | const ip = &zcu.intern_pool; | 1167 | const ip = &zcu.intern_pool; |
| 1170 | const nav_val = zcu.navValue(nav_index); | 1168 | const nav = ip.getNav(nav_index); |
| 1169 | const nav_val: Value = .fromInterned(nav.resolved.?.value); | ||
| 1171 | if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?; | 1170 | if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?; |
| 1172 | const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | 1171 | if (nav.resolved.?.@"threadlocal" and macho_file.base.comp.config.any_non_single_threaded) { |
| 1173 | .variable => |variable| .{ false, variable.is_threadlocal, variable.init }, | ||
| 1174 | .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none }, | ||
| 1175 | else => .{ true, false, nav_val.toIntern() }, | ||
| 1176 | }; | ||
| 1177 | if (is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) { | ||
| 1178 | for (code) |byte| { | 1172 | for (code) |byte| { |
| 1179 | if (byte != 0) break; | 1173 | if (byte != 0) break; |
| 1180 | } else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection( | 1174 | } else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection( |
| ... | @@ -1188,8 +1182,8 @@ fn getNavOutputSection( | ... | @@ -1188,8 +1182,8 @@ fn getNavOutputSection( |
| 1188 | .{ .flags = macho.S_THREAD_LOCAL_REGULAR }, | 1182 | .{ .flags = macho.S_THREAD_LOCAL_REGULAR }, |
| 1189 | ); | 1183 | ); |
| 1190 | } | 1184 | } |
| 1191 | if (is_const) return macho_file.zig_const_sect_index.?; | 1185 | if (nav.resolved.?.@"const") return macho_file.zig_const_sect_index.?; |
| 1192 | if (nav_init != .none and Value.fromInterned(nav_init).isUndef(zcu)) | 1186 | if (nav_val.isUndef(zcu)) |
| 1193 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { | 1187 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1194 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, | 1188 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, |
| 1195 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, | 1189 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, |
| ... | @@ -1550,7 +1544,7 @@ fn isThreadlocal(macho_file: *MachO, nav_index: InternPool.Nav.Index) bool { | ... | @@ -1550,7 +1544,7 @@ fn isThreadlocal(macho_file: *MachO, nav_index: InternPool.Nav.Index) bool { |
| 1550 | if (!macho_file.base.comp.config.any_non_single_threaded) | 1544 | if (!macho_file.base.comp.config.any_non_single_threaded) |
| 1551 | return false; | 1545 | return false; |
| 1552 | const ip = &macho_file.base.comp.zcu.?.intern_pool; | 1546 | const ip = &macho_file.base.comp.zcu.?.intern_pool; |
| 1553 | return ip.getNav(nav_index).isThreadlocal(ip); | 1547 | return ip.getNav(nav_index).resolved.?.@"threadlocal"; |
| 1554 | } | 1548 | } |
| 1555 | 1549 | ||
| 1556 | fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { | 1550 | fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { |
src/link/SpirV.zig+1-1| ... | @@ -189,7 +189,7 @@ pub fn updateExports( | ... | @@ -189,7 +189,7 @@ pub fn updateExports( |
| 189 | @panic("TODO: implement Linker linker code for exporting a constant value"); | 189 | @panic("TODO: implement Linker linker code for exporting a constant value"); |
| 190 | }, | 190 | }, |
| 191 | }; | 191 | }; |
| 192 | const nav_ty = ip.getNav(nav_index).typeOf(ip); | 192 | const nav_ty = ip.getNav(nav_index).resolved.?.type; |
| 193 | const target = zcu.getTarget(); | 193 | const target = zcu.getTarget(); |
| 194 | if (ip.isFunctionType(nav_ty)) { | 194 | if (ip.isFunctionType(nav_ty)) { |
| 195 | const spv_decl_index = try linker.module.resolveNav(ip, nav_index); | 195 | const spv_decl_index = try linker.module.resolveNav(ip, nav_index); |
src/link/Wasm.zig+28-29| ... | @@ -420,7 +420,7 @@ pub const OutputFunctionIndex = enum(u32) { | ... | @@ -420,7 +420,7 @@ pub const OutputFunctionIndex = enum(u32) { |
| 420 | const zcu = wasm.base.comp.zcu.?; | 420 | const zcu = wasm.base.comp.zcu.?; |
| 421 | const ip = &zcu.intern_pool; | 421 | const ip = &zcu.intern_pool; |
| 422 | const nav = ip.getNav(nav_index); | 422 | const nav = ip.getNav(nav_index); |
| 423 | return fromIpIndex(wasm, nav.status.fully_resolved.val); | 423 | return fromIpIndex(wasm, nav.resolved.?.value); |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | pub fn fromTagNameType(wasm: *const Wasm, tag_type: InternPool.Index) OutputFunctionIndex { | 426 | pub fn fromTagNameType(wasm: *const Wasm, tag_type: InternPool.Index) OutputFunctionIndex { |
| ... | @@ -1022,7 +1022,7 @@ pub const FunctionImport = extern struct { | ... | @@ -1022,7 +1022,7 @@ pub const FunctionImport = extern struct { |
| 1022 | pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) Resolution { | 1022 | pub fn fromIpNav(wasm: *const Wasm, nav_index: InternPool.Nav.Index) Resolution { |
| 1023 | const zcu = wasm.base.comp.zcu.?; | 1023 | const zcu = wasm.base.comp.zcu.?; |
| 1024 | const ip = &zcu.intern_pool; | 1024 | const ip = &zcu.intern_pool; |
| 1025 | return fromIpIndex(wasm, ip.getNav(nav_index).status.fully_resolved.val); | 1025 | return fromIpIndex(wasm, ip.getNav(nav_index).resolved.?.value); |
| 1026 | } | 1026 | } |
| 1027 | 1027 | ||
| 1028 | pub fn fromZcuFunc(wasm: *const Wasm, i: ZcuFunc.Index) Resolution { | 1028 | pub fn fromZcuFunc(wasm: *const Wasm, i: ZcuFunc.Index) Resolution { |
| ... | @@ -1885,7 +1885,7 @@ pub const DataSegmentId = enum(u32) { | ... | @@ -1885,7 +1885,7 @@ pub const DataSegmentId = enum(u32) { |
| 1885 | const zcu = wasm.base.comp.zcu.?; | 1885 | const zcu = wasm.base.comp.zcu.?; |
| 1886 | const ip = &zcu.intern_pool; | 1886 | const ip = &zcu.intern_pool; |
| 1887 | const nav = ip.getNav(i.key(wasm).*); | 1887 | const nav = ip.getNav(i.key(wasm).*); |
| 1888 | if (nav.isThreadlocal(ip)) return .tls; | 1888 | if (nav.resolved.?.@"threadlocal") return .tls; |
| 1889 | const code = i.value(wasm).code; | 1889 | const code = i.value(wasm).code; |
| 1890 | return if (code.off == .none) .zero else .data; | 1890 | return if (code.off == .none) .zero else .data; |
| 1891 | }, | 1891 | }, |
| ... | @@ -1908,7 +1908,7 @@ pub const DataSegmentId = enum(u32) { | ... | @@ -1908,7 +1908,7 @@ pub const DataSegmentId = enum(u32) { |
| 1908 | const zcu = wasm.base.comp.zcu.?; | 1908 | const zcu = wasm.base.comp.zcu.?; |
| 1909 | const ip = &zcu.intern_pool; | 1909 | const ip = &zcu.intern_pool; |
| 1910 | const nav = ip.getNav(i.key(wasm).*); | 1910 | const nav = ip.getNav(i.key(wasm).*); |
| 1911 | return nav.isThreadlocal(ip); | 1911 | return nav.resolved.?.@"threadlocal"; |
| 1912 | }, | 1912 | }, |
| 1913 | }; | 1913 | }; |
| 1914 | } | 1914 | } |
| ... | @@ -1934,7 +1934,7 @@ pub const DataSegmentId = enum(u32) { | ... | @@ -1934,7 +1934,7 @@ pub const DataSegmentId = enum(u32) { |
| 1934 | const zcu = wasm.base.comp.zcu.?; | 1934 | const zcu = wasm.base.comp.zcu.?; |
| 1935 | const ip = &zcu.intern_pool; | 1935 | const ip = &zcu.intern_pool; |
| 1936 | const nav = ip.getNav(i.key(wasm).*); | 1936 | const nav = ip.getNav(i.key(wasm).*); |
| 1937 | return nav.getLinkSection().toSlice(ip) orelse switch (category(id, wasm)) { | 1937 | return nav.resolved.?.@"linksection".toSlice(ip) orelse switch (category(id, wasm)) { |
| 1938 | .tls => ".tdata", | 1938 | .tls => ".tdata", |
| 1939 | .data => ".data", | 1939 | .data => ".data", |
| 1940 | .zero => ".bss", | 1940 | .zero => ".bss", |
| ... | @@ -1962,9 +1962,9 @@ pub const DataSegmentId = enum(u32) { | ... | @@ -1962,9 +1962,9 @@ pub const DataSegmentId = enum(u32) { |
| 1962 | const zcu = wasm.base.comp.zcu.?; | 1962 | const zcu = wasm.base.comp.zcu.?; |
| 1963 | const ip = &zcu.intern_pool; | 1963 | const ip = &zcu.intern_pool; |
| 1964 | const nav = ip.getNav(i.key(wasm).*); | 1964 | const nav = ip.getNav(i.key(wasm).*); |
| 1965 | const explicit = nav.getAlignment(); | 1965 | const explicit = nav.resolved.?.@"align"; |
| 1966 | if (explicit != .none) return explicit; | 1966 | if (explicit != .none) return explicit; |
| 1967 | const ty: Zcu.Type = .fromInterned(nav.typeOf(ip)); | 1967 | const ty: Zcu.Type = .fromInterned(nav.resolved.?.type); |
| 1968 | const result = ty.abiAlignment(zcu); | 1968 | const result = ty.abiAlignment(zcu); |
| 1969 | assert(result != .none); | 1969 | assert(result != .none); |
| 1970 | return result; | 1970 | return result; |
| ... | @@ -2269,7 +2269,7 @@ pub const ZcuImportIndex = enum(u32) { | ... | @@ -2269,7 +2269,7 @@ pub const ZcuImportIndex = enum(u32) { |
| 2269 | const zcu = wasm.base.comp.zcu.?; | 2269 | const zcu = wasm.base.comp.zcu.?; |
| 2270 | const ip = &zcu.intern_pool; | 2270 | const ip = &zcu.intern_pool; |
| 2271 | const nav_index = index.ptr(wasm).*; | 2271 | const nav_index = index.ptr(wasm).*; |
| 2272 | const ext = ip.getNav(nav_index).getResolvedExtern(ip).?; | 2272 | const ext = ip.indexToKey(ip.getNav(nav_index).resolved.?.value).@"extern"; |
| 2273 | const name_slice = ext.name.toSlice(ip); | 2273 | const name_slice = ext.name.toSlice(ip); |
| 2274 | return wasm.getExistingString(name_slice).?; | 2274 | return wasm.getExistingString(name_slice).?; |
| 2275 | } | 2275 | } |
| ... | @@ -2278,7 +2278,7 @@ pub const ZcuImportIndex = enum(u32) { | ... | @@ -2278,7 +2278,7 @@ pub const ZcuImportIndex = enum(u32) { |
| 2278 | const zcu = wasm.base.comp.zcu.?; | 2278 | const zcu = wasm.base.comp.zcu.?; |
| 2279 | const ip = &zcu.intern_pool; | 2279 | const ip = &zcu.intern_pool; |
| 2280 | const nav_index = index.ptr(wasm).*; | 2280 | const nav_index = index.ptr(wasm).*; |
| 2281 | const ext = ip.getNav(nav_index).getResolvedExtern(ip).?; | 2281 | const ext = ip.indexToKey(ip.getNav(nav_index).resolved.?.value).@"extern"; |
| 2282 | const lib_name = ext.lib_name.toSlice(ip) orelse return .none; | 2282 | const lib_name = ext.lib_name.toSlice(ip) orelse return .none; |
| 2283 | return wasm.getExistingString(lib_name).?.toOptional(); | 2283 | return wasm.getExistingString(lib_name).?.toOptional(); |
| 2284 | } | 2284 | } |
| ... | @@ -2289,7 +2289,7 @@ pub const ZcuImportIndex = enum(u32) { | ... | @@ -2289,7 +2289,7 @@ pub const ZcuImportIndex = enum(u32) { |
| 2289 | const zcu = comp.zcu.?; | 2289 | const zcu = comp.zcu.?; |
| 2290 | const ip = &zcu.intern_pool; | 2290 | const ip = &zcu.intern_pool; |
| 2291 | const nav_index = index.ptr(wasm).*; | 2291 | const nav_index = index.ptr(wasm).*; |
| 2292 | const ext = ip.getNav(nav_index).getResolvedExtern(ip).?; | 2292 | const ext = ip.indexToKey(ip.getNav(nav_index).resolved.?.value).@"extern"; |
| 2293 | const fn_info = zcu.typeToFunc(.fromInterned(ext.ty)).?; | 2293 | const fn_info = zcu.typeToFunc(.fromInterned(ext.ty)).?; |
| 2294 | return getExistingFunctionType(wasm, fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target).?; | 2294 | return getExistingFunctionType(wasm, fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target).?; |
| 2295 | } | 2295 | } |
| ... | @@ -2381,7 +2381,7 @@ pub const FunctionImportId = enum(u32) { | ... | @@ -2381,7 +2381,7 @@ pub const FunctionImportId = enum(u32) { |
| 2381 | .zcu_import => |i| { | 2381 | .zcu_import => |i| { |
| 2382 | const zcu = wasm.base.comp.zcu.?; | 2382 | const zcu = wasm.base.comp.zcu.?; |
| 2383 | const ip = &zcu.intern_pool; | 2383 | const ip = &zcu.intern_pool; |
| 2384 | const ext = ip.getNav(i.ptr(wasm).*).getResolvedExtern(ip).?; | 2384 | const ext = ip.indexToKey(ip.getNav(i.ptr(wasm).*).resolved.?.value).@"extern"; |
| 2385 | return ext.linkage != .weak and ext.lib_name != .none; | 2385 | return ext.linkage != .weak and ext.lib_name != .none; |
| 2386 | }, | 2386 | }, |
| 2387 | }; | 2387 | }; |
| ... | @@ -3288,7 +3288,8 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index | ... | @@ -3288,7 +3288,8 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 3288 | const is_obj = comp.config.output_mode == .Obj; | 3288 | const is_obj = comp.config.output_mode == .Obj; |
| 3289 | const target = &comp.root_mod.resolved_target.result; | 3289 | const target = &comp.root_mod.resolved_target.result; |
| 3290 | 3290 | ||
| 3291 | const nav_init, const chased_nav_index = switch (ip.indexToKey(nav.status.fully_resolved.val)) { | 3291 | switch (ip.indexToKey(nav.resolved.?.value)) { |
| 3292 | else => {}, | ||
| 3292 | .func => return, // global const which is a function alias | 3293 | .func => return, // global const which is a function alias |
| 3293 | .@"extern" => |ext| { | 3294 | .@"extern" => |ext| { |
| 3294 | if (is_obj) { | 3295 | if (is_obj) { |
| ... | @@ -3302,7 +3303,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index | ... | @@ -3302,7 +3303,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 3302 | try wasm.function_imports.ensureUnusedCapacity(gpa, 1); | 3303 | try wasm.function_imports.ensureUnusedCapacity(gpa, 1); |
| 3303 | try wasm.data_imports.ensureUnusedCapacity(gpa, 1); | 3304 | try wasm.data_imports.ensureUnusedCapacity(gpa, 1); |
| 3304 | const zcu_import = wasm.addZcuImportReserved(ext.owner_nav); | 3305 | const zcu_import = wasm.addZcuImportReserved(ext.owner_nav); |
| 3305 | if (ip.isFunctionType(nav.typeOf(ip))) { | 3306 | if (ip.isFunctionType(nav.resolved.?.type)) { |
| 3306 | wasm.function_imports.putAssumeCapacity(name, .fromZcuImport(zcu_import, wasm)); | 3307 | wasm.function_imports.putAssumeCapacity(name, .fromZcuImport(zcu_import, wasm)); |
| 3307 | // Ensure there is a corresponding function type table entry. | 3308 | // Ensure there is a corresponding function type table entry. |
| 3308 | const fn_info = zcu.typeToFunc(.fromInterned(ext.ty)).?; | 3309 | const fn_info = zcu.typeToFunc(.fromInterned(ext.ty)).?; |
| ... | @@ -3312,31 +3313,29 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index | ... | @@ -3312,31 +3313,29 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 3312 | } | 3313 | } |
| 3313 | return; | 3314 | return; |
| 3314 | }, | 3315 | }, |
| 3315 | .variable => |variable| .{ variable.init, variable.owner_nav }, | 3316 | } |
| 3316 | else => .{ nav.status.fully_resolved.val, nav_index }, | 3317 | //log.debug("updateNav {f} {d}", .{ nav.fqn.fmt(ip), nav_index }); |
| 3317 | }; | 3318 | assert(!wasm.imports.contains(nav_index)); |
| 3318 | //log.debug("updateNav {f} {d}", .{ nav.fqn.fmt(ip), chased_nav_index }); | ||
| 3319 | assert(!wasm.imports.contains(chased_nav_index)); | ||
| 3320 | 3319 | ||
| 3321 | if (nav_init != .none and !Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) { | 3320 | if (!Zcu.Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) { |
| 3322 | if (is_obj) { | 3321 | if (is_obj) { |
| 3323 | assert(!wasm.navs_obj.contains(chased_nav_index)); | 3322 | assert(!wasm.navs_obj.contains(nav_index)); |
| 3324 | } else { | 3323 | } else { |
| 3325 | assert(!wasm.navs_exe.contains(chased_nav_index)); | 3324 | assert(!wasm.navs_exe.contains(nav_index)); |
| 3326 | } | 3325 | } |
| 3327 | return; | 3326 | return; |
| 3328 | } | 3327 | } |
| 3329 | 3328 | ||
| 3330 | if (is_obj) { | 3329 | if (is_obj) { |
| 3331 | const zcu_data_starts: ZcuDataStarts = .initObj(wasm); | 3330 | const zcu_data_starts: ZcuDataStarts = .initObj(wasm); |
| 3332 | const navs_i = try refNavObj(wasm, chased_nav_index); | 3331 | const navs_i = try refNavObj(wasm, nav_index); |
| 3333 | const zcu_data = try lowerZcuData(wasm, pt, nav_init); | 3332 | const zcu_data = try lowerZcuData(wasm, pt, nav.resolved.?.value); |
| 3334 | navs_i.value(wasm).* = zcu_data; | 3333 | navs_i.value(wasm).* = zcu_data; |
| 3335 | try zcu_data_starts.finishObj(wasm, pt); | 3334 | try zcu_data_starts.finishObj(wasm, pt); |
| 3336 | } else { | 3335 | } else { |
| 3337 | const zcu_data_starts: ZcuDataStarts = .initExe(wasm); | 3336 | const zcu_data_starts: ZcuDataStarts = .initExe(wasm); |
| 3338 | const navs_i = try refNavExe(wasm, chased_nav_index); | 3337 | const navs_i = try refNavExe(wasm, nav_index); |
| 3339 | const zcu_data = try lowerZcuData(wasm, pt, nav_init); | 3338 | const zcu_data = try lowerZcuData(wasm, pt, nav.resolved.?.value); |
| 3340 | navs_i.value(wasm).code = zcu_data.code; | 3339 | navs_i.value(wasm).code = zcu_data.code; |
| 3341 | try zcu_data_starts.finishExe(wasm, pt); | 3340 | try zcu_data_starts.finishExe(wasm, pt); |
| 3342 | } | 3341 | } |
| ... | @@ -4173,9 +4172,8 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { | ... | @@ -4173,9 +4172,8 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { |
| 4173 | } | 4172 | } |
| 4174 | const zcu = comp.zcu.?; | 4173 | const zcu = comp.zcu.?; |
| 4175 | const ip = &zcu.intern_pool; | 4174 | const ip = &zcu.intern_pool; |
| 4176 | const nav = ip.getNav(nav_index); | 4175 | switch (ip.indexToKey(ip.getNav(nav_index).resolved.?.value)) { |
| 4177 | if (nav.getResolvedExtern(ip)) |ext| { | 4176 | .@"extern" => |ext| if (wasm.getExistingString(ext.name.toSlice(ip))) |symbol_name| { |
| 4178 | if (wasm.getExistingString(ext.name.toSlice(ip))) |symbol_name| { | ||
| 4179 | if (wasm.object_data_imports.getPtr(symbol_name)) |import| { | 4177 | if (wasm.object_data_imports.getPtr(symbol_name)) |import| { |
| 4180 | switch (import.resolution.unpack(wasm)) { | 4178 | switch (import.resolution.unpack(wasm)) { |
| 4181 | .unresolved => unreachable, | 4179 | .unresolved => unreachable, |
| ... | @@ -4195,7 +4193,8 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { | ... | @@ -4195,7 +4193,8 @@ pub fn navAddr(wasm: *Wasm, nav_index: InternPool.Nav.Index) u32 { |
| 4195 | .nav_obj => @panic("TODO"), | 4193 | .nav_obj => @panic("TODO"), |
| 4196 | } | 4194 | } |
| 4197 | } | 4195 | } |
| 4198 | } | 4196 | }, |
| 4197 | else => {}, | ||
| 4199 | } | 4198 | } |
| 4200 | // Otherwise it's a zero bit type; any address will do. | 4199 | // Otherwise it's a zero bit type; any address will do. |
| 4201 | return 0; | 4200 | return 0; |
src/link/Wasm/Flush.zig+1-1| ... | @@ -211,7 +211,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -211,7 +211,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | for (wasm.nav_exports.keys(), wasm.nav_exports.values()) |*nav_export, export_index| { | 213 | for (wasm.nav_exports.keys(), wasm.nav_exports.values()) |*nav_export, export_index| { |
| 214 | if (ip.isFunctionType(ip.getNav(nav_export.nav_index).typeOf(ip))) { | 214 | if (ip.isFunctionType(ip.getNav(nav_export.nav_index).resolved.?.type)) { |
| 215 | log.debug("flush export '{s}' nav={d}", .{ nav_export.name.slice(wasm), nav_export.nav_index }); | 215 | log.debug("flush export '{s}' nav={d}", .{ nav_export.name.slice(wasm), nav_export.nav_index }); |
| 216 | const function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?; | 216 | const function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?; |
| 217 | const explicit = f.missing_exports.swapRemove(nav_export.name); | 217 | const explicit = f.missing_exports.swapRemove(nav_export.name); |
src/print_value.zig-1| ... | @@ -74,7 +74,6 @@ pub fn print( | ... | @@ -74,7 +74,6 @@ pub fn print( |
| 74 | .@"unreachable", | 74 | .@"unreachable", |
| 75 | => try writer.writeAll(@tagName(simple_value)), | 75 | => try writer.writeAll(@tagName(simple_value)), |
| 76 | }, | 76 | }, |
| 77 | .variable => try writer.writeAll("(variable)"), | ||
| 78 | .@"extern" => |e| try writer.print("(extern '{f}')", .{e.name.fmt(ip)}), | 77 | .@"extern" => |e| try writer.print("(extern '{f}')", .{e.name.fmt(ip)}), |
| 79 | .func => |func| try writer.print("(function '{f}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}), | 78 | .func => |func| try writer.print("(function '{f}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}), |
| 80 | .int => |int| switch (int.storage) { | 79 | .int => |int| switch (int.storage) { |