| author | |
| committer | |
| log | 9eda6ccefce370c76209ea50dd57fe65bfe25536 |
| tree | d5b4af496b8a6d1811788557d85e340ce26ef2bc |
| parent | 5a3ae38f3b79a69cb6f4ad28934a51165cae2ef1 |
This change eliminates some problematic recursive logic in InternPool,
and provides a safer API.11 files changed, 533 insertions(+), 546 deletions(-)
src/InternPool.zig+179-221| ... | @@ -326,6 +326,7 @@ pub const Key = union(enum) { | ... | @@ -326,6 +326,7 @@ pub const Key = union(enum) { |
| 326 | empty_enum_value: Index, | 326 | empty_enum_value: Index, |
| 327 | float: Float, | 327 | float: Float, |
| 328 | ptr: Ptr, | 328 | ptr: Ptr, |
| 329 | slice: Slice, | ||
| 329 | opt: Opt, | 330 | opt: Opt, |
| 330 | /// An instance of a struct, array, or vector. | 331 | /// An instance of a struct, array, or vector. |
| 331 | /// Each element/field stored as an `Index`. | 332 | /// Each element/field stored as an `Index`. |
| ... | @@ -493,7 +494,7 @@ pub const Key = union(enum) { | ... | @@ -493,7 +494,7 @@ pub const Key = union(enum) { |
| 493 | start: u32, | 494 | start: u32, |
| 494 | len: u32, | 495 | len: u32, |
| 495 | 496 | ||
| 496 | pub fn get(slice: Slice, ip: *const InternPool) []RuntimeOrder { | 497 | pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder { |
| 497 | return @ptrCast(ip.extra.items[slice.start..][0..slice.len]); | 498 | return @ptrCast(ip.extra.items[slice.start..][0..slice.len]); |
| 498 | } | 499 | } |
| 499 | }; | 500 | }; |
| ... | @@ -1197,8 +1198,6 @@ pub const Key = union(enum) { | ... | @@ -1197,8 +1198,6 @@ pub const Key = union(enum) { |
| 1197 | ty: Index, | 1198 | ty: Index, |
| 1198 | /// The value of the address that the pointer points to. | 1199 | /// The value of the address that the pointer points to. |
| 1199 | addr: Addr, | 1200 | addr: Addr, |
| 1200 | /// This could be `none` if size is not a slice. | ||
| 1201 | len: Index = .none, | ||
| 1202 | 1201 | ||
| 1203 | pub const Addr = union(enum) { | 1202 | pub const Addr = union(enum) { |
| 1204 | const Tag = @typeInfo(Addr).Union.tag_type.?; | 1203 | const Tag = @typeInfo(Addr).Union.tag_type.?; |
| ... | @@ -1232,6 +1231,15 @@ pub const Key = union(enum) { | ... | @@ -1232,6 +1231,15 @@ pub const Key = union(enum) { |
| 1232 | }; | 1231 | }; |
| 1233 | }; | 1232 | }; |
| 1234 | 1233 | ||
| 1234 | pub const Slice = struct { | ||
| 1235 | /// This is the slice type, not the element type. | ||
| 1236 | ty: Index, | ||
| 1237 | /// The slice's `ptr` field. Must be a many-ptr with the same properties as `ty`. | ||
| 1238 | ptr: Index, | ||
| 1239 | /// The slice's `len` field. Must be a `usize`. | ||
| 1240 | len: Index, | ||
| 1241 | }; | ||
| 1242 | |||
| 1235 | /// `null` is represented by the `val` field being `none`. | 1243 | /// `null` is represented by the `val` field being `none`. |
| 1236 | pub const Opt = extern struct { | 1244 | pub const Opt = extern struct { |
| 1237 | /// This is the optional type; not the payload type. | 1245 | /// This is the optional type; not the payload type. |
| ... | @@ -1354,12 +1362,14 @@ pub const Key = union(enum) { | ... | @@ -1354,12 +1362,14 @@ pub const Key = union(enum) { |
| 1354 | return hasher.final(); | 1362 | return hasher.final(); |
| 1355 | }, | 1363 | }, |
| 1356 | 1364 | ||
| 1365 | .slice => |slice| Hash.hash(seed, asBytes(&slice.ty) ++ asBytes(&slice.ptr) ++ asBytes(&slice.len)), | ||
| 1366 | |||
| 1357 | .ptr => |ptr| { | 1367 | .ptr => |ptr| { |
| 1358 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. | 1368 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. |
| 1359 | // This is sound due to pointer provenance rules. | 1369 | // This is sound due to pointer provenance rules. |
| 1360 | const addr: @typeInfo(Key.Ptr.Addr).Union.tag_type.? = ptr.addr; | 1370 | const addr: @typeInfo(Key.Ptr.Addr).Union.tag_type.? = ptr.addr; |
| 1361 | const seed2 = seed + @intFromEnum(addr); | 1371 | const seed2 = seed + @intFromEnum(addr); |
| 1362 | const common = asBytes(&ptr.ty) ++ asBytes(&ptr.len); | 1372 | const common = asBytes(&ptr.ty); |
| 1363 | return switch (ptr.addr) { | 1373 | return switch (ptr.addr) { |
| 1364 | .decl => |x| Hash.hash(seed2, common ++ asBytes(&x)), | 1374 | .decl => |x| Hash.hash(seed2, common ++ asBytes(&x)), |
| 1365 | 1375 | ||
| ... | @@ -1624,9 +1634,17 @@ pub const Key = union(enum) { | ... | @@ -1624,9 +1634,17 @@ pub const Key = union(enum) { |
| 1624 | return a_ty_info.eql(b_ty_info, ip); | 1634 | return a_ty_info.eql(b_ty_info, ip); |
| 1625 | }, | 1635 | }, |
| 1626 | 1636 | ||
| 1637 | .slice => |a_info| { | ||
| 1638 | const b_info = b.slice; | ||
| 1639 | if (a_info.ty != b_info.ty) return false; | ||
| 1640 | if (a_info.ptr != b_info.ptr) return false; | ||
| 1641 | if (a_info.len != b_info.len) return false; | ||
| 1642 | return true; | ||
| 1643 | }, | ||
| 1644 | |||
| 1627 | .ptr => |a_info| { | 1645 | .ptr => |a_info| { |
| 1628 | const b_info = b.ptr; | 1646 | const b_info = b.ptr; |
| 1629 | if (a_info.ty != b_info.ty or a_info.len != b_info.len) return false; | 1647 | if (a_info.ty != b_info.ty) return false; |
| 1630 | 1648 | ||
| 1631 | const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?; | 1649 | const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?; |
| 1632 | if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false; | 1650 | if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false; |
| ... | @@ -1829,6 +1847,7 @@ pub const Key = union(enum) { | ... | @@ -1829,6 +1847,7 @@ pub const Key = union(enum) { |
| 1829 | => .type_type, | 1847 | => .type_type, |
| 1830 | 1848 | ||
| 1831 | inline .ptr, | 1849 | inline .ptr, |
| 1850 | .slice, | ||
| 1832 | .int, | 1851 | .int, |
| 1833 | .float, | 1852 | .float, |
| 1834 | .opt, | 1853 | .opt, |
| ... | @@ -3983,77 +4002,11 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -3983,77 +4002,11 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 3983 | }, | 4002 | }, |
| 3984 | .ptr_slice => { | 4003 | .ptr_slice => { |
| 3985 | const info = ip.extraData(PtrSlice, data); | 4004 | const info = ip.extraData(PtrSlice, data); |
| 3986 | const ptr_item = ip.items.get(@intFromEnum(info.ptr)); | 4005 | return .{ .slice = .{ |
| 3987 | return .{ | 4006 | .ty = info.ty, |
| 3988 | .ptr = .{ | 4007 | .ptr = info.ptr, |
| 3989 | .ty = info.ty, | 4008 | .len = info.len, |
| 3990 | .addr = switch (ptr_item.tag) { | 4009 | } }; |
| 3991 | .ptr_decl => .{ | ||
| 3992 | .decl = ip.extraData(PtrDecl, ptr_item.data).decl, | ||
| 3993 | }, | ||
| 3994 | .ptr_mut_decl => b: { | ||
| 3995 | const sub_info = ip.extraData(PtrMutDecl, ptr_item.data); | ||
| 3996 | break :b .{ .mut_decl = .{ | ||
| 3997 | .decl = sub_info.decl, | ||
| 3998 | .runtime_index = sub_info.runtime_index, | ||
| 3999 | } }; | ||
| 4000 | }, | ||
| 4001 | .ptr_anon_decl => .{ | ||
| 4002 | .anon_decl = .{ | ||
| 4003 | .val = ip.extraData(PtrAnonDecl, ptr_item.data).val, | ||
| 4004 | .orig_ty = info.ty, | ||
| 4005 | }, | ||
| 4006 | }, | ||
| 4007 | .ptr_anon_decl_aligned => b: { | ||
| 4008 | const sub_info = ip.extraData(PtrAnonDeclAligned, ptr_item.data); | ||
| 4009 | break :b .{ .anon_decl = .{ | ||
| 4010 | .val = sub_info.val, | ||
| 4011 | .orig_ty = sub_info.orig_ty, | ||
| 4012 | } }; | ||
| 4013 | }, | ||
| 4014 | .ptr_comptime_field => .{ | ||
| 4015 | .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val, | ||
| 4016 | }, | ||
| 4017 | .ptr_int => .{ | ||
| 4018 | .int = ip.extraData(PtrBase, ptr_item.data).base, | ||
| 4019 | }, | ||
| 4020 | .ptr_eu_payload => .{ | ||
| 4021 | .eu_payload = ip.extraData(PtrBase, ptr_item.data).base, | ||
| 4022 | }, | ||
| 4023 | .ptr_opt_payload => .{ | ||
| 4024 | .opt_payload = ip.extraData(PtrBase, ptr_item.data).base, | ||
| 4025 | }, | ||
| 4026 | .ptr_elem => b: { | ||
| 4027 | // Avoid `indexToKey` recursion by asserting the tag encoding. | ||
| 4028 | const sub_info = ip.extraData(PtrBaseIndex, ptr_item.data); | ||
| 4029 | const index_item = ip.items.get(@intFromEnum(sub_info.index)); | ||
| 4030 | break :b switch (index_item.tag) { | ||
| 4031 | .int_usize => .{ .elem = .{ | ||
| 4032 | .base = sub_info.base, | ||
| 4033 | .index = index_item.data, | ||
| 4034 | } }, | ||
| 4035 | .int_positive => @panic("TODO"), // implement along with behavior test coverage | ||
| 4036 | else => unreachable, | ||
| 4037 | }; | ||
| 4038 | }, | ||
| 4039 | .ptr_field => b: { | ||
| 4040 | // Avoid `indexToKey` recursion by asserting the tag encoding. | ||
| 4041 | const sub_info = ip.extraData(PtrBaseIndex, ptr_item.data); | ||
| 4042 | const index_item = ip.items.get(@intFromEnum(sub_info.index)); | ||
| 4043 | break :b switch (index_item.tag) { | ||
| 4044 | .int_usize => .{ .field = .{ | ||
| 4045 | .base = sub_info.base, | ||
| 4046 | .index = index_item.data, | ||
| 4047 | } }, | ||
| 4048 | .int_positive => @panic("TODO"), // implement along with behavior test coverage | ||
| 4049 | else => unreachable, | ||
| 4050 | }; | ||
| 4051 | }, | ||
| 4052 | else => unreachable, | ||
| 4053 | }, | ||
| 4054 | .len = info.len, | ||
| 4055 | }, | ||
| 4056 | }; | ||
| 4057 | }, | 4010 | }, |
| 4058 | .int_u8 => .{ .int = .{ | 4011 | .int_u8 => .{ .int = .{ |
| 4059 | .ty = .u8_type, | 4012 | .ty = .u8_type, |
| ... | @@ -4735,153 +4688,139 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -4735,153 +4688,139 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 4735 | }); | 4688 | }); |
| 4736 | }, | 4689 | }, |
| 4737 | 4690 | ||
| 4691 | .slice => |slice| { | ||
| 4692 | assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice); | ||
| 4693 | assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many); | ||
| 4694 | ip.items.appendAssumeCapacity(.{ | ||
| 4695 | .tag = .ptr_slice, | ||
| 4696 | .data = try ip.addExtra(gpa, PtrSlice{ | ||
| 4697 | .ty = slice.ty, | ||
| 4698 | .ptr = slice.ptr, | ||
| 4699 | .len = slice.len, | ||
| 4700 | }), | ||
| 4701 | }); | ||
| 4702 | }, | ||
| 4703 | |||
| 4738 | .ptr => |ptr| { | 4704 | .ptr => |ptr| { |
| 4739 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; | 4705 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; |
| 4740 | switch (ptr.len) { | 4706 | assert(ptr_type.flags.size != .Slice); |
| 4741 | .none => { | 4707 | switch (ptr.addr) { |
| 4742 | assert(ptr_type.flags.size != .Slice); | 4708 | .decl => |decl| ip.items.appendAssumeCapacity(.{ |
| 4743 | switch (ptr.addr) { | 4709 | .tag = .ptr_decl, |
| 4744 | .decl => |decl| ip.items.appendAssumeCapacity(.{ | 4710 | .data = try ip.addExtra(gpa, PtrDecl{ |
| 4745 | .tag = .ptr_decl, | 4711 | .ty = ptr.ty, |
| 4746 | .data = try ip.addExtra(gpa, PtrDecl{ | 4712 | .decl = decl, |
| 4747 | .ty = ptr.ty, | 4713 | }), |
| 4748 | .decl = decl, | 4714 | }), |
| 4749 | }), | 4715 | .mut_decl => |mut_decl| ip.items.appendAssumeCapacity(.{ |
| 4716 | .tag = .ptr_mut_decl, | ||
| 4717 | .data = try ip.addExtra(gpa, PtrMutDecl{ | ||
| 4718 | .ty = ptr.ty, | ||
| 4719 | .decl = mut_decl.decl, | ||
| 4720 | .runtime_index = mut_decl.runtime_index, | ||
| 4721 | }), | ||
| 4722 | }), | ||
| 4723 | .anon_decl => |anon_decl| ip.items.appendAssumeCapacity( | ||
| 4724 | if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{ | ||
| 4725 | .tag = .ptr_anon_decl, | ||
| 4726 | .data = try ip.addExtra(gpa, PtrAnonDecl{ | ||
| 4727 | .ty = ptr.ty, | ||
| 4728 | .val = anon_decl.val, | ||
| 4750 | }), | 4729 | }), |
| 4751 | .mut_decl => |mut_decl| ip.items.appendAssumeCapacity(.{ | 4730 | } else .{ |
| 4752 | .tag = .ptr_mut_decl, | 4731 | .tag = .ptr_anon_decl_aligned, |
| 4753 | .data = try ip.addExtra(gpa, PtrMutDecl{ | 4732 | .data = try ip.addExtra(gpa, PtrAnonDeclAligned{ |
| 4754 | .ty = ptr.ty, | 4733 | .ty = ptr.ty, |
| 4755 | .decl = mut_decl.decl, | 4734 | .val = anon_decl.val, |
| 4756 | .runtime_index = mut_decl.runtime_index, | 4735 | .orig_ty = anon_decl.orig_ty, |
| 4757 | }), | ||
| 4758 | }), | 4736 | }), |
| 4759 | .anon_decl => |anon_decl| ip.items.appendAssumeCapacity( | 4737 | }, |
| 4760 | if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{ | 4738 | ), |
| 4761 | .tag = .ptr_anon_decl, | 4739 | .comptime_field => |field_val| { |
| 4762 | .data = try ip.addExtra(gpa, PtrAnonDecl{ | 4740 | assert(field_val != .none); |
| 4763 | .ty = ptr.ty, | 4741 | ip.items.appendAssumeCapacity(.{ |
| 4764 | .val = anon_decl.val, | 4742 | .tag = .ptr_comptime_field, |
| 4765 | }), | 4743 | .data = try ip.addExtra(gpa, PtrComptimeField{ |
| 4766 | } else .{ | 4744 | .ty = ptr.ty, |
| 4767 | .tag = .ptr_anon_decl_aligned, | 4745 | .field_val = field_val, |
| 4768 | .data = try ip.addExtra(gpa, PtrAnonDeclAligned{ | 4746 | }), |
| 4769 | .ty = ptr.ty, | 4747 | }); |
| 4770 | .val = anon_decl.val, | 4748 | }, |
| 4771 | .orig_ty = anon_decl.orig_ty, | 4749 | .int, .eu_payload, .opt_payload => |base| { |
| 4772 | }), | 4750 | switch (ptr.addr) { |
| 4773 | }, | 4751 | .int => assert(ip.typeOf(base) == .usize_type), |
| 4774 | ), | 4752 | .eu_payload => assert(ip.indexToKey( |
| 4775 | .comptime_field => |field_val| { | 4753 | ip.indexToKey(ip.typeOf(base)).ptr_type.child, |
| 4776 | assert(field_val != .none); | 4754 | ) == .error_union_type), |
| 4777 | ip.items.appendAssumeCapacity(.{ | 4755 | .opt_payload => assert(ip.indexToKey( |
| 4778 | .tag = .ptr_comptime_field, | 4756 | ip.indexToKey(ip.typeOf(base)).ptr_type.child, |
| 4779 | .data = try ip.addExtra(gpa, PtrComptimeField{ | 4757 | ) == .opt_type), |
| 4780 | .ty = ptr.ty, | 4758 | else => unreachable, |
| 4781 | .field_val = field_val, | 4759 | } |
| 4782 | }), | 4760 | ip.items.appendAssumeCapacity(.{ |
| 4783 | }); | 4761 | .tag = switch (ptr.addr) { |
| 4762 | .int => .ptr_int, | ||
| 4763 | .eu_payload => .ptr_eu_payload, | ||
| 4764 | .opt_payload => .ptr_opt_payload, | ||
| 4765 | else => unreachable, | ||
| 4784 | }, | 4766 | }, |
| 4785 | .int, .eu_payload, .opt_payload => |base| { | 4767 | .data = try ip.addExtra(gpa, PtrBase{ |
| 4786 | switch (ptr.addr) { | 4768 | .ty = ptr.ty, |
| 4787 | .int => assert(ip.typeOf(base) == .usize_type), | 4769 | .base = base, |
| 4788 | .eu_payload => assert(ip.indexToKey( | 4770 | }), |
| 4789 | ip.indexToKey(ip.typeOf(base)).ptr_type.child, | 4771 | }); |
| 4790 | ) == .error_union_type), | 4772 | }, |
| 4791 | .opt_payload => assert(ip.indexToKey( | 4773 | .elem, .field => |base_index| { |
| 4792 | ip.indexToKey(ip.typeOf(base)).ptr_type.child, | 4774 | const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type; |
| 4793 | ) == .opt_type), | 4775 | switch (ptr.addr) { |
| 4794 | else => unreachable, | 4776 | .elem => assert(base_ptr_type.flags.size == .Many), |
| 4795 | } | 4777 | .field => { |
| 4796 | ip.items.appendAssumeCapacity(.{ | 4778 | assert(base_ptr_type.flags.size == .One); |
| 4797 | .tag = switch (ptr.addr) { | 4779 | switch (ip.indexToKey(base_ptr_type.child)) { |
| 4798 | .int => .ptr_int, | 4780 | .anon_struct_type => |anon_struct_type| { |
| 4799 | .eu_payload => .ptr_eu_payload, | 4781 | assert(ptr.addr == .field); |
| 4800 | .opt_payload => .ptr_opt_payload, | 4782 | assert(base_index.index < anon_struct_type.types.len); |
| 4801 | else => unreachable, | ||
| 4802 | }, | 4783 | }, |
| 4803 | .data = try ip.addExtra(gpa, PtrBase{ | 4784 | .struct_type => |struct_type| { |
| 4804 | .ty = ptr.ty, | 4785 | assert(ptr.addr == .field); |
| 4805 | .base = base, | 4786 | assert(base_index.index < struct_type.field_types.len); |
| 4806 | }), | 4787 | }, |
| 4807 | }); | 4788 | .union_type => |union_key| { |
| 4808 | }, | 4789 | const union_type = ip.loadUnionType(union_key); |
| 4809 | .elem, .field => |base_index| { | 4790 | assert(ptr.addr == .field); |
| 4810 | const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type; | 4791 | assert(base_index.index < union_type.field_names.len); |
| 4811 | switch (ptr.addr) { | 4792 | }, |
| 4812 | .elem => assert(base_ptr_type.flags.size == .Many), | 4793 | .ptr_type => |slice_type| { |
| 4813 | .field => { | 4794 | assert(ptr.addr == .field); |
| 4814 | assert(base_ptr_type.flags.size == .One); | 4795 | assert(slice_type.flags.size == .Slice); |
| 4815 | switch (ip.indexToKey(base_ptr_type.child)) { | 4796 | assert(base_index.index < 2); |
| 4816 | .anon_struct_type => |anon_struct_type| { | ||
| 4817 | assert(ptr.addr == .field); | ||
| 4818 | assert(base_index.index < anon_struct_type.types.len); | ||
| 4819 | }, | ||
| 4820 | .struct_type => |struct_type| { | ||
| 4821 | assert(ptr.addr == .field); | ||
| 4822 | assert(base_index.index < struct_type.field_types.len); | ||
| 4823 | }, | ||
| 4824 | .union_type => |union_key| { | ||
| 4825 | const union_type = ip.loadUnionType(union_key); | ||
| 4826 | assert(ptr.addr == .field); | ||
| 4827 | assert(base_index.index < union_type.field_names.len); | ||
| 4828 | }, | ||
| 4829 | .ptr_type => |slice_type| { | ||
| 4830 | assert(ptr.addr == .field); | ||
| 4831 | assert(slice_type.flags.size == .Slice); | ||
| 4832 | assert(base_index.index < 2); | ||
| 4833 | }, | ||
| 4834 | else => unreachable, | ||
| 4835 | } | ||
| 4836 | }, | 4797 | }, |
| 4837 | else => unreachable, | 4798 | else => unreachable, |
| 4838 | } | 4799 | } |
| 4839 | _ = ip.map.pop(); | ||
| 4840 | const index_index = try ip.get(gpa, .{ .int = .{ | ||
| 4841 | .ty = .usize_type, | ||
| 4842 | .storage = .{ .u64 = base_index.index }, | ||
| 4843 | } }); | ||
| 4844 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); | ||
| 4845 | try ip.items.ensureUnusedCapacity(gpa, 1); | ||
| 4846 | ip.items.appendAssumeCapacity(.{ | ||
| 4847 | .tag = switch (ptr.addr) { | ||
| 4848 | .elem => .ptr_elem, | ||
| 4849 | .field => .ptr_field, | ||
| 4850 | else => unreachable, | ||
| 4851 | }, | ||
| 4852 | .data = try ip.addExtra(gpa, PtrBaseIndex{ | ||
| 4853 | .ty = ptr.ty, | ||
| 4854 | .base = base_index.base, | ||
| 4855 | .index = index_index, | ||
| 4856 | }), | ||
| 4857 | }); | ||
| 4858 | }, | 4800 | }, |
| 4801 | else => unreachable, | ||
| 4859 | } | 4802 | } |
| 4860 | }, | ||
| 4861 | else => { | ||
| 4862 | // TODO: change Key.Ptr for slices to reference the manyptr value | ||
| 4863 | // rather than having an addr field directly. Then we can avoid | ||
| 4864 | // these problematic calls to pop(), get(), and getOrPutAdapted(). | ||
| 4865 | assert(ptr_type.flags.size == .Slice); | ||
| 4866 | _ = ip.map.pop(); | 4803 | _ = ip.map.pop(); |
| 4867 | var new_key = key; | 4804 | const index_index = try ip.get(gpa, .{ .int = .{ |
| 4868 | new_key.ptr.ty = ip.slicePtrType(ptr.ty); | 4805 | .ty = .usize_type, |
| 4869 | new_key.ptr.len = .none; | 4806 | .storage = .{ .u64 = base_index.index }, |
| 4870 | assert(ip.indexToKey(new_key.ptr.ty).ptr_type.flags.size == .Many); | 4807 | } }); |
| 4871 | const ptr_index = try ip.get(gpa, new_key); | ||
| 4872 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); | 4808 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); |
| 4873 | try ip.items.ensureUnusedCapacity(gpa, 1); | 4809 | try ip.items.ensureUnusedCapacity(gpa, 1); |
| 4874 | ip.items.appendAssumeCapacity(.{ | 4810 | ip.items.appendAssumeCapacity(.{ |
| 4875 | .tag = .ptr_slice, | 4811 | .tag = switch (ptr.addr) { |
| 4876 | .data = try ip.addExtra(gpa, PtrSlice{ | 4812 | .elem => .ptr_elem, |
| 4813 | .field => .ptr_field, | ||
| 4814 | else => unreachable, | ||
| 4815 | }, | ||
| 4816 | .data = try ip.addExtra(gpa, PtrBaseIndex{ | ||
| 4877 | .ty = ptr.ty, | 4817 | .ty = ptr.ty, |
| 4878 | .ptr = ptr_index, | 4818 | .base = base_index.base, |
| 4879 | .len = ptr.len, | 4819 | .index = index_index, |
| 4880 | }), | 4820 | }), |
| 4881 | }); | 4821 | }); |
| 4882 | }, | 4822 | }, |
| 4883 | } | 4823 | } |
| 4884 | assert(ptr.ty == ip.indexToKey(@as(Index, @enumFromInt(ip.items.len - 1))).ptr.ty); | ||
| 4885 | }, | 4824 | }, |
| 4886 | 4825 | ||
| 4887 | .opt => |opt| { | 4826 | .opt => |opt| { |
| ... | @@ -6844,14 +6783,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -6844,14 +6783,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 6844 | .val = .none, | 6783 | .val = .none, |
| 6845 | } }); | 6784 | } }); |
| 6846 | 6785 | ||
| 6847 | if (ip.isPointerType(new_ty)) return ip.get(gpa, .{ .ptr = .{ | 6786 | if (ip.isPointerType(new_ty)) switch (ip.indexToKey(new_ty).ptr_type.flags.size) { |
| 6848 | .ty = new_ty, | 6787 | .One, .Many, .C => return ip.get(gpa, .{ .ptr = .{ |
| 6849 | .addr = .{ .int = .zero_usize }, | 6788 | .ty = new_ty, |
| 6850 | .len = switch (ip.indexToKey(new_ty).ptr_type.flags.size) { | 6789 | .addr = .{ .int = .zero_usize }, |
| 6851 | .One, .Many, .C => .none, | 6790 | } }), |
| 6852 | .Slice => try ip.get(gpa, .{ .undef = .usize_type }), | 6791 | .Slice => return ip.get(gpa, .{ .slice = .{ |
| 6853 | }, | 6792 | .ty = new_ty, |
| 6854 | } }); | 6793 | .ptr = try ip.get(gpa, .{ .ptr = .{ |
| 6794 | .ty = ip.slicePtrType(new_ty), | ||
| 6795 | .addr = .{ .int = .zero_usize }, | ||
| 6796 | } }), | ||
| 6797 | .len = try ip.get(gpa, .{ .undef = .usize_type }), | ||
| 6798 | } }), | ||
| 6799 | }; | ||
| 6855 | }, | 6800 | }, |
| 6856 | else => switch (tags[@intFromEnum(val)]) { | 6801 | else => switch (tags[@intFromEnum(val)]) { |
| 6857 | .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty), | 6802 | .func_decl => return getCoercedFuncDecl(ip, gpa, val, new_ty), |
| ... | @@ -6929,11 +6874,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -6929,11 +6874,18 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 6929 | }, | 6874 | }, |
| 6930 | else => {}, | 6875 | else => {}, |
| 6931 | }, | 6876 | }, |
| 6932 | .ptr => |ptr| if (ip.isPointerType(new_ty)) | 6877 | .slice => |slice| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size == .Slice) |
| 6878 | return ip.get(gpa, .{ .slice = .{ | ||
| 6879 | .ty = new_ty, | ||
| 6880 | .ptr = try ip.getCoerced(gpa, slice.ptr, ip.slicePtrType(new_ty)), | ||
| 6881 | .len = slice.len, | ||
| 6882 | } }) | ||
| 6883 | else if (ip.isIntegerType(new_ty)) | ||
| 6884 | return ip.getCoerced(gpa, slice.ptr, new_ty), | ||
| 6885 | .ptr => |ptr| if (ip.isPointerType(new_ty) and ip.indexToKey(new_ty).ptr_type.flags.size != .Slice) | ||
| 6933 | return ip.get(gpa, .{ .ptr = .{ | 6886 | return ip.get(gpa, .{ .ptr = .{ |
| 6934 | .ty = new_ty, | 6887 | .ty = new_ty, |
| 6935 | .addr = ptr.addr, | 6888 | .addr = ptr.addr, |
| 6936 | .len = ptr.len, | ||
| 6937 | } }) | 6889 | } }) |
| 6938 | else if (ip.isIntegerType(new_ty)) | 6890 | else if (ip.isIntegerType(new_ty)) |
| 6939 | switch (ptr.addr) { | 6891 | switch (ptr.addr) { |
| ... | @@ -6942,14 +6894,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -6942,14 +6894,20 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 6942 | }, | 6894 | }, |
| 6943 | .opt => |opt| switch (ip.indexToKey(new_ty)) { | 6895 | .opt => |opt| switch (ip.indexToKey(new_ty)) { |
| 6944 | .ptr_type => |ptr_type| return switch (opt.val) { | 6896 | .ptr_type => |ptr_type| return switch (opt.val) { |
| 6945 | .none => try ip.get(gpa, .{ .ptr = .{ | 6897 | .none => switch (ptr_type.flags.size) { |
| 6946 | .ty = new_ty, | 6898 | .One, .Many, .C => try ip.get(gpa, .{ .ptr = .{ |
| 6947 | .addr = .{ .int = .zero_usize }, | 6899 | .ty = new_ty, |
| 6948 | .len = switch (ptr_type.flags.size) { | 6900 | .addr = .{ .int = .zero_usize }, |
| 6949 | .One, .Many, .C => .none, | 6901 | } }), |
| 6950 | .Slice => try ip.get(gpa, .{ .undef = .usize_type }), | 6902 | .Slice => try ip.get(gpa, .{ .slice = .{ |
| 6951 | }, | 6903 | .ty = new_ty, |
| 6952 | } }), | 6904 | .ptr = try ip.get(gpa, .{ .ptr = .{ |
| 6905 | .ty = ip.slicePtrType(new_ty), | ||
| 6906 | .addr = .{ .int = .zero_usize }, | ||
| 6907 | } }), | ||
| 6908 | .len = try ip.get(gpa, .{ .undef = .usize_type }), | ||
| 6909 | } }), | ||
| 6910 | }, | ||
| 6953 | else => |payload| try ip.getCoerced(gpa, payload, new_ty), | 6911 | else => |payload| try ip.getCoerced(gpa, payload, new_ty), |
| 6954 | }, | 6912 | }, |
| 6955 | .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{ | 6913 | .opt_type => |child_type| return try ip.get(gpa, .{ .opt = .{ |
src/Module.zig+21-14| ... | @@ -5278,9 +5278,12 @@ pub fn populateTestFunctions( | ... | @@ -5278,9 +5278,12 @@ pub fn populateTestFunctions( |
| 5278 | 5278 | ||
| 5279 | const test_fn_fields = .{ | 5279 | const test_fn_fields = .{ |
| 5280 | // name | 5280 | // name |
| 5281 | try mod.intern(.{ .ptr = .{ | 5281 | try mod.intern(.{ .slice = .{ |
| 5282 | .ty = .slice_const_u8_type, | 5282 | .ty = .slice_const_u8_type, |
| 5283 | .addr = .{ .decl = test_name_decl_index }, | 5283 | .ptr = try mod.intern(.{ .ptr = .{ |
| 5284 | .ty = .manyptr_const_u8_type, | ||
| 5285 | .addr = .{ .decl = test_name_decl_index }, | ||
| 5286 | } }), | ||
| 5284 | .len = try mod.intern(.{ .int = .{ | 5287 | .len = try mod.intern(.{ .int = .{ |
| 5285 | .ty = .usize_type, | 5288 | .ty = .usize_type, |
| 5286 | .storage = .{ .u64 = test_decl_name.len }, | 5289 | .storage = .{ .u64 = test_decl_name.len }, |
| ... | @@ -5331,9 +5334,12 @@ pub fn populateTestFunctions( | ... | @@ -5331,9 +5334,12 @@ pub fn populateTestFunctions( |
| 5331 | }, | 5334 | }, |
| 5332 | }); | 5335 | }); |
| 5333 | const new_val = decl.val; | 5336 | const new_val = decl.val; |
| 5334 | const new_init = try mod.intern(.{ .ptr = .{ | 5337 | const new_init = try mod.intern(.{ .slice = .{ |
| 5335 | .ty = new_ty.toIntern(), | 5338 | .ty = new_ty.toIntern(), |
| 5336 | .addr = .{ .decl = array_decl_index }, | 5339 | .ptr = try mod.intern(.{ .ptr = .{ |
| 5340 | .ty = new_ty.slicePtrFieldType(mod).toIntern(), | ||
| 5341 | .addr = .{ .decl = array_decl_index }, | ||
| 5342 | } }), | ||
| 5337 | .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(), | 5343 | .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(), |
| 5338 | } }); | 5344 | } }); |
| 5339 | ip.mutateVarInit(decl.val.toIntern(), new_init); | 5345 | ip.mutateVarInit(decl.val.toIntern(), new_init); |
| ... | @@ -5423,16 +5429,17 @@ pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void { | ... | @@ -5423,16 +5429,17 @@ pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void { |
| 5423 | .err_name => {}, | 5429 | .err_name => {}, |
| 5424 | .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)), | 5430 | .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)), |
| 5425 | }, | 5431 | }, |
| 5426 | .ptr => |ptr| { | 5432 | .slice => |slice| { |
| 5427 | switch (ptr.addr) { | 5433 | try mod.markReferencedDeclsAlive(Value.fromInterned(slice.ptr)); |
| 5428 | .decl => |decl| try mod.markDeclIndexAlive(decl), | 5434 | try mod.markReferencedDeclsAlive(Value.fromInterned(slice.len)); |
| 5429 | .anon_decl => {}, | 5435 | }, |
| 5430 | .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl), | 5436 | .ptr => |ptr| switch (ptr.addr) { |
| 5431 | .int, .comptime_field => {}, | 5437 | .decl => |decl| try mod.markDeclIndexAlive(decl), |
| 5432 | .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)), | 5438 | .anon_decl => {}, |
| 5433 | .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)), | 5439 | .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl), |
| 5434 | } | 5440 | .int, .comptime_field => {}, |
| 5435 | if (ptr.len != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(ptr.len)); | 5441 | .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)), |
| 5442 | .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)), | ||
| 5436 | }, | 5443 | }, |
| 5437 | .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)), | 5444 | .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)), |
| 5438 | .aggregate => |aggregate| for (aggregate.storage.values()) |elem| | 5445 | .aggregate => |aggregate| for (aggregate.storage.values()) |elem| |
src/Sema.zig+165-124| ... | @@ -17375,16 +17375,19 @@ fn zirBuiltinSrc( | ... | @@ -17375,16 +17375,19 @@ fn zirBuiltinSrc( |
| 17375 | .sentinel = .zero_u8, | 17375 | .sentinel = .zero_u8, |
| 17376 | .child = .u8_type, | 17376 | .child = .u8_type, |
| 17377 | } }); | 17377 | } }); |
| 17378 | break :v try ip.get(gpa, .{ .ptr = .{ | 17378 | break :v try ip.get(gpa, .{ .slice = .{ |
| 17379 | .ty = .slice_const_u8_sentinel_0_type, | 17379 | .ty = .slice_const_u8_sentinel_0_type, |
| 17380 | .ptr = try ip.get(gpa, .{ .ptr = .{ | ||
| 17381 | .ty = .manyptr_const_u8_sentinel_0_type, | ||
| 17382 | .addr = .{ .anon_decl = .{ | ||
| 17383 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 17384 | .val = try ip.get(gpa, .{ .aggregate = .{ | ||
| 17385 | .ty = array_ty, | ||
| 17386 | .storage = .{ .bytes = bytes }, | ||
| 17387 | } }), | ||
| 17388 | } }, | ||
| 17389 | } }), | ||
| 17380 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), | 17390 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), |
| 17381 | .addr = .{ .anon_decl = .{ | ||
| 17382 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 17383 | .val = try ip.get(gpa, .{ .aggregate = .{ | ||
| 17384 | .ty = array_ty, | ||
| 17385 | .storage = .{ .bytes = bytes }, | ||
| 17386 | } }), | ||
| 17387 | } }, | ||
| 17388 | } }); | 17391 | } }); |
| 17389 | }; | 17392 | }; |
| 17390 | 17393 | ||
| ... | @@ -17396,16 +17399,19 @@ fn zirBuiltinSrc( | ... | @@ -17396,16 +17399,19 @@ fn zirBuiltinSrc( |
| 17396 | .sentinel = .zero_u8, | 17399 | .sentinel = .zero_u8, |
| 17397 | .child = .u8_type, | 17400 | .child = .u8_type, |
| 17398 | } }); | 17401 | } }); |
| 17399 | break :v try ip.get(gpa, .{ .ptr = .{ | 17402 | break :v try ip.get(gpa, .{ .slice = .{ |
| 17400 | .ty = .slice_const_u8_sentinel_0_type, | 17403 | .ty = .slice_const_u8_sentinel_0_type, |
| 17404 | .ptr = try ip.get(gpa, .{ .ptr = .{ | ||
| 17405 | .ty = .manyptr_const_u8_sentinel_0_type, | ||
| 17406 | .addr = .{ .anon_decl = .{ | ||
| 17407 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 17408 | .val = try ip.get(gpa, .{ .aggregate = .{ | ||
| 17409 | .ty = array_ty, | ||
| 17410 | .storage = .{ .bytes = bytes }, | ||
| 17411 | } }), | ||
| 17412 | } }, | ||
| 17413 | } }), | ||
| 17401 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), | 17414 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), |
| 17402 | .addr = .{ .anon_decl = .{ | ||
| 17403 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 17404 | .val = try ip.get(gpa, .{ .aggregate = .{ | ||
| 17405 | .ty = array_ty, | ||
| 17406 | .storage = .{ .bytes = bytes }, | ||
| 17407 | } }), | ||
| 17408 | } }, | ||
| 17409 | } }); | 17415 | } }); |
| 17410 | }; | 17416 | }; |
| 17411 | 17417 | ||
| ... | @@ -17517,12 +17523,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17517,12 +17523,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17517 | .is_const = true, | 17523 | .is_const = true, |
| 17518 | }, | 17524 | }, |
| 17519 | })).toIntern(); | 17525 | })).toIntern(); |
| 17520 | break :v try mod.intern(.{ .ptr = .{ | 17526 | break :v try mod.intern(.{ .slice = .{ |
| 17521 | .ty = ptr_ty, | 17527 | .ty = ptr_ty, |
| 17522 | .addr = .{ .anon_decl = .{ | 17528 | .ptr = try mod.intern(.{ .ptr = .{ |
| 17523 | .orig_ty = ptr_ty, | 17529 | .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(), |
| 17524 | .val = new_decl_val, | 17530 | .addr = .{ .anon_decl = .{ |
| 17525 | } }, | 17531 | .orig_ty = ptr_ty, |
| 17532 | .val = new_decl_val, | ||
| 17533 | } }, | ||
| 17534 | } }), | ||
| 17526 | .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(), | 17535 | .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(), |
| 17527 | } }); | 17536 | } }); |
| 17528 | }; | 17537 | }; |
| ... | @@ -17796,12 +17805,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17796,12 +17805,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17796 | .ty = new_decl_ty.toIntern(), | 17805 | .ty = new_decl_ty.toIntern(), |
| 17797 | .storage = .{ .bytes = name }, | 17806 | .storage = .{ .bytes = name }, |
| 17798 | } }); | 17807 | } }); |
| 17799 | break :v try mod.intern(.{ .ptr = .{ | 17808 | break :v try mod.intern(.{ .slice = .{ |
| 17800 | .ty = .slice_const_u8_sentinel_0_type, | 17809 | .ty = .slice_const_u8_sentinel_0_type, |
| 17801 | .addr = .{ .anon_decl = .{ | 17810 | .ptr = try mod.intern(.{ .ptr = .{ |
| 17802 | .val = new_decl_val, | 17811 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17803 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17812 | .addr = .{ .anon_decl = .{ |
| 17804 | } }, | 17813 | .val = new_decl_val, |
| 17814 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 17815 | } }, | ||
| 17816 | } }), | ||
| 17805 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), | 17817 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 17806 | } }); | 17818 | } }); |
| 17807 | }; | 17819 | }; |
| ... | @@ -17838,12 +17850,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17838,12 +17850,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17838 | .ty = array_errors_ty.toIntern(), | 17850 | .ty = array_errors_ty.toIntern(), |
| 17839 | .storage = .{ .elems = vals }, | 17851 | .storage = .{ .elems = vals }, |
| 17840 | } }); | 17852 | } }); |
| 17841 | break :v try mod.intern(.{ .ptr = .{ | 17853 | break :v try mod.intern(.{ .slice = .{ |
| 17842 | .ty = slice_errors_ty.toIntern(), | 17854 | .ty = slice_errors_ty.toIntern(), |
| 17843 | .addr = .{ .anon_decl = .{ | 17855 | .ptr = try mod.intern(.{ .ptr = .{ |
| 17844 | .orig_ty = slice_errors_ty.toIntern(), | 17856 | .ty = slice_errors_ty.slicePtrFieldType(mod).toIntern(), |
| 17845 | .val = new_decl_val, | 17857 | .addr = .{ .anon_decl = .{ |
| 17846 | } }, | 17858 | .orig_ty = slice_errors_ty.toIntern(), |
| 17859 | .val = new_decl_val, | ||
| 17860 | } }, | ||
| 17861 | } }), | ||
| 17847 | .len = (try mod.intValue(Type.usize, vals.len)).toIntern(), | 17862 | .len = (try mod.intValue(Type.usize, vals.len)).toIntern(), |
| 17848 | } }); | 17863 | } }); |
| 17849 | } else .none; | 17864 | } else .none; |
| ... | @@ -17925,12 +17940,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17925,12 +17940,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17925 | .ty = new_decl_ty.toIntern(), | 17940 | .ty = new_decl_ty.toIntern(), |
| 17926 | .storage = .{ .bytes = name }, | 17941 | .storage = .{ .bytes = name }, |
| 17927 | } }); | 17942 | } }); |
| 17928 | break :v try mod.intern(.{ .ptr = .{ | 17943 | break :v try mod.intern(.{ .slice = .{ |
| 17929 | .ty = .slice_const_u8_sentinel_0_type, | 17944 | .ty = .slice_const_u8_sentinel_0_type, |
| 17930 | .addr = .{ .anon_decl = .{ | 17945 | .ptr = try mod.intern(.{ .ptr = .{ |
| 17931 | .val = new_decl_val, | 17946 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17932 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17947 | .addr = .{ .anon_decl = .{ |
| 17933 | } }, | 17948 | .val = new_decl_val, |
| 17949 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 17950 | } }, | ||
| 17951 | } }), | ||
| 17934 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), | 17952 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 17935 | } }); | 17953 | } }); |
| 17936 | }; | 17954 | }; |
| ... | @@ -17963,12 +17981,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17963,12 +17981,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17963 | .is_const = true, | 17981 | .is_const = true, |
| 17964 | }, | 17982 | }, |
| 17965 | })).toIntern(); | 17983 | })).toIntern(); |
| 17966 | break :v try mod.intern(.{ .ptr = .{ | 17984 | break :v try mod.intern(.{ .slice = .{ |
| 17967 | .ty = ptr_ty, | 17985 | .ty = ptr_ty, |
| 17968 | .addr = .{ .anon_decl = .{ | 17986 | .ptr = try mod.intern(.{ .ptr = .{ |
| 17969 | .val = new_decl_val, | 17987 | .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(), |
| 17970 | .orig_ty = ptr_ty, | 17988 | .addr = .{ .anon_decl = .{ |
| 17971 | } }, | 17989 | .val = new_decl_val, |
| 17990 | .orig_ty = ptr_ty, | ||
| 17991 | } }, | ||
| 17992 | } }), | ||
| 17972 | .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(), | 17993 | .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(), |
| 17973 | } }); | 17994 | } }); |
| 17974 | }; | 17995 | }; |
| ... | @@ -18051,12 +18072,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18051,12 +18072,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18051 | .ty = new_decl_ty.toIntern(), | 18072 | .ty = new_decl_ty.toIntern(), |
| 18052 | .storage = .{ .bytes = name }, | 18073 | .storage = .{ .bytes = name }, |
| 18053 | } }); | 18074 | } }); |
| 18054 | break :v try mod.intern(.{ .ptr = .{ | 18075 | break :v try mod.intern(.{ .slice = .{ |
| 18055 | .ty = .slice_const_u8_sentinel_0_type, | 18076 | .ty = .slice_const_u8_sentinel_0_type, |
| 18056 | .addr = .{ .anon_decl = .{ | 18077 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18057 | .val = new_decl_val, | 18078 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18058 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18079 | .addr = .{ .anon_decl = .{ |
| 18059 | } }, | 18080 | .val = new_decl_val, |
| 18081 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 18082 | } }, | ||
| 18083 | } }), | ||
| 18060 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), | 18084 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 18061 | } }); | 18085 | } }); |
| 18062 | }; | 18086 | }; |
| ... | @@ -18097,12 +18121,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18097,12 +18121,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18097 | .is_const = true, | 18121 | .is_const = true, |
| 18098 | }, | 18122 | }, |
| 18099 | })).toIntern(); | 18123 | })).toIntern(); |
| 18100 | break :v try mod.intern(.{ .ptr = .{ | 18124 | break :v try mod.intern(.{ .slice = .{ |
| 18101 | .ty = ptr_ty, | 18125 | .ty = ptr_ty, |
| 18102 | .addr = .{ .anon_decl = .{ | 18126 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18103 | .orig_ty = ptr_ty, | 18127 | .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(), |
| 18104 | .val = new_decl_val, | 18128 | .addr = .{ .anon_decl = .{ |
| 18105 | } }, | 18129 | .orig_ty = ptr_ty, |
| 18130 | .val = new_decl_val, | ||
| 18131 | } }, | ||
| 18132 | } }), | ||
| 18106 | .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(), | 18133 | .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(), |
| 18107 | } }); | 18134 | } }); |
| 18108 | }; | 18135 | }; |
| ... | @@ -18199,12 +18226,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18199,12 +18226,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18199 | .ty = new_decl_ty.toIntern(), | 18226 | .ty = new_decl_ty.toIntern(), |
| 18200 | .storage = .{ .bytes = bytes }, | 18227 | .storage = .{ .bytes = bytes }, |
| 18201 | } }); | 18228 | } }); |
| 18202 | break :v try mod.intern(.{ .ptr = .{ | 18229 | break :v try mod.intern(.{ .slice = .{ |
| 18203 | .ty = .slice_const_u8_sentinel_0_type, | 18230 | .ty = .slice_const_u8_sentinel_0_type, |
| 18204 | .addr = .{ .anon_decl = .{ | 18231 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18205 | .val = new_decl_val, | 18232 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18206 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18233 | .addr = .{ .anon_decl = .{ |
| 18207 | } }, | 18234 | .val = new_decl_val, |
| 18235 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 18236 | } }, | ||
| 18237 | } }), | ||
| 18208 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), | 18238 | .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(), |
| 18209 | } }); | 18239 | } }); |
| 18210 | }; | 18240 | }; |
| ... | @@ -18259,12 +18289,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18259,12 +18289,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18259 | .ty = new_decl_ty.toIntern(), | 18289 | .ty = new_decl_ty.toIntern(), |
| 18260 | .storage = .{ .bytes = name }, | 18290 | .storage = .{ .bytes = name }, |
| 18261 | } }); | 18291 | } }); |
| 18262 | break :v try mod.intern(.{ .ptr = .{ | 18292 | break :v try mod.intern(.{ .slice = .{ |
| 18263 | .ty = .slice_const_u8_sentinel_0_type, | 18293 | .ty = .slice_const_u8_sentinel_0_type, |
| 18264 | .addr = .{ .anon_decl = .{ | 18294 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18265 | .val = new_decl_val, | 18295 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18266 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18296 | .addr = .{ .anon_decl = .{ |
| 18267 | } }, | 18297 | .val = new_decl_val, |
| 18298 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 18299 | } }, | ||
| 18300 | } }), | ||
| 18268 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), | 18301 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 18269 | } }); | 18302 | } }); |
| 18270 | }; | 18303 | }; |
| ... | @@ -18315,12 +18348,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18315,12 +18348,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18315 | .is_const = true, | 18348 | .is_const = true, |
| 18316 | }, | 18349 | }, |
| 18317 | })).toIntern(); | 18350 | })).toIntern(); |
| 18318 | break :v try mod.intern(.{ .ptr = .{ | 18351 | break :v try mod.intern(.{ .slice = .{ |
| 18319 | .ty = ptr_ty, | 18352 | .ty = ptr_ty, |
| 18320 | .addr = .{ .anon_decl = .{ | 18353 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18321 | .orig_ty = ptr_ty, | 18354 | .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(), |
| 18322 | .val = new_decl_val, | 18355 | .addr = .{ .anon_decl = .{ |
| 18323 | } }, | 18356 | .orig_ty = ptr_ty, |
| 18357 | .val = new_decl_val, | ||
| 18358 | } }, | ||
| 18359 | } }), | ||
| 18324 | .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(), | 18360 | .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(), |
| 18325 | } }); | 18361 | } }); |
| 18326 | }; | 18362 | }; |
| ... | @@ -18453,12 +18489,15 @@ fn typeInfoDecls( | ... | @@ -18453,12 +18489,15 @@ fn typeInfoDecls( |
| 18453 | .is_const = true, | 18489 | .is_const = true, |
| 18454 | }, | 18490 | }, |
| 18455 | })).toIntern(); | 18491 | })).toIntern(); |
| 18456 | return try mod.intern(.{ .ptr = .{ | 18492 | return try mod.intern(.{ .slice = .{ |
| 18457 | .ty = ptr_ty, | 18493 | .ty = ptr_ty, |
| 18458 | .addr = .{ .anon_decl = .{ | 18494 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18459 | .orig_ty = ptr_ty, | 18495 | .ty = Type.fromInterned(ptr_ty).slicePtrFieldType(mod).toIntern(), |
| 18460 | .val = new_decl_val, | 18496 | .addr = .{ .anon_decl = .{ |
| 18461 | } }, | 18497 | .orig_ty = ptr_ty, |
| 18498 | .val = new_decl_val, | ||
| 18499 | } }, | ||
| 18500 | } }), | ||
| 18462 | .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(), | 18501 | .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(), |
| 18463 | } }); | 18502 | } }); |
| 18464 | } | 18503 | } |
| ... | @@ -18498,12 +18537,15 @@ fn typeInfoNamespaceDecls( | ... | @@ -18498,12 +18537,15 @@ fn typeInfoNamespaceDecls( |
| 18498 | .ty = new_decl_ty.toIntern(), | 18537 | .ty = new_decl_ty.toIntern(), |
| 18499 | .storage = .{ .bytes = name }, | 18538 | .storage = .{ .bytes = name }, |
| 18500 | } }); | 18539 | } }); |
| 18501 | break :v try mod.intern(.{ .ptr = .{ | 18540 | break :v try mod.intern(.{ .slice = .{ |
| 18502 | .ty = .slice_const_u8_sentinel_0_type, | 18541 | .ty = .slice_const_u8_sentinel_0_type, |
| 18503 | .addr = .{ .anon_decl = .{ | 18542 | .ptr = try mod.intern(.{ .ptr = .{ |
| 18504 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18543 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18505 | .val = new_decl_val, | 18544 | .addr = .{ .anon_decl = .{ |
| 18506 | } }, | 18545 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 18546 | .val = new_decl_val, | ||
| 18547 | } }, | ||
| 18548 | } }), | ||
| 18507 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), | 18549 | .len = (try mod.intValue(Type.usize, name.len)).toIntern(), |
| 18508 | } }); | 18550 | } }); |
| 18509 | }; | 18551 | }; |
| ... | @@ -22738,9 +22780,12 @@ fn ptrCastFull( | ... | @@ -22738,9 +22780,12 @@ fn ptrCastFull( |
| 22738 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { | 22780 | if (dest_info.flags.size == .Slice and src_info.flags.size != .Slice) { |
| 22739 | if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty); | 22781 | if (ptr_val.isUndef(mod)) return mod.undefRef(dest_ty); |
| 22740 | const arr_len = try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod)); | 22782 | const arr_len = try mod.intValue(Type.usize, Type.fromInterned(src_info.child).arrayLen(mod)); |
| 22741 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ | 22783 | return Air.internedToRef((try mod.intern(.{ .slice = .{ |
| 22742 | .ty = dest_ty.toIntern(), | 22784 | .ty = dest_ty.toIntern(), |
| 22743 | .addr = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr, | 22785 | .ptr = try mod.intern(.{ .ptr = .{ |
| 22786 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), | ||
| 22787 | .addr = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr, | ||
| 22788 | } }), | ||
| 22744 | .len = arr_len.toIntern(), | 22789 | .len = arr_len.toIntern(), |
| 22745 | } }))); | 22790 | } }))); |
| 22746 | } else { | 22791 | } else { |
| ... | @@ -28765,21 +28810,24 @@ fn coerceExtra( | ... | @@ -28765,21 +28810,24 @@ fn coerceExtra( |
| 28765 | if (inst_child_ty.structFieldCount(mod) == 0) { | 28810 | if (inst_child_ty.structFieldCount(mod) == 0) { |
| 28766 | // Optional slice is represented with a null pointer so | 28811 | // Optional slice is represented with a null pointer so |
| 28767 | // we use a dummy pointer value with the required alignment. | 28812 | // we use a dummy pointer value with the required alignment. |
| 28768 | return Air.internedToRef((try mod.intern(.{ .ptr = .{ | 28813 | return Air.internedToRef((try mod.intern(.{ .slice = .{ |
| 28769 | .ty = dest_ty.toIntern(), | 28814 | .ty = dest_ty.toIntern(), |
| 28770 | .addr = .{ .int = if (dest_info.flags.alignment != .none) | 28815 | .ptr = try mod.intern(.{ .ptr = .{ |
| 28771 | (try mod.intValue( | 28816 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), |
| 28772 | Type.usize, | 28817 | .addr = .{ .int = if (dest_info.flags.alignment != .none) |
| 28773 | dest_info.flags.alignment.toByteUnitsOptional().?, | 28818 | (try mod.intValue( |
| 28774 | )).toIntern() | 28819 | Type.usize, |
| 28775 | else | 28820 | dest_info.flags.alignment.toByteUnitsOptional().?, |
| 28776 | try mod.intern_pool.getCoercedInts( | 28821 | )).toIntern() |
| 28777 | mod.gpa, | 28822 | else |
| 28778 | mod.intern_pool.indexToKey( | 28823 | try mod.intern_pool.getCoercedInts( |
| 28779 | (try Type.fromInterned(dest_info.child).lazyAbiAlignment(mod)).toIntern(), | 28824 | mod.gpa, |
| 28780 | ).int, | 28825 | mod.intern_pool.indexToKey( |
| 28781 | .usize_type, | 28826 | (try Type.fromInterned(dest_info.child).lazyAbiAlignment(mod)).toIntern(), |
| 28782 | ) }, | 28827 | ).int, |
| 28828 | .usize_type, | ||
| 28829 | ) }, | ||
| 28830 | } }), | ||
| 28783 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), | 28831 | .len = (try mod.intValue(Type.usize, 0)).toIntern(), |
| 28784 | } }))); | 28832 | } }))); |
| 28785 | } | 28833 | } |
| ... | @@ -31276,7 +31324,7 @@ fn beginComptimePtrLoad( | ... | @@ -31276,7 +31324,7 @@ fn beginComptimePtrLoad( |
| 31276 | }, | 31324 | }, |
| 31277 | Value.slice_len_index => TypedValue{ | 31325 | Value.slice_len_index => TypedValue{ |
| 31278 | .ty = Type.usize, | 31326 | .ty = Type.usize, |
| 31279 | .val = Value.fromInterned(ip.indexToKey(try tv.val.intern(tv.ty, mod)).ptr.len), | 31327 | .val = Value.fromInterned(ip.indexToKey(try tv.val.intern(tv.ty, mod)).slice.len), |
| 31280 | }, | 31328 | }, |
| 31281 | else => unreachable, | 31329 | else => unreachable, |
| 31282 | }; | 31330 | }; |
| ... | @@ -31445,13 +31493,16 @@ fn coerceArrayPtrToSlice( | ... | @@ -31445,13 +31493,16 @@ fn coerceArrayPtrToSlice( |
| 31445 | if (try sema.resolveValue(inst)) |val| { | 31493 | if (try sema.resolveValue(inst)) |val| { |
| 31446 | const ptr_array_ty = sema.typeOf(inst); | 31494 | const ptr_array_ty = sema.typeOf(inst); |
| 31447 | const array_ty = ptr_array_ty.childType(mod); | 31495 | const array_ty = ptr_array_ty.childType(mod); |
| 31448 | const slice_val = try mod.intern(.{ .ptr = .{ | 31496 | const slice_val = try mod.intern(.{ .slice = .{ |
| 31449 | .ty = dest_ty.toIntern(), | 31497 | .ty = dest_ty.toIntern(), |
| 31450 | .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) { | 31498 | .ptr = try mod.intern(.{ .ptr = .{ |
| 31451 | .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) }, | 31499 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), |
| 31452 | .ptr => |ptr| ptr.addr, | 31500 | .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 31453 | else => unreachable, | 31501 | .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) }, |
| 31454 | }, | 31502 | .ptr => |ptr| ptr.addr, |
| 31503 | else => unreachable, | ||
| 31504 | }, | ||
| 31505 | } }), | ||
| 31455 | .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), | 31506 | .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), |
| 31456 | } }); | 31507 | } }); |
| 31457 | return Air.internedToRef(slice_val); | 31508 | return Air.internedToRef(slice_val); |
| ... | @@ -35211,51 +35262,43 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { | ... | @@ -35211,51 +35262,43 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { |
| 35211 | (try val.getUnsignedIntAdvanced(mod, sema)).?, | 35262 | (try val.getUnsignedIntAdvanced(mod, sema)).?, |
| 35212 | ), | 35263 | ), |
| 35213 | }, | 35264 | }, |
| 35265 | .slice => |slice| { | ||
| 35266 | const ptr = try sema.resolveLazyValue(Value.fromInterned(slice.ptr)); | ||
| 35267 | const len = try sema.resolveLazyValue(Value.fromInterned(slice.len)); | ||
| 35268 | if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val; | ||
| 35269 | return Value.fromInterned(try mod.intern(.{ .slice = .{ | ||
| 35270 | .ty = slice.ty, | ||
| 35271 | .ptr = ptr.toIntern(), | ||
| 35272 | .len = len.toIntern(), | ||
| 35273 | } })); | ||
| 35274 | }, | ||
| 35214 | .ptr => |ptr| { | 35275 | .ptr => |ptr| { |
| 35215 | const resolved_len = switch (ptr.len) { | ||
| 35216 | .none => .none, | ||
| 35217 | else => (try sema.resolveLazyValue(Value.fromInterned(ptr.len))).toIntern(), | ||
| 35218 | }; | ||
| 35219 | switch (ptr.addr) { | 35276 | switch (ptr.addr) { |
| 35220 | .decl, .mut_decl, .anon_decl => return if (resolved_len == ptr.len) | 35277 | .decl, .mut_decl, .anon_decl => return val, |
| 35221 | val | ||
| 35222 | else | ||
| 35223 | Value.fromInterned((try mod.intern(.{ .ptr = .{ | ||
| 35224 | .ty = ptr.ty, | ||
| 35225 | .addr = switch (ptr.addr) { | ||
| 35226 | .decl => |decl| .{ .decl = decl }, | ||
| 35227 | .mut_decl => |mut_decl| .{ .mut_decl = mut_decl }, | ||
| 35228 | .anon_decl => |anon_decl| .{ .anon_decl = anon_decl }, | ||
| 35229 | else => unreachable, | ||
| 35230 | }, | ||
| 35231 | .len = resolved_len, | ||
| 35232 | } }))), | ||
| 35233 | .comptime_field => |field_val| { | 35278 | .comptime_field => |field_val| { |
| 35234 | const resolved_field_val = | 35279 | const resolved_field_val = |
| 35235 | (try sema.resolveLazyValue(Value.fromInterned(field_val))).toIntern(); | 35280 | (try sema.resolveLazyValue(Value.fromInterned(field_val))).toIntern(); |
| 35236 | return if (resolved_field_val == field_val and resolved_len == ptr.len) | 35281 | return if (resolved_field_val == field_val) |
| 35237 | val | 35282 | val |
| 35238 | else | 35283 | else |
| 35239 | Value.fromInterned((try mod.intern(.{ .ptr = .{ | 35284 | Value.fromInterned((try mod.intern(.{ .ptr = .{ |
| 35240 | .ty = ptr.ty, | 35285 | .ty = ptr.ty, |
| 35241 | .addr = .{ .comptime_field = resolved_field_val }, | 35286 | .addr = .{ .comptime_field = resolved_field_val }, |
| 35242 | .len = resolved_len, | ||
| 35243 | } }))); | 35287 | } }))); |
| 35244 | }, | 35288 | }, |
| 35245 | .int => |int| { | 35289 | .int => |int| { |
| 35246 | const resolved_int = (try sema.resolveLazyValue(Value.fromInterned(int))).toIntern(); | 35290 | const resolved_int = (try sema.resolveLazyValue(Value.fromInterned(int))).toIntern(); |
| 35247 | return if (resolved_int == int and resolved_len == ptr.len) | 35291 | return if (resolved_int == int) |
| 35248 | val | 35292 | val |
| 35249 | else | 35293 | else |
| 35250 | Value.fromInterned((try mod.intern(.{ .ptr = .{ | 35294 | Value.fromInterned((try mod.intern(.{ .ptr = .{ |
| 35251 | .ty = ptr.ty, | 35295 | .ty = ptr.ty, |
| 35252 | .addr = .{ .int = resolved_int }, | 35296 | .addr = .{ .int = resolved_int }, |
| 35253 | .len = resolved_len, | ||
| 35254 | } }))); | 35297 | } }))); |
| 35255 | }, | 35298 | }, |
| 35256 | .eu_payload, .opt_payload => |base| { | 35299 | .eu_payload, .opt_payload => |base| { |
| 35257 | const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base))).toIntern(); | 35300 | const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base))).toIntern(); |
| 35258 | return if (resolved_base == base and resolved_len == ptr.len) | 35301 | return if (resolved_base == base) |
| 35259 | val | 35302 | val |
| 35260 | else | 35303 | else |
| 35261 | Value.fromInterned((try mod.intern(.{ .ptr = .{ | 35304 | Value.fromInterned((try mod.intern(.{ .ptr = .{ |
| ... | @@ -35265,12 +35308,11 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { | ... | @@ -35265,12 +35308,11 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { |
| 35265 | .opt_payload => .{ .opt_payload = resolved_base }, | 35308 | .opt_payload => .{ .opt_payload = resolved_base }, |
| 35266 | else => unreachable, | 35309 | else => unreachable, |
| 35267 | }, | 35310 | }, |
| 35268 | .len = ptr.len, | ||
| 35269 | } }))); | 35311 | } }))); |
| 35270 | }, | 35312 | }, |
| 35271 | .elem, .field => |base_index| { | 35313 | .elem, .field => |base_index| { |
| 35272 | const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base_index.base))).toIntern(); | 35314 | const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base_index.base))).toIntern(); |
| 35273 | return if (resolved_base == base_index.base and resolved_len == ptr.len) | 35315 | return if (resolved_base == base_index.base) |
| 35274 | val | 35316 | val |
| 35275 | else | 35317 | else |
| 35276 | Value.fromInterned((try mod.intern(.{ .ptr = .{ | 35318 | Value.fromInterned((try mod.intern(.{ .ptr = .{ |
| ... | @@ -35286,7 +35328,6 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { | ... | @@ -35286,7 +35328,6 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { |
| 35286 | } }, | 35328 | } }, |
| 35287 | else => unreachable, | 35329 | else => unreachable, |
| 35288 | }, | 35330 | }, |
| 35289 | .len = ptr.len, | ||
| 35290 | } }))); | 35331 | } }))); |
| 35291 | }, | 35332 | }, |
| 35292 | } | 35333 | } |
src/TypedValue.zig+46-42| ... | @@ -264,52 +264,56 @@ pub fn print( | ... | @@ -264,52 +264,56 @@ pub fn print( |
| 264 | .float => |float| switch (float.storage) { | 264 | .float => |float| switch (float.storage) { |
| 265 | inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}), | 265 | inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}), |
| 266 | }, | 266 | }, |
| 267 | .ptr => |ptr| { | 267 | .slice => |slice| { |
| 268 | if (ptr.addr == .int) { | 268 | const ptr_ty = switch (ip.indexToKey(slice.ptr)) { |
| 269 | switch (ip.indexToKey(ptr.addr.int)) { | 269 | .ptr => |ptr| ty: { |
| 270 | .int => |i| switch (i.storage) { | 270 | if (ptr.addr == .int) return print(.{ |
| 271 | inline else => |addr| return writer.print("{x:0>8}", .{addr}), | 271 | .ty = Type.fromInterned(ptr.ty), |
| 272 | }, | 272 | .val = Value.fromInterned(slice.ptr), |
| 273 | .undef => return writer.writeAll("undefined"), | 273 | }, writer, level - 1, mod); |
| 274 | else => unreachable, | 274 | break :ty ip.indexToKey(ptr.ty).ptr_type; |
| 275 | } | 275 | }, |
| 276 | .undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type, | ||
| 277 | else => unreachable, | ||
| 278 | }; | ||
| 279 | if (level == 0) { | ||
| 280 | return writer.writeAll(".{ ... }"); | ||
| 276 | } | 281 | } |
| 277 | 282 | const elem_ty = Type.fromInterned(ptr_ty.child); | |
| 278 | const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type; | 283 | const len = Value.fromInterned(slice.len).toUnsignedInt(mod); |
| 279 | if (ptr_ty.flags.size == .Slice) { | 284 | if (elem_ty.eql(Type.u8, mod)) str: { |
| 280 | if (level == 0) { | 285 | const max_len = @min(len, max_string_len); |
| 281 | return writer.writeAll(".{ ... }"); | 286 | var buf: [max_string_len]u8 = undefined; |
| 282 | } | 287 | for (buf[0..max_len], 0..) |*c, i| { |
| 283 | const elem_ty = Type.fromInterned(ptr_ty.child); | ||
| 284 | const len = Value.fromInterned(ptr.len).toUnsignedInt(mod); | ||
| 285 | if (elem_ty.eql(Type.u8, mod)) str: { | ||
| 286 | const max_len = @min(len, max_string_len); | ||
| 287 | var buf: [max_string_len]u8 = undefined; | ||
| 288 | for (buf[0..max_len], 0..) |*c, i| { | ||
| 289 | const maybe_elem = try val.maybeElemValue(mod, i); | ||
| 290 | const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }"); | ||
| 291 | if (elem.isUndef(mod)) break :str; | ||
| 292 | c.* = @as(u8, @intCast(elem.toUnsignedInt(mod))); | ||
| 293 | } | ||
| 294 | const truncated = if (len > max_string_len) " (truncated)" else ""; | ||
| 295 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); | ||
| 296 | } | ||
| 297 | try writer.writeAll(".{ "); | ||
| 298 | const max_len = @min(len, max_aggregate_items); | ||
| 299 | for (0..max_len) |i| { | ||
| 300 | if (i != 0) try writer.writeAll(", "); | ||
| 301 | const maybe_elem = try val.maybeElemValue(mod, i); | 288 | const maybe_elem = try val.maybeElemValue(mod, i); |
| 302 | const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }"); | 289 | const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }"); |
| 303 | try print(.{ | 290 | if (elem.isUndef(mod)) break :str; |
| 304 | .ty = elem_ty, | 291 | c.* = @as(u8, @intCast(elem.toUnsignedInt(mod))); |
| 305 | .val = elem, | ||
| 306 | }, writer, level - 1, mod); | ||
| 307 | } | ||
| 308 | if (len > max_aggregate_items) { | ||
| 309 | try writer.writeAll(", ..."); | ||
| 310 | } | 292 | } |
| 311 | return writer.writeAll(" }"); | 293 | const truncated = if (len > max_string_len) " (truncated)" else ""; |
| 294 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); | ||
| 295 | } | ||
| 296 | try writer.writeAll(".{ "); | ||
| 297 | const max_len = @min(len, max_aggregate_items); | ||
| 298 | for (0..max_len) |i| { | ||
| 299 | if (i != 0) try writer.writeAll(", "); | ||
| 300 | const maybe_elem = try val.maybeElemValue(mod, i); | ||
| 301 | const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }"); | ||
| 302 | try print(.{ | ||
| 303 | .ty = elem_ty, | ||
| 304 | .val = elem, | ||
| 305 | }, writer, level - 1, mod); | ||
| 312 | } | 306 | } |
| 307 | if (len > max_aggregate_items) { | ||
| 308 | try writer.writeAll(", ..."); | ||
| 309 | } | ||
| 310 | return writer.writeAll(" }"); | ||
| 311 | }, | ||
| 312 | .ptr => |ptr| { | ||
| 313 | if (ptr.addr == .int) {} | ||
| 314 | |||
| 315 | const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type; | ||
| 316 | if (ptr_ty.flags.size == .Slice) {} | ||
| 313 | 317 | ||
| 314 | switch (ptr.addr) { | 318 | switch (ptr.addr) { |
| 315 | .decl => |decl_index| { | 319 | .decl => |decl_index| { |
src/arch/wasm/CodeGen.zig+12-3| ... | @@ -3179,9 +3179,6 @@ fn lowerAnonDeclRef( | ... | @@ -3179,9 +3179,6 @@ fn lowerAnonDeclRef( |
| 3179 | 3179 | ||
| 3180 | fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { | 3180 | fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { |
| 3181 | const mod = func.bin_file.base.comp.module.?; | 3181 | const mod = func.bin_file.base.comp.module.?; |
| 3182 | if (tv.ty.isSlice(mod)) { | ||
| 3183 | return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) }; | ||
| 3184 | } | ||
| 3185 | 3182 | ||
| 3186 | const decl = mod.declPtr(decl_index); | 3183 | const decl = mod.declPtr(decl_index); |
| 3187 | // check if decl is an alias to a function, in which case we | 3184 | // check if decl is an alias to a function, in which case we |
| ... | @@ -3335,6 +3332,18 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3335,6 +3332,18 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3335 | .f64 => |f64_val| return WValue{ .float64 = f64_val }, | 3332 | .f64 => |f64_val| return WValue{ .float64 = f64_val }, |
| 3336 | else => unreachable, | 3333 | else => unreachable, |
| 3337 | }, | 3334 | }, |
| 3335 | .slice => |slice| { | ||
| 3336 | var ptr = ip.indexToKey(slice.ptr).ptr; | ||
| 3337 | const owner_decl = while (true) switch (ptr.addr) { | ||
| 3338 | .decl => |decl| break decl, | ||
| 3339 | .mut_decl => |mut_decl| break mut_decl.decl, | ||
| 3340 | .int, .anon_decl => return func.fail("Wasm TODO: lower slice where ptr is not owned by decl", .{}), | ||
| 3341 | .opt_payload, .eu_payload => |base| ptr = ip.indexToKey(base).ptr, | ||
| 3342 | .elem, .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr, | ||
| 3343 | .comptime_field => unreachable, | ||
| 3344 | }; | ||
| 3345 | return .{ .memory = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, owner_decl) }; | ||
| 3346 | }, | ||
| 3338 | .ptr => |ptr| switch (ptr.addr) { | 3347 | .ptr => |ptr| switch (ptr.addr) { |
| 3339 | .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0), | 3348 | .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0), |
| 3340 | .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0), | 3349 | .mut_decl => |mut_decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, mut_decl.decl, 0), |
src/codegen.zig+15-16| ... | @@ -322,24 +322,24 @@ pub fn generateSymbol( | ... | @@ -322,24 +322,24 @@ pub fn generateSymbol( |
| 322 | }, | 322 | }, |
| 323 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), | 323 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), |
| 324 | }, | 324 | }, |
| 325 | .ptr => |ptr| { | 325 | .ptr => switch (try lowerParentPtr(bin_file, src_loc, typed_value.val.toIntern(), code, debug_output, reloc_info)) { |
| 326 | // generate ptr | 326 | .ok => {}, |
| 327 | switch (try lowerParentPtr(bin_file, src_loc, switch (ptr.len) { | 327 | .fail => |em| return .{ .fail = em }, |
| 328 | .none => typed_value.val, | 328 | }, |
| 329 | else => typed_value.val.slicePtr(mod), | 329 | .slice => |slice| { |
| 330 | }.toIntern(), code, debug_output, reloc_info)) { | 330 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 331 | .ty = typed_value.ty.slicePtrFieldType(mod), | ||
| 332 | .val = Value.fromInterned(slice.ptr), | ||
| 333 | }, code, debug_output, reloc_info)) { | ||
| 331 | .ok => {}, | 334 | .ok => {}, |
| 332 | .fail => |em| return .{ .fail = em }, | 335 | .fail => |em| return .{ .fail = em }, |
| 333 | } | 336 | } |
| 334 | if (ptr.len != .none) { | 337 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 335 | // generate len | 338 | .ty = Type.usize, |
| 336 | switch (try generateSymbol(bin_file, src_loc, .{ | 339 | .val = Value.fromInterned(slice.len), |
| 337 | .ty = Type.usize, | 340 | }, code, debug_output, reloc_info)) { |
| 338 | .val = Value.fromInterned(ptr.len), | 341 | .ok => {}, |
| 339 | }, code, debug_output, reloc_info)) { | 342 | .fail => |em| return .{ .fail = em }, |
| 340 | .ok => {}, | ||
| 341 | .fail => |em| return Result{ .fail = em }, | ||
| 342 | } | ||
| 343 | } | 343 | } |
| 344 | }, | 344 | }, |
| 345 | .opt => { | 345 | .opt => { |
| ... | @@ -676,7 +676,6 @@ fn lowerParentPtr( | ... | @@ -676,7 +676,6 @@ fn lowerParentPtr( |
| 676 | ) CodeGenError!Result { | 676 | ) CodeGenError!Result { |
| 677 | const mod = bin_file.comp.module.?; | 677 | const mod = bin_file.comp.module.?; |
| 678 | const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr; | 678 | const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr; |
| 679 | assert(ptr.len == .none); | ||
| 680 | return switch (ptr.addr) { | 679 | return switch (ptr.addr) { |
| 681 | .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info), | 680 | .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info), |
| 682 | .mut_decl => |md| try lowerDeclRef(bin_file, src_loc, md.decl, code, debug_output, reloc_info), | 681 | .mut_decl => |md| try lowerDeclRef(bin_file, src_loc, md.decl, code, debug_output, reloc_info), |
src/codegen/c.zig+28-43| ... | @@ -1207,50 +1207,35 @@ pub const DeclGen = struct { | ... | @@ -1207,50 +1207,35 @@ pub const DeclGen = struct { |
| 1207 | try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)}); | 1207 | try writer.print("{x}", .{try dg.fmtIntLiteral(repr_ty, repr_val, location)}); |
| 1208 | if (!empty) try writer.writeByte(')'); | 1208 | if (!empty) try writer.writeByte(')'); |
| 1209 | }, | 1209 | }, |
| 1210 | .ptr => |ptr| { | 1210 | .slice => |slice| { |
| 1211 | if (ptr.len != .none) { | 1211 | if (!location.isInitializer()) { |
| 1212 | if (!location.isInitializer()) { | 1212 | try writer.writeByte('('); |
| 1213 | try writer.writeByte('('); | 1213 | try dg.renderType(writer, ty); |
| 1214 | try dg.renderType(writer, ty); | 1214 | try writer.writeByte(')'); |
| 1215 | try writer.writeByte(')'); | ||
| 1216 | } | ||
| 1217 | try writer.writeByte('{'); | ||
| 1218 | } | ||
| 1219 | const ptr_location = switch (ptr.len) { | ||
| 1220 | .none => location, | ||
| 1221 | else => initializer_type, | ||
| 1222 | }; | ||
| 1223 | const ptr_ty = switch (ptr.len) { | ||
| 1224 | .none => ty, | ||
| 1225 | else => ty.slicePtrFieldType(mod), | ||
| 1226 | }; | ||
| 1227 | const ptr_val = switch (ptr.len) { | ||
| 1228 | .none => val, | ||
| 1229 | else => val.slicePtr(mod), | ||
| 1230 | }; | ||
| 1231 | switch (ptr.addr) { | ||
| 1232 | .decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val, d, ptr_location), | ||
| 1233 | .mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val, md.decl, ptr_location), | ||
| 1234 | .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val, decl_val, ptr_location), | ||
| 1235 | .int => |int| { | ||
| 1236 | try writer.writeAll("(("); | ||
| 1237 | try dg.renderType(writer, ptr_ty); | ||
| 1238 | try writer.print("){x})", .{ | ||
| 1239 | try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), ptr_location), | ||
| 1240 | }); | ||
| 1241 | }, | ||
| 1242 | .eu_payload, | ||
| 1243 | .opt_payload, | ||
| 1244 | .elem, | ||
| 1245 | .field, | ||
| 1246 | => try dg.renderParentPtr(writer, ptr_val.ip_index, ptr_location), | ||
| 1247 | .comptime_field => unreachable, | ||
| 1248 | } | ||
| 1249 | if (ptr.len != .none) { | ||
| 1250 | try writer.writeAll(", "); | ||
| 1251 | try dg.renderValue(writer, Type.usize, Value.fromInterned(ptr.len), initializer_type); | ||
| 1252 | try writer.writeByte('}'); | ||
| 1253 | } | 1215 | } |
| 1216 | try writer.writeByte('{'); | ||
| 1217 | try dg.renderValue(writer, ty.slicePtrFieldType(mod), Value.fromInterned(slice.ptr), initializer_type); | ||
| 1218 | try writer.writeAll(", "); | ||
| 1219 | try dg.renderValue(writer, Type.usize, Value.fromInterned(slice.len), initializer_type); | ||
| 1220 | try writer.writeByte('}'); | ||
| 1221 | }, | ||
| 1222 | .ptr => |ptr| switch (ptr.addr) { | ||
| 1223 | .decl => |d| try dg.renderDeclValue(writer, ty, val, d, location), | ||
| 1224 | .mut_decl => |md| try dg.renderDeclValue(writer, ty, val, md.decl, location), | ||
| 1225 | .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ty, val, decl_val, location), | ||
| 1226 | .int => |int| { | ||
| 1227 | try writer.writeAll("(("); | ||
| 1228 | try dg.renderType(writer, ty); | ||
| 1229 | try writer.print("){x})", .{ | ||
| 1230 | try dg.fmtIntLiteral(Type.usize, Value.fromInterned(int), location), | ||
| 1231 | }); | ||
| 1232 | }, | ||
| 1233 | .eu_payload, | ||
| 1234 | .opt_payload, | ||
| 1235 | .elem, | ||
| 1236 | .field, | ||
| 1237 | => try dg.renderParentPtr(writer, val.ip_index, location), | ||
| 1238 | .comptime_field => unreachable, | ||
| 1254 | }, | 1239 | }, |
| 1255 | .opt => |opt| { | 1240 | .opt => |opt| { |
| 1256 | const payload_ty = ty.optionalChild(mod); | 1241 | const payload_ty = ty.optionalChild(mod); |
src/codegen/llvm.zig+16-23| ... | @@ -3644,6 +3644,7 @@ pub const Object = struct { | ... | @@ -3644,6 +3644,7 @@ pub const Object = struct { |
| 3644 | .empty_enum_value, | 3644 | .empty_enum_value, |
| 3645 | .float, | 3645 | .float, |
| 3646 | .ptr, | 3646 | .ptr, |
| 3647 | .slice, | ||
| 3647 | .opt, | 3648 | .opt, |
| 3648 | .aggregate, | 3649 | .aggregate, |
| 3649 | .un, | 3650 | .un, |
| ... | @@ -3872,30 +3873,22 @@ pub const Object = struct { | ... | @@ -3872,30 +3873,22 @@ pub const Object = struct { |
| 3872 | 128 => try o.builder.fp128Const(val.toFloat(f128, mod)), | 3873 | 128 => try o.builder.fp128Const(val.toFloat(f128, mod)), |
| 3873 | else => unreachable, | 3874 | else => unreachable, |
| 3874 | }, | 3875 | }, |
| 3875 | .ptr => |ptr| { | 3876 | .ptr => |ptr| return switch (ptr.addr) { |
| 3876 | const ptr_ty = switch (ptr.len) { | 3877 | .decl => |decl| try o.lowerDeclRefValue(ty, decl), |
| 3877 | .none => ty, | 3878 | .mut_decl => |mut_decl| try o.lowerDeclRefValue(ty, mut_decl.decl), |
| 3878 | else => ty.slicePtrFieldType(mod), | 3879 | .anon_decl => |anon_decl| try o.lowerAnonDeclRef(ty, anon_decl), |
| 3879 | }; | 3880 | .int => |int| try o.lowerIntAsPtr(int), |
| 3880 | const ptr_val = switch (ptr.addr) { | 3881 | .eu_payload, |
| 3881 | .decl => |decl| try o.lowerDeclRefValue(ptr_ty, decl), | 3882 | .opt_payload, |
| 3882 | .mut_decl => |mut_decl| try o.lowerDeclRefValue(ptr_ty, mut_decl.decl), | 3883 | .elem, |
| 3883 | .anon_decl => |anon_decl| try o.lowerAnonDeclRef(ptr_ty, anon_decl), | 3884 | .field, |
| 3884 | .int => |int| try o.lowerIntAsPtr(int), | 3885 | => try o.lowerParentPtr(val), |
| 3885 | .eu_payload, | 3886 | .comptime_field => unreachable, |
| 3886 | .opt_payload, | ||
| 3887 | .elem, | ||
| 3888 | .field, | ||
| 3889 | => try o.lowerParentPtr(val), | ||
| 3890 | .comptime_field => unreachable, | ||
| 3891 | }; | ||
| 3892 | switch (ptr.len) { | ||
| 3893 | .none => return ptr_val, | ||
| 3894 | else => return o.builder.structConst(try o.lowerType(ty), &.{ | ||
| 3895 | ptr_val, try o.lowerValue(ptr.len), | ||
| 3896 | }), | ||
| 3897 | } | ||
| 3898 | }, | 3887 | }, |
| 3888 | .slice => |slice| return o.builder.structConst(try o.lowerType(ty), &.{ | ||
| 3889 | try o.lowerValue(slice.ptr), | ||
| 3890 | try o.lowerValue(slice.len), | ||
| 3891 | }), | ||
| 3899 | .opt => |opt| { | 3892 | .opt => |opt| { |
| 3900 | comptime assert(optional_layout_version == 3); | 3893 | comptime assert(optional_layout_version == 3); |
| 3901 | const payload_ty = ty.optionalChild(mod); | 3894 | const payload_ty = ty.optionalChild(mod); |
src/codegen/spirv.zig+6-12| ... | @@ -855,18 +855,12 @@ const DeclGen = struct { | ... | @@ -855,18 +855,12 @@ const DeclGen = struct { |
| 855 | const int_ty = ty.intTagType(mod); | 855 | const int_ty = ty.intTagType(mod); |
| 856 | return try self.constant(int_ty, int_val, repr); | 856 | return try self.constant(int_ty, int_val, repr); |
| 857 | }, | 857 | }, |
| 858 | .ptr => |ptr| { | 858 | .ptr => return self.constantPtr(ty, val), |
| 859 | const ptr_ty = switch (ptr.len) { | 859 | .slice => |slice| { |
| 860 | .none => ty, | 860 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 861 | else => ty.slicePtrFieldType(mod), | 861 | const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr)); |
| 862 | }; | 862 | const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect); |
| 863 | const ptr_id = try self.constantPtr(ptr_ty, val); | 863 | return self.constructStruct( |
| 864 | if (ptr.len == .none) { | ||
| 865 | return ptr_id; | ||
| 866 | } | ||
| 867 | |||
| 868 | const len_id = try self.constant(Type.usize, Value.fromInterned(ptr.len), .indirect); | ||
| 869 | return try self.constructStruct( | ||
| 870 | ty, | 864 | ty, |
| 871 | &.{ ptr_ty, Type.usize }, | 865 | &.{ ptr_ty, Type.usize }, |
| 872 | &.{ ptr_id, len_id }, | 866 | &.{ ptr_id, len_id }, |
src/type.zig+9| ... | @@ -426,6 +426,7 @@ pub const Type = struct { | ... | @@ -426,6 +426,7 @@ pub const Type = struct { |
| 426 | .empty_enum_value, | 426 | .empty_enum_value, |
| 427 | .float, | 427 | .float, |
| 428 | .ptr, | 428 | .ptr, |
| 429 | .slice, | ||
| 429 | .opt, | 430 | .opt, |
| 430 | .aggregate, | 431 | .aggregate, |
| 431 | .un, | 432 | .un, |
| ... | @@ -651,6 +652,7 @@ pub const Type = struct { | ... | @@ -651,6 +652,7 @@ pub const Type = struct { |
| 651 | .empty_enum_value, | 652 | .empty_enum_value, |
| 652 | .float, | 653 | .float, |
| 653 | .ptr, | 654 | .ptr, |
| 655 | .slice, | ||
| 654 | .opt, | 656 | .opt, |
| 655 | .aggregate, | 657 | .aggregate, |
| 656 | .un, | 658 | .un, |
| ... | @@ -758,6 +760,7 @@ pub const Type = struct { | ... | @@ -758,6 +760,7 @@ pub const Type = struct { |
| 758 | .empty_enum_value, | 760 | .empty_enum_value, |
| 759 | .float, | 761 | .float, |
| 760 | .ptr, | 762 | .ptr, |
| 763 | .slice, | ||
| 761 | .opt, | 764 | .opt, |
| 762 | .aggregate, | 765 | .aggregate, |
| 763 | .un, | 766 | .un, |
| ... | @@ -1073,6 +1076,7 @@ pub const Type = struct { | ... | @@ -1073,6 +1076,7 @@ pub const Type = struct { |
| 1073 | .empty_enum_value, | 1076 | .empty_enum_value, |
| 1074 | .float, | 1077 | .float, |
| 1075 | .ptr, | 1078 | .ptr, |
| 1079 | .slice, | ||
| 1076 | .opt, | 1080 | .opt, |
| 1077 | .aggregate, | 1081 | .aggregate, |
| 1078 | .un, | 1082 | .un, |
| ... | @@ -1434,6 +1438,7 @@ pub const Type = struct { | ... | @@ -1434,6 +1438,7 @@ pub const Type = struct { |
| 1434 | .empty_enum_value, | 1438 | .empty_enum_value, |
| 1435 | .float, | 1439 | .float, |
| 1436 | .ptr, | 1440 | .ptr, |
| 1441 | .slice, | ||
| 1437 | .opt, | 1442 | .opt, |
| 1438 | .aggregate, | 1443 | .aggregate, |
| 1439 | .un, | 1444 | .un, |
| ... | @@ -1660,6 +1665,7 @@ pub const Type = struct { | ... | @@ -1660,6 +1665,7 @@ pub const Type = struct { |
| 1660 | .empty_enum_value, | 1665 | .empty_enum_value, |
| 1661 | .float, | 1666 | .float, |
| 1662 | .ptr, | 1667 | .ptr, |
| 1668 | .slice, | ||
| 1663 | .opt, | 1669 | .opt, |
| 1664 | .aggregate, | 1670 | .aggregate, |
| 1665 | .un, | 1671 | .un, |
| ... | @@ -2195,6 +2201,7 @@ pub const Type = struct { | ... | @@ -2195,6 +2201,7 @@ pub const Type = struct { |
| 2195 | .empty_enum_value, | 2201 | .empty_enum_value, |
| 2196 | .float, | 2202 | .float, |
| 2197 | .ptr, | 2203 | .ptr, |
| 2204 | .slice, | ||
| 2198 | .opt, | 2205 | .opt, |
| 2199 | .aggregate, | 2206 | .aggregate, |
| 2200 | .un, | 2207 | .un, |
| ... | @@ -2538,6 +2545,7 @@ pub const Type = struct { | ... | @@ -2538,6 +2545,7 @@ pub const Type = struct { |
| 2538 | .empty_enum_value, | 2545 | .empty_enum_value, |
| 2539 | .float, | 2546 | .float, |
| 2540 | .ptr, | 2547 | .ptr, |
| 2548 | .slice, | ||
| 2541 | .opt, | 2549 | .opt, |
| 2542 | .aggregate, | 2550 | .aggregate, |
| 2543 | .un, | 2551 | .un, |
| ... | @@ -2731,6 +2739,7 @@ pub const Type = struct { | ... | @@ -2731,6 +2739,7 @@ pub const Type = struct { |
| 2731 | .empty_enum_value, | 2739 | .empty_enum_value, |
| 2732 | .float, | 2740 | .float, |
| 2733 | .ptr, | 2741 | .ptr, |
| 2742 | .slice, | ||
| 2734 | .opt, | 2743 | .opt, |
| 2735 | .aggregate, | 2744 | .aggregate, |
| 2736 | .un, | 2745 | .un, |
src/value.zig+36-48| ... | @@ -194,10 +194,7 @@ pub const Value = struct { | ... | @@ -194,10 +194,7 @@ pub const Value = struct { |
| 194 | const ip = &mod.intern_pool; | 194 | const ip = &mod.intern_pool; |
| 195 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 195 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 196 | .enum_literal => |enum_literal| enum_literal, | 196 | .enum_literal => |enum_literal| enum_literal, |
| 197 | .ptr => |ptr| switch (ptr.len) { | 197 | .slice => |slice| try arrayToIpString(val, Value.fromInterned(slice.len).toUnsignedInt(mod), mod), |
| 198 | .none => unreachable, | ||
| 199 | else => try arrayToIpString(val, Value.fromInterned(ptr.len).toUnsignedInt(mod), mod), | ||
| 200 | }, | ||
| 201 | .aggregate => |aggregate| switch (aggregate.storage) { | 198 | .aggregate => |aggregate| switch (aggregate.storage) { |
| 202 | .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes), | 199 | .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes), |
| 203 | .elems => try arrayToIpString(val, ty.arrayLen(mod), mod), | 200 | .elems => try arrayToIpString(val, ty.arrayLen(mod), mod), |
| ... | @@ -217,10 +214,7 @@ pub const Value = struct { | ... | @@ -217,10 +214,7 @@ pub const Value = struct { |
| 217 | pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 { | 214 | pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 { |
| 218 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 215 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 219 | .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)), | 216 | .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)), |
| 220 | .ptr => |ptr| switch (ptr.len) { | 217 | .slice => |slice| try arrayToAllocatedBytes(val, Value.fromInterned(slice.len).toUnsignedInt(mod), allocator, mod), |
| 221 | .none => unreachable, | ||
| 222 | else => try arrayToAllocatedBytes(val, Value.fromInterned(ptr.len).toUnsignedInt(mod), allocator, mod), | ||
| 223 | }, | ||
| 224 | .aggregate => |aggregate| switch (aggregate.storage) { | 218 | .aggregate => |aggregate| switch (aggregate.storage) { |
| 225 | .bytes => |bytes| try allocator.dupe(u8, bytes), | 219 | .bytes => |bytes| try allocator.dupe(u8, bytes), |
| 226 | .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod), | 220 | .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod), |
| ... | @@ -286,12 +280,11 @@ pub const Value = struct { | ... | @@ -286,12 +280,11 @@ pub const Value = struct { |
| 286 | }, | 280 | }, |
| 287 | .slice => { | 281 | .slice => { |
| 288 | const pl = val.castTag(.slice).?.data; | 282 | const pl = val.castTag(.slice).?.data; |
| 289 | const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod); | 283 | return mod.intern(.{ .slice = .{ |
| 290 | var ptr_key = ip.indexToKey(ptr).ptr; | 284 | .ty = ty.toIntern(), |
| 291 | assert(ptr_key.len == .none); | 285 | .len = try pl.len.intern(Type.usize, mod), |
| 292 | ptr_key.ty = ty.toIntern(); | 286 | .ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod), |
| 293 | ptr_key.len = try pl.len.intern(Type.usize, mod); | 287 | } }); |
| 294 | return mod.intern(.{ .ptr = ptr_key }); | ||
| 295 | }, | 288 | }, |
| 296 | .bytes => { | 289 | .bytes => { |
| 297 | const pl = val.castTag(.bytes).?.data; | 290 | const pl = val.castTag(.bytes).?.data; |
| ... | @@ -374,6 +367,7 @@ pub const Value = struct { | ... | @@ -374,6 +367,7 @@ pub const Value = struct { |
| 374 | .enum_tag, | 367 | .enum_tag, |
| 375 | .empty_enum_value, | 368 | .empty_enum_value, |
| 376 | .float, | 369 | .float, |
| 370 | .ptr, | ||
| 377 | => val, | 371 | => val, |
| 378 | 372 | ||
| 379 | .error_union => |error_union| switch (error_union.val) { | 373 | .error_union => |error_union| switch (error_union.val) { |
| ... | @@ -381,13 +375,10 @@ pub const Value = struct { | ... | @@ -381,13 +375,10 @@ pub const Value = struct { |
| 381 | .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)), | 375 | .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)), |
| 382 | }, | 376 | }, |
| 383 | 377 | ||
| 384 | .ptr => |ptr| switch (ptr.len) { | 378 | .slice => |slice| Tag.slice.create(arena, .{ |
| 385 | .none => val, | 379 | .ptr = Value.fromInterned(slice.ptr), |
| 386 | else => |len| Tag.slice.create(arena, .{ | 380 | .len = Value.fromInterned(slice.len), |
| 387 | .ptr = val.slicePtr(mod), | 381 | }), |
| 388 | .len = Value.fromInterned(len), | ||
| 389 | }), | ||
| 390 | }, | ||
| 391 | 382 | ||
| 392 | .opt => |opt| switch (opt.val) { | 383 | .opt => |opt| switch (opt.val) { |
| 393 | .none => val, | 384 | .none => val, |
| ... | @@ -1538,6 +1529,7 @@ pub const Value = struct { | ... | @@ -1538,6 +1529,7 @@ pub const Value = struct { |
| 1538 | 1529 | ||
| 1539 | pub fn isComptimeMutablePtr(val: Value, mod: *Module) bool { | 1530 | pub fn isComptimeMutablePtr(val: Value, mod: *Module) bool { |
| 1540 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1531 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1532 | .slice => |slice| return Value.fromInterned(slice.ptr).isComptimeMutablePtr(mod), | ||
| 1541 | .ptr => |ptr| switch (ptr.addr) { | 1533 | .ptr => |ptr| switch (ptr.addr) { |
| 1542 | .mut_decl, .comptime_field => true, | 1534 | .mut_decl, .comptime_field => true, |
| 1543 | .eu_payload, .opt_payload => |base_ptr| Value.fromInterned(base_ptr).isComptimeMutablePtr(mod), | 1535 | .eu_payload, .opt_payload => |base_ptr| Value.fromInterned(base_ptr).isComptimeMutablePtr(mod), |
| ... | @@ -1600,9 +1592,8 @@ pub const Value = struct { | ... | @@ -1600,9 +1592,8 @@ pub const Value = struct { |
| 1600 | 1592 | ||
| 1601 | pub fn sliceLen(val: Value, mod: *Module) u64 { | 1593 | pub fn sliceLen(val: Value, mod: *Module) u64 { |
| 1602 | const ip = &mod.intern_pool; | 1594 | const ip = &mod.intern_pool; |
| 1603 | const ptr = ip.indexToKey(val.toIntern()).ptr; | 1595 | return switch (ip.indexToKey(val.toIntern())) { |
| 1604 | return switch (ptr.len) { | 1596 | .ptr => |ptr| switch (ip.indexToKey(switch (ptr.addr) { |
| 1605 | .none => switch (ip.indexToKey(switch (ptr.addr) { | ||
| 1606 | .decl => |decl| mod.declPtr(decl).ty.toIntern(), | 1597 | .decl => |decl| mod.declPtr(decl).ty.toIntern(), |
| 1607 | .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(), | 1598 | .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(), |
| 1608 | .anon_decl => |anon_decl| ip.typeOf(anon_decl.val), | 1599 | .anon_decl => |anon_decl| ip.typeOf(anon_decl.val), |
| ... | @@ -1612,7 +1603,8 @@ pub const Value = struct { | ... | @@ -1612,7 +1603,8 @@ pub const Value = struct { |
| 1612 | .array_type => |array_type| array_type.len, | 1603 | .array_type => |array_type| array_type.len, |
| 1613 | else => 1, | 1604 | else => 1, |
| 1614 | }, | 1605 | }, |
| 1615 | else => Value.fromInterned(ptr.len).toUnsignedInt(mod), | 1606 | .slice => |slice| Value.fromInterned(slice.len).toUnsignedInt(mod), |
| 1607 | else => unreachable, | ||
| 1616 | }; | 1608 | }; |
| 1617 | } | 1609 | } |
| 1618 | 1610 | ||
| ... | @@ -1636,6 +1628,7 @@ pub const Value = struct { | ... | @@ -1636,6 +1628,7 @@ pub const Value = struct { |
| 1636 | .undef => |ty| Value.fromInterned((try mod.intern(.{ | 1628 | .undef => |ty| Value.fromInterned((try mod.intern(.{ |
| 1637 | .undef = Type.fromInterned(ty).elemType2(mod).toIntern(), | 1629 | .undef = Type.fromInterned(ty).elemType2(mod).toIntern(), |
| 1638 | }))), | 1630 | }))), |
| 1631 | .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValue(mod, index), | ||
| 1639 | .ptr => |ptr| switch (ptr.addr) { | 1632 | .ptr => |ptr| switch (ptr.addr) { |
| 1640 | .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index), | 1633 | .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index), |
| 1641 | .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValue(mod, index), | 1634 | .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValue(mod, index), |
| ... | @@ -1800,25 +1793,23 @@ pub const Value = struct { | ... | @@ -1800,25 +1793,23 @@ pub const Value = struct { |
| 1800 | ) Allocator.Error!Value { | 1793 | ) Allocator.Error!Value { |
| 1801 | const elem_ty = elem_ptr_ty.childType(mod); | 1794 | const elem_ty = elem_ptr_ty.childType(mod); |
| 1802 | const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1795 | const ptr_val = switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1803 | .ptr => |ptr| ptr: { | 1796 | .slice => |slice| Value.fromInterned(slice.ptr), |
| 1804 | switch (ptr.addr) { | ||
| 1805 | .elem => |elem| if (Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod).eql(elem_ty, mod)) | ||
| 1806 | return Value.fromInterned((try mod.intern(.{ .ptr = .{ | ||
| 1807 | .ty = elem_ptr_ty.toIntern(), | ||
| 1808 | .addr = .{ .elem = .{ | ||
| 1809 | .base = elem.base, | ||
| 1810 | .index = elem.index + index, | ||
| 1811 | } }, | ||
| 1812 | } }))), | ||
| 1813 | else => {}, | ||
| 1814 | } | ||
| 1815 | break :ptr switch (ptr.len) { | ||
| 1816 | .none => val, | ||
| 1817 | else => val.slicePtr(mod), | ||
| 1818 | }; | ||
| 1819 | }, | ||
| 1820 | else => val, | 1797 | else => val, |
| 1821 | }; | 1798 | }; |
| 1799 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { | ||
| 1800 | .ptr => |ptr| switch (ptr.addr) { | ||
| 1801 | .elem => |elem| if (Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod).eql(elem_ty, mod)) | ||
| 1802 | return Value.fromInterned((try mod.intern(.{ .ptr = .{ | ||
| 1803 | .ty = elem_ptr_ty.toIntern(), | ||
| 1804 | .addr = .{ .elem = .{ | ||
| 1805 | .base = elem.base, | ||
| 1806 | .index = elem.index + index, | ||
| 1807 | } }, | ||
| 1808 | } }))), | ||
| 1809 | else => {}, | ||
| 1810 | }, | ||
| 1811 | else => {}, | ||
| 1812 | } | ||
| 1822 | var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type; | 1813 | var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type; |
| 1823 | assert(ptr_ty_key.flags.size != .Slice); | 1814 | assert(ptr_ty_key.flags.size != .Slice); |
| 1824 | ptr_ty_key.flags.size = .Many; | 1815 | ptr_ty_key.flags.size = .Many; |
| ... | @@ -1850,12 +1841,9 @@ pub const Value = struct { | ... | @@ -1850,12 +1841,9 @@ pub const Value = struct { |
| 1850 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1841 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1851 | .undef => true, | 1842 | .undef => true, |
| 1852 | .simple_value => |v| v == .undefined, | 1843 | .simple_value => |v| v == .undefined, |
| 1853 | .ptr => |ptr| switch (ptr.len) { | 1844 | .slice => |slice| for (0..@intCast(Value.fromInterned(slice.len).toUnsignedInt(mod))) |idx| { |
| 1854 | .none => false, | 1845 | if (try (try val.elemValue(mod, idx)).anyUndef(mod)) break true; |
| 1855 | else => for (0..@as(usize, @intCast(Value.fromInterned(ptr.len).toUnsignedInt(mod)))) |index| { | 1846 | } else false, |
| 1856 | if (try (try val.elemValue(mod, index)).anyUndef(mod)) break true; | ||
| 1857 | } else false, | ||
| 1858 | }, | ||
| 1859 | .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| { | 1847 | .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| { |
| 1860 | const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i]; | 1848 | const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i]; |
| 1861 | if (try anyUndef(Value.fromInterned(elem), mod)) break true; | 1849 | if (try anyUndef(Value.fromInterned(elem), mod)) break true; |