| ... | @@ -69,7 +69,14 @@ pub const Type = extern union { | ... | @@ -69,7 +69,14 @@ pub const Type = extern union { |
| 69 | .fn_ccc_void_no_args => return .Fn, | 69 | .fn_ccc_void_no_args => return .Fn, |
| 70 | .function => return .Fn, | 70 | .function => return .Fn, |
| 71 | | 71 | |
| 72 | .array, .array_u8_sentinel_0, .array_u8, .array_sentinel => return .Array, | 72 | .array, |
| | 73 | .array_u8_sentinel_0, |
| | 74 | .array_u8, |
| | 75 | .array_sentinel, |
| | 76 | => return .Array, |
| | 77 | |
| | 78 | .vector => return .Vector, |
| | 79 | |
| 73 | .single_const_pointer_to_comptime_int, | 80 | .single_const_pointer_to_comptime_int, |
| 74 | .const_slice_u8, | 81 | .const_slice_u8, |
| 75 | .single_const_pointer, | 82 | .single_const_pointer, |
| ... | @@ -438,7 +445,7 @@ pub const Type = extern union { | ... | @@ -438,7 +445,7 @@ pub const Type = extern union { |
| 438 | const info_b = b.intInfo(@as(Target, undefined)); | 445 | const info_b = b.intInfo(@as(Target, undefined)); |
| 439 | return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits; | 446 | return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits; |
| 440 | }, | 447 | }, |
| 441 | .Array => { | 448 | .Array, .Vector => { |
| 442 | if (a.arrayLen() != b.arrayLen()) | 449 | if (a.arrayLen() != b.arrayLen()) |
| 443 | return false; | 450 | return false; |
| 444 | if (!a.elemType().eql(b.elemType())) | 451 | if (!a.elemType().eql(b.elemType())) |
| ... | @@ -487,7 +494,6 @@ pub const Type = extern union { | ... | @@ -487,7 +494,6 @@ pub const Type = extern union { |
| 487 | .BoundFn, | 494 | .BoundFn, |
| 488 | .Opaque, | 495 | .Opaque, |
| 489 | .Frame, | 496 | .Frame, |
| 490 | .Vector, | | |
| 491 | => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }), | 497 | => std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ a, b }), |
| 492 | } | 498 | } |
| 493 | } | 499 | } |
| ... | @@ -522,7 +528,7 @@ pub const Type = extern union { | ... | @@ -522,7 +528,7 @@ pub const Type = extern union { |
| 522 | std.hash.autoHash(&hasher, info.bits); | 528 | std.hash.autoHash(&hasher, info.bits); |
| 523 | } | 529 | } |
| 524 | }, | 530 | }, |
| 525 | .Array => { | 531 | .Array, .Vector => { |
| 526 | std.hash.autoHash(&hasher, self.arrayLen()); | 532 | std.hash.autoHash(&hasher, self.arrayLen()); |
| 527 | std.hash.autoHash(&hasher, self.elemType().hash()); | 533 | std.hash.autoHash(&hasher, self.elemType().hash()); |
| 528 | // TODO hash array sentinel | 534 | // TODO hash array sentinel |
| ... | @@ -552,7 +558,6 @@ pub const Type = extern union { | ... | @@ -552,7 +558,6 @@ pub const Type = extern union { |
| 552 | .Opaque, | 558 | .Opaque, |
| 553 | .Frame, | 559 | .Frame, |
| 554 | .AnyFrame, | 560 | .AnyFrame, |
| 555 | .Vector, | | |
| 556 | .EnumLiteral, | 561 | .EnumLiteral, |
| 557 | => { | 562 | => { |
| 558 | // TODO implement more type hashing | 563 | // TODO implement more type hashing |
| ... | @@ -647,6 +652,13 @@ pub const Type = extern union { | ... | @@ -647,6 +652,13 @@ pub const Type = extern union { |
| 647 | .int_unsigned, | 652 | .int_unsigned, |
| 648 | => return self.copyPayloadShallow(allocator, Payload.Bits), | 653 | => return self.copyPayloadShallow(allocator, Payload.Bits), |
| 649 | | 654 | |
| | 655 | .vector => { |
| | 656 | const payload = self.castTag(.vector).?.data; |
| | 657 | return Tag.vector.create(allocator, .{ |
| | 658 | .len = payload.len, |
| | 659 | .elem_type = try payload.elem_type.copy(allocator), |
| | 660 | }); |
| | 661 | }, |
| 650 | .array => { | 662 | .array => { |
| 651 | const payload = self.castTag(.array).?.data; | 663 | const payload = self.castTag(.array).?.data; |
| 652 | return Tag.array.create(allocator, .{ | 664 | return Tag.array.create(allocator, .{ |
| ... | @@ -839,6 +851,12 @@ pub const Type = extern union { | ... | @@ -839,6 +851,12 @@ pub const Type = extern union { |
| 839 | const len = ty.castTag(.array_u8_sentinel_0).?.data; | 851 | const len = ty.castTag(.array_u8_sentinel_0).?.data; |
| 840 | return writer.print("[{d}:0]u8", .{len}); | 852 | return writer.print("[{d}:0]u8", .{len}); |
| 841 | }, | 853 | }, |
| | 854 | .vector => { |
| | 855 | const payload = ty.castTag(.vector).?.data; |
| | 856 | try writer.print("@Vector({d}, ", .{payload.len}); |
| | 857 | try payload.elem_type.format("", .{}, writer); |
| | 858 | return writer.writeAll(")"); |
| | 859 | }, |
| 842 | .array => { | 860 | .array => { |
| 843 | const payload = ty.castTag(.array).?.data; | 861 | const payload = ty.castTag(.array).?.data; |
| 844 | try writer.print("[{d}]", .{payload.len}); | 862 | try writer.print("[{d}]", .{payload.len}); |
| ... | @@ -1116,7 +1134,7 @@ pub const Type = extern union { | ... | @@ -1116,7 +1134,7 @@ pub const Type = extern union { |
| 1116 | }, | 1134 | }, |
| 1117 | | 1135 | |
| 1118 | // TODO lazy types | 1136 | // TODO lazy types |
| 1119 | .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0, | 1137 | .array, .vector => self.elemType().hasCodeGenBits() and self.arrayLen() != 0, |
| 1120 | .array_u8 => self.arrayLen() != 0, | 1138 | .array_u8 => self.arrayLen() != 0, |
| 1121 | .array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(), | 1139 | .array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(), |
| 1122 | .int_signed, .int_unsigned => self.cast(Payload.Bits).?.data != 0, | 1140 | .int_signed, .int_unsigned => self.cast(Payload.Bits).?.data != 0, |
| ... | @@ -1264,6 +1282,10 @@ pub const Type = extern union { | ... | @@ -1264,6 +1282,10 @@ pub const Type = extern union { |
| 1264 | | 1282 | |
| 1265 | .array, .array_sentinel => return self.elemType().abiAlignment(target), | 1283 | .array, .array_sentinel => return self.elemType().abiAlignment(target), |
| 1266 | | 1284 | |
| | 1285 | // TODO audit this - is there any more complicated logic to determine |
| | 1286 | // ABI alignment of vectors? |
| | 1287 | .vector => return 16, |
| | 1288 | |
| 1267 | .int_signed, .int_unsigned => { | 1289 | .int_signed, .int_unsigned => { |
| 1268 | const bits: u16 = self.cast(Payload.Bits).?.data; | 1290 | const bits: u16 = self.cast(Payload.Bits).?.data; |
| 1269 | return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8); | 1291 | return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8); |
| ... | @@ -1386,8 +1408,8 @@ pub const Type = extern union { | ... | @@ -1386,8 +1408,8 @@ pub const Type = extern union { |
| 1386 | | 1408 | |
| 1387 | .array_u8 => self.castTag(.array_u8).?.data, | 1409 | .array_u8 => self.castTag(.array_u8).?.data, |
| 1388 | .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data + 1, | 1410 | .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data + 1, |
| 1389 | .array => { | 1411 | .array, .vector => { |
| 1390 | const payload = self.castTag(.array).?.data; | 1412 | const payload = self.cast(Payload.Array).?.data; |
| 1391 | const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target)); | 1413 | const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target)); |
| 1392 | return payload.len * elem_size; | 1414 | return payload.len * elem_size; |
| 1393 | }, | 1415 | }, |
| ... | @@ -1534,6 +1556,11 @@ pub const Type = extern union { | ... | @@ -1534,6 +1556,11 @@ pub const Type = extern union { |
| 1534 | | 1556 | |
| 1535 | .bool => 1, | 1557 | .bool => 1, |
| 1536 | | 1558 | |
| | 1559 | .vector => { |
| | 1560 | const payload = self.castTag(.vector).?.data; |
| | 1561 | const elem_bit_size = payload.elem_type.bitSize(target); |
| | 1562 | return elem_bit_size * payload.len; |
| | 1563 | }, |
| 1537 | .array_u8 => 8 * self.castTag(.array_u8).?.data, | 1564 | .array_u8 => 8 * self.castTag(.array_u8).?.data, |
| 1538 | .array_u8_sentinel_0 => 8 * (self.castTag(.array_u8_sentinel_0).?.data + 1), | 1565 | .array_u8_sentinel_0 => 8 * (self.castTag(.array_u8_sentinel_0).?.data + 1), |
| 1539 | .array => { | 1566 | .array => { |
| ... | @@ -1811,7 +1838,6 @@ pub const Type = extern union { | ... | @@ -1811,7 +1838,6 @@ pub const Type = extern union { |
| 1811 | .Enum, | 1838 | .Enum, |
| 1812 | .Frame, | 1839 | .Frame, |
| 1813 | .AnyFrame, | 1840 | .AnyFrame, |
| 1814 | .Vector, | | |
| 1815 | => return true, | 1841 | => return true, |
| 1816 | | 1842 | |
| 1817 | .Opaque => return is_extern, | 1843 | .Opaque => return is_extern, |
| ... | @@ -1830,7 +1856,7 @@ pub const Type = extern union { | ... | @@ -1830,7 +1856,7 @@ pub const Type = extern union { |
| 1830 | var buf: Payload.ElemType = undefined; | 1856 | var buf: Payload.ElemType = undefined; |
| 1831 | return ty.optionalChild(&buf).isValidVarType(is_extern); | 1857 | return ty.optionalChild(&buf).isValidVarType(is_extern); |
| 1832 | }, | 1858 | }, |
| 1833 | .Pointer, .Array => ty = ty.elemType(), | 1859 | .Pointer, .Array, .Vector => ty = ty.elemType(), |
| 1834 | .ErrorUnion => ty = ty.errorUnionChild(), | 1860 | .ErrorUnion => ty = ty.errorUnionChild(), |
| 1835 | | 1861 | |
| 1836 | .Fn => @panic("TODO fn isValidVarType"), | 1862 | .Fn => @panic("TODO fn isValidVarType"), |
| ... | @@ -1846,6 +1872,7 @@ pub const Type = extern union { | ... | @@ -1846,6 +1872,7 @@ pub const Type = extern union { |
| 1846 | /// Asserts the type is a pointer or array type. | 1872 | /// Asserts the type is a pointer or array type. |
| 1847 | pub fn elemType(self: Type) Type { | 1873 | pub fn elemType(self: Type) Type { |
| 1848 | return switch (self.tag()) { | 1874 | return switch (self.tag()) { |
| | 1875 | .vector => self.castTag(.vector).?.data.elem_type, |
| 1849 | .array => self.castTag(.array).?.data.elem_type, | 1876 | .array => self.castTag(.array).?.data.elem_type, |
| 1850 | .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type, | 1877 | .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type, |
| 1851 | .single_const_pointer, | 1878 | .single_const_pointer, |
| ... | @@ -1936,6 +1963,7 @@ pub const Type = extern union { | ... | @@ -1936,6 +1963,7 @@ pub const Type = extern union { |
| 1936 | /// Asserts the type is an array or vector. | 1963 | /// Asserts the type is an array or vector. |
| 1937 | pub fn arrayLen(self: Type) u64 { | 1964 | pub fn arrayLen(self: Type) u64 { |
| 1938 | return switch (self.tag()) { | 1965 | return switch (self.tag()) { |
| | 1966 | .vector => self.castTag(.vector).?.data.len, |
| 1939 | .array => self.castTag(.array).?.data.len, | 1967 | .array => self.castTag(.array).?.data.len, |
| 1940 | .array_sentinel => self.castTag(.array_sentinel).?.data.len, | 1968 | .array_sentinel => self.castTag(.array_sentinel).?.data.len, |
| 1941 | .array_u8 => self.castTag(.array_u8).?.data, | 1969 | .array_u8 => self.castTag(.array_u8).?.data, |
| ... | @@ -1955,6 +1983,7 @@ pub const Type = extern union { | ... | @@ -1955,6 +1983,7 @@ pub const Type = extern union { |
| 1955 | .c_const_pointer, | 1983 | .c_const_pointer, |
| 1956 | .c_mut_pointer, | 1984 | .c_mut_pointer, |
| 1957 | .single_const_pointer_to_comptime_int, | 1985 | .single_const_pointer_to_comptime_int, |
| | 1986 | .vector, |
| 1958 | .array, | 1987 | .array, |
| 1959 | .array_u8, | 1988 | .array_u8, |
| 1960 | .manyptr_u8, | 1989 | .manyptr_u8, |
| ... | @@ -2325,7 +2354,7 @@ pub const Type = extern union { | ... | @@ -2325,7 +2354,7 @@ pub const Type = extern union { |
| 2325 | return null; | 2354 | return null; |
| 2326 | } | 2355 | } |
| 2327 | }, | 2356 | }, |
| 2328 | .array, .array_u8 => { | 2357 | .vector, .array, .array_u8 => { |
| 2329 | if (ty.arrayLen() == 0) | 2358 | if (ty.arrayLen() == 0) |
| 2330 | return Value.initTag(.empty_array); | 2359 | return Value.initTag(.empty_array); |
| 2331 | ty = ty.elemType(); | 2360 | ty = ty.elemType(); |
| ... | @@ -2730,6 +2759,7 @@ pub const Type = extern union { | ... | @@ -2730,6 +2759,7 @@ pub const Type = extern union { |
| 2730 | array_u8_sentinel_0, | 2759 | array_u8_sentinel_0, |
| 2731 | array, | 2760 | array, |
| 2732 | array_sentinel, | 2761 | array_sentinel, |
| | 2762 | vector, |
| 2733 | pointer, | 2763 | pointer, |
| 2734 | single_const_pointer, | 2764 | single_const_pointer, |
| 2735 | single_mut_pointer, | 2765 | single_mut_pointer, |
| ... | @@ -2845,7 +2875,7 @@ pub const Type = extern union { | ... | @@ -2845,7 +2875,7 @@ pub const Type = extern union { |
| 2845 | | 2875 | |
| 2846 | .error_set => Payload.ErrorSet, | 2876 | .error_set => Payload.ErrorSet, |
| 2847 | | 2877 | |
| 2848 | .array => Payload.Array, | 2878 | .array, .vector => Payload.Array, |
| 2849 | .array_sentinel => Payload.ArraySentinel, | 2879 | .array_sentinel => Payload.ArraySentinel, |
| 2850 | .pointer => Payload.Pointer, | 2880 | .pointer => Payload.Pointer, |
| 2851 | .function => Payload.Function, | 2881 | .function => Payload.Function, |
| ... | @@ -2888,9 +2918,7 @@ pub const Type = extern union { | ... | @@ -2888,9 +2918,7 @@ pub const Type = extern union { |
| 2888 | }; | 2918 | }; |
| 2889 | | 2919 | |
| 2890 | pub const Array = struct { | 2920 | pub const Array = struct { |
| 2891 | pub const base_tag = Tag.array; | 2921 | base: Payload, |
| 2892 | | | |
| 2893 | base: Payload = Payload{ .tag = base_tag }, | | |
| 2894 | data: struct { | 2922 | data: struct { |
| 2895 | len: u64, | 2923 | len: u64, |
| 2896 | elem_type: Type, | 2924 | elem_type: Type, |