| ... | ... | @@ -666,9 +666,12 @@ pub const Tag = enum(u8) { |
| 666 | 666 | /// An integer type. |
| 667 | 667 | /// data is number of bits |
| 668 | 668 | type_int_unsigned, |
| 669 | /// An array type whose length requires 64 bits or which has a sentinel. |
| 670 | /// data is payload to Array. |
| 671 | type_array_big, |
| 669 | 672 | /// An array type that has no sentinel and whose length fits in 32 bits. |
| 670 | 673 | /// data is payload to Vector. |
| 671 | | type_array, |
| 674 | type_array_small, |
| 672 | 675 | /// A vector type. |
| 673 | 676 | /// data is payload to Vector. |
| 674 | 677 | type_vector, |
| ... | ... | @@ -862,6 +865,25 @@ pub const Vector = struct { |
| 862 | 865 | child: Index, |
| 863 | 866 | }; |
| 864 | 867 | |
| 868 | pub const Array = struct { |
| 869 | len0: u32, |
| 870 | len1: u32, |
| 871 | child: Index, |
| 872 | sentinel: Index, |
| 873 | |
| 874 | pub const Length = packed struct(u64) { |
| 875 | len0: u32, |
| 876 | len1: u32, |
| 877 | }; |
| 878 | |
| 879 | pub fn getLength(a: Array) u64 { |
| 880 | return @bitCast(u64, Length{ |
| 881 | .len0 = a.len0, |
| 882 | .len1 = a.len1, |
| 883 | }); |
| 884 | } |
| 885 | }; |
| 886 | |
| 865 | 887 | pub const ErrorUnion = struct { |
| 866 | 888 | error_set_type: Index, |
| 867 | 889 | payload_type: Index, |
| ... | ... | @@ -958,7 +980,15 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 958 | 980 | .bits = @intCast(u16, data), |
| 959 | 981 | }, |
| 960 | 982 | }, |
| 961 | | .type_array => { |
| 983 | .type_array_big => { |
| 984 | const array_info = ip.extraData(Array, data); |
| 985 | return .{ .array_type = .{ |
| 986 | .len = array_info.getLength(), |
| 987 | .child = array_info.child, |
| 988 | .sentinel = array_info.sentinel, |
| 989 | } }; |
| 990 | }, |
| 991 | .type_array_small => { |
| 962 | 992 | const array_info = ip.extraData(Vector, data); |
| 963 | 993 | return .{ .array_type = .{ |
| 964 | 994 | .len = array_info.len, |
| ... | ... | @@ -1094,13 +1124,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 1094 | 1124 | }); |
| 1095 | 1125 | }, |
| 1096 | 1126 | .array_type => |array_type| { |
| 1097 | | const len = @intCast(u32, array_type.len); // TODO have a big_array encoding |
| 1098 | | assert(array_type.sentinel == .none); // TODO have a sentinel_array encoding |
| 1127 | assert(array_type.child != .none); |
| 1128 | |
| 1129 | if (std.math.cast(u32, array_type.len)) |len| { |
| 1130 | if (array_type.sentinel == .none) { |
| 1131 | ip.items.appendAssumeCapacity(.{ |
| 1132 | .tag = .type_array_small, |
| 1133 | .data = try ip.addExtra(gpa, Vector{ |
| 1134 | .len = len, |
| 1135 | .child = array_type.child, |
| 1136 | }), |
| 1137 | }); |
| 1138 | return @intToEnum(Index, ip.items.len - 1); |
| 1139 | } |
| 1140 | } |
| 1141 | |
| 1142 | const length = @bitCast(Array.Length, array_type.len); |
| 1099 | 1143 | ip.items.appendAssumeCapacity(.{ |
| 1100 | | .tag = .type_array, |
| 1101 | | .data = try ip.addExtra(gpa, Vector{ |
| 1102 | | .len = len, |
| 1144 | .tag = .type_array_big, |
| 1145 | .data = try ip.addExtra(gpa, Array{ |
| 1146 | .len0 = length.len0, |
| 1147 | .len1 = length.len1, |
| 1103 | 1148 | .child = array_type.child, |
| 1149 | .sentinel = array_type.sentinel, |
| 1104 | 1150 | }), |
| 1105 | 1151 | }); |
| 1106 | 1152 | }, |
| ... | ... | @@ -1488,7 +1534,8 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void { |
| 1488 | 1534 | gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) { |
| 1489 | 1535 | .type_int_signed => 0, |
| 1490 | 1536 | .type_int_unsigned => 0, |
| 1491 | | .type_array => @sizeOf(Vector), |
| 1537 | .type_array_small => @sizeOf(Vector), |
| 1538 | .type_array_big => @sizeOf(Array), |
| 1492 | 1539 | .type_vector => @sizeOf(Vector), |
| 1493 | 1540 | .type_pointer => @sizeOf(Pointer), |
| 1494 | 1541 | .type_slice => 0, |