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