| ... | ... | @@ -197,7 +197,7 @@ pub const Key = union(enum) { |
| 197 | 197 | undef: Index, |
| 198 | 198 | runtime_value: TypeValue, |
| 199 | 199 | simple_value: SimpleValue, |
| 200 | | variable: Key.Variable, |
| 200 | variable: Variable, |
| 201 | 201 | extern_func: ExternFunc, |
| 202 | 202 | func: Func, |
| 203 | 203 | int: Key.Int, |
| ... | ... | @@ -205,19 +205,19 @@ pub const Key = union(enum) { |
| 205 | 205 | error_union: ErrorUnion, |
| 206 | 206 | enum_literal: NullTerminatedString, |
| 207 | 207 | /// A specific enum tag, indicated by the integer tag value. |
| 208 | | enum_tag: Key.EnumTag, |
| 208 | enum_tag: EnumTag, |
| 209 | 209 | /// An empty enum or union. TODO: this value's existence is strange, because such a type in |
| 210 | 210 | /// reality has no values. See #15909. |
| 211 | 211 | /// Payload is the type for which we are an empty value. |
| 212 | 212 | empty_enum_value: Index, |
| 213 | | float: Key.Float, |
| 213 | float: Float, |
| 214 | 214 | ptr: Ptr, |
| 215 | 215 | opt: Opt, |
| 216 | 216 | /// An instance of a struct, array, or vector. |
| 217 | 217 | /// Each element/field stored as an `Index`. |
| 218 | 218 | /// In the case of sentinel-terminated arrays, the sentinel value *is* stored, |
| 219 | 219 | /// so the slice length will be one more than the type's array length. |
| 220 | | aggregate: Key.Aggregate, |
| 220 | aggregate: Aggregate, |
| 221 | 221 | /// An instance of a union. |
| 222 | 222 | un: Union, |
| 223 | 223 | |
| ... | ... | @@ -226,14 +226,15 @@ pub const Key = union(enum) { |
| 226 | 226 | /// A comptime function call with a memoized result. |
| 227 | 227 | memoized_call: Key.MemoizedCall, |
| 228 | 228 | |
| 229 | | pub const TypeValue = struct { |
| 229 | pub const TypeValue = extern struct { |
| 230 | 230 | ty: Index, |
| 231 | 231 | val: Index, |
| 232 | 232 | }; |
| 233 | 233 | |
| 234 | 234 | pub const IntType = std.builtin.Type.Int; |
| 235 | 235 | |
| 236 | | pub const ErrorUnionType = struct { |
| 236 | /// Extern for hashing via memory reinterpretation. |
| 237 | pub const ErrorUnionType = extern struct { |
| 237 | 238 | error_set_type: Index, |
| 238 | 239 | payload_type: Index, |
| 239 | 240 | }; |
| ... | ... | @@ -296,25 +297,27 @@ pub const Key = union(enum) { |
| 296 | 297 | pub const AddressSpace = std.builtin.AddressSpace; |
| 297 | 298 | }; |
| 298 | 299 | |
| 299 | | pub const ArrayType = struct { |
| 300 | /// Extern so that hashing can be done via memory reinterpreting. |
| 301 | pub const ArrayType = extern struct { |
| 300 | 302 | len: u64, |
| 301 | 303 | child: Index, |
| 302 | 304 | sentinel: Index = .none, |
| 303 | 305 | }; |
| 304 | 306 | |
| 305 | | pub const VectorType = struct { |
| 307 | /// Extern so that hashing can be done via memory reinterpreting. |
| 308 | pub const VectorType = extern struct { |
| 306 | 309 | len: u32, |
| 307 | 310 | child: Index, |
| 308 | 311 | }; |
| 309 | 312 | |
| 310 | | pub const OpaqueType = struct { |
| 313 | pub const OpaqueType = extern struct { |
| 311 | 314 | /// The Decl that corresponds to the opaque itself. |
| 312 | 315 | decl: Module.Decl.Index, |
| 313 | 316 | /// Represents the declarations inside this opaque. |
| 314 | 317 | namespace: Module.Namespace.Index, |
| 315 | 318 | }; |
| 316 | 319 | |
| 317 | | pub const StructType = struct { |
| 320 | pub const StructType = extern struct { |
| 318 | 321 | /// The `none` tag is used to represent a struct with no fields. |
| 319 | 322 | index: Module.Struct.OptionalIndex, |
| 320 | 323 | /// May be `none` if the struct has no declarations. |
| ... | ... | @@ -501,7 +504,8 @@ pub const Key = union(enum) { |
| 501 | 504 | lib_name: OptionalNullTerminatedString, |
| 502 | 505 | }; |
| 503 | 506 | |
| 504 | | pub const Func = struct { |
| 507 | /// Extern so it can be hashed by reinterpreting memory. |
| 508 | pub const Func = extern struct { |
| 505 | 509 | ty: Index, |
| 506 | 510 | index: Module.Fn.Index, |
| 507 | 511 | }; |
| ... | ... | @@ -534,7 +538,7 @@ pub const Key = union(enum) { |
| 534 | 538 | }; |
| 535 | 539 | }; |
| 536 | 540 | |
| 537 | | pub const Error = struct { |
| 541 | pub const Error = extern struct { |
| 538 | 542 | ty: Index, |
| 539 | 543 | name: NullTerminatedString, |
| 540 | 544 | }; |
| ... | ... | @@ -549,7 +553,7 @@ pub const Key = union(enum) { |
| 549 | 553 | }; |
| 550 | 554 | }; |
| 551 | 555 | |
| 552 | | pub const EnumTag = struct { |
| 556 | pub const EnumTag = extern struct { |
| 553 | 557 | /// The enum type. |
| 554 | 558 | ty: Index, |
| 555 | 559 | /// The integer tag value which has the integer tag type of the enum. |
| ... | ... | @@ -600,14 +604,14 @@ pub const Key = union(enum) { |
| 600 | 604 | }; |
| 601 | 605 | |
| 602 | 606 | /// `null` is represented by the `val` field being `none`. |
| 603 | | pub const Opt = struct { |
| 607 | pub const Opt = extern struct { |
| 604 | 608 | /// This is the optional type; not the payload type. |
| 605 | 609 | ty: Index, |
| 606 | 610 | /// This could be `none`, indicating the optional is `null`. |
| 607 | 611 | val: Index, |
| 608 | 612 | }; |
| 609 | 613 | |
| 610 | | pub const Union = struct { |
| 614 | pub const Union = extern struct { |
| 611 | 615 | /// This is the union type; not the field type. |
| 612 | 616 | ty: Index, |
| 613 | 617 | /// Indicates the active field. |
| ... | ... | @@ -654,10 +658,10 @@ pub const Key = union(enum) { |
| 654 | 658 | const asBytes = std.mem.asBytes; |
| 655 | 659 | const KeyTag = @typeInfo(Key).Union.tag_type.?; |
| 656 | 660 | const seed = @enumToInt(@as(KeyTag, key)); |
| 657 | | switch (key) { |
| 658 | | .ptr_type => |x| return WyhashKing.hash(seed, asBytes(&x)), |
| 659 | | |
| 660 | | inline .int_type, |
| 661 | return switch (key) { |
| 662 | // TODO: assert no padding in these types |
| 663 | inline .ptr_type, |
| 664 | .func, |
| 661 | 665 | .array_type, |
| 662 | 666 | .vector_type, |
| 663 | 667 | .opt_type, |
| ... | ... | @@ -667,31 +671,26 @@ pub const Key = union(enum) { |
| 667 | 671 | .simple_value, |
| 668 | 672 | .opt, |
| 669 | 673 | .struct_type, |
| 670 | | .union_type, |
| 671 | | .un, |
| 672 | 674 | .undef, |
| 673 | 675 | .err, |
| 674 | | .error_union, |
| 675 | 676 | .enum_literal, |
| 676 | 677 | .enum_tag, |
| 677 | 678 | .empty_enum_value, |
| 678 | 679 | .inferred_error_set_type, |
| 679 | | => |info| { |
| 680 | | var hasher = std.hash.Wyhash.init(seed); |
| 681 | | std.hash.autoHash(&hasher, info); |
| 682 | | return hasher.final(); |
| 683 | | }, |
| 680 | .un, |
| 681 | => |x| WyhashKing.hash(seed, asBytes(&x)), |
| 684 | 682 | |
| 685 | | .runtime_value => |runtime_value| { |
| 686 | | var hasher = std.hash.Wyhash.init(seed); |
| 687 | | std.hash.autoHash(&hasher, runtime_value.val); |
| 688 | | return hasher.final(); |
| 689 | | }, |
| 690 | | .opaque_type => |opaque_type| { |
| 691 | | var hasher = std.hash.Wyhash.init(seed); |
| 692 | | std.hash.autoHash(&hasher, opaque_type.decl); |
| 693 | | return hasher.final(); |
| 683 | .int_type => |x| WyhashKing.hash(seed + @enumToInt(x.signedness), asBytes(&x.bits)), |
| 684 | .union_type => |x| WyhashKing.hash(seed + @enumToInt(x.runtime_tag), asBytes(&x.index)), |
| 685 | |
| 686 | .error_union => |x| switch (x.val) { |
| 687 | .err_name => |y| WyhashKing.hash(seed + 0, asBytes(&x.ty) ++ asBytes(&y)), |
| 688 | .payload => |y| WyhashKing.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)), |
| 694 | 689 | }, |
| 690 | |
| 691 | .runtime_value => |x| WyhashKing.hash(seed, asBytes(&x.val)), |
| 692 | .opaque_type => |x| WyhashKing.hash(seed, asBytes(&x.decl)), |
| 693 | |
| 695 | 694 | .enum_type => |enum_type| { |
| 696 | 695 | var hasher = std.hash.Wyhash.init(seed); |
| 697 | 696 | std.hash.autoHash(&hasher, enum_type.decl); |
| ... | ... | @@ -703,18 +702,7 @@ pub const Key = union(enum) { |
| 703 | 702 | std.hash.autoHash(&hasher, variable.decl); |
| 704 | 703 | return hasher.final(); |
| 705 | 704 | }, |
| 706 | | .extern_func => |extern_func| { |
| 707 | | var hasher = std.hash.Wyhash.init(seed); |
| 708 | | std.hash.autoHash(&hasher, extern_func.ty); |
| 709 | | std.hash.autoHash(&hasher, extern_func.decl); |
| 710 | | return hasher.final(); |
| 711 | | }, |
| 712 | | .func => |func| { |
| 713 | | var hasher = std.hash.Wyhash.init(seed); |
| 714 | | std.hash.autoHash(&hasher, func.ty); |
| 715 | | std.hash.autoHash(&hasher, func.index); |
| 716 | | return hasher.final(); |
| 717 | | }, |
| 705 | .extern_func => |x| WyhashKing.hash(seed, asBytes(&x.ty) ++ asBytes(&x.decl)), |
| 718 | 706 | |
| 719 | 707 | .int => |int| { |
| 720 | 708 | var hasher = std.hash.Wyhash.init(seed); |
| ... | ... | @@ -865,11 +853,7 @@ pub const Key = union(enum) { |
| 865 | 853 | return hasher.final(); |
| 866 | 854 | }, |
| 867 | 855 | |
| 868 | | .memoized_decl => |memoized_decl| { |
| 869 | | var hasher = std.hash.Wyhash.init(seed); |
| 870 | | std.hash.autoHash(&hasher, memoized_decl.val); |
| 871 | | return hasher.final(); |
| 872 | | }, |
| 856 | .memoized_decl => |x| WyhashKing.hash(seed, asBytes(&x.val)), |
| 873 | 857 | |
| 874 | 858 | .memoized_call => |memoized_call| { |
| 875 | 859 | var hasher = std.hash.Wyhash.init(seed); |
| ... | ... | @@ -877,7 +861,7 @@ pub const Key = union(enum) { |
| 877 | 861 | for (memoized_call.arg_values) |arg| std.hash.autoHash(&hasher, arg); |
| 878 | 862 | return hasher.final(); |
| 879 | 863 | }, |
| 880 | | } |
| 864 | }; |
| 881 | 865 | } |
| 882 | 866 | |
| 883 | 867 | pub fn eql(a: Key, b: Key, ip: *const InternPool) bool { |
| ... | ... | @@ -1474,7 +1458,7 @@ pub const Index = enum(u32) { |
| 1474 | 1458 | error_union_error: struct { data: *Key.Error }, |
| 1475 | 1459 | error_union_payload: struct { data: *Tag.TypeValue }, |
| 1476 | 1460 | enum_literal: struct { data: NullTerminatedString }, |
| 1477 | | enum_tag: struct { data: *Key.EnumTag }, |
| 1461 | enum_tag: struct { data: *Tag.EnumTag }, |
| 1478 | 1462 | float_f16: struct { data: f16 }, |
| 1479 | 1463 | float_f32: struct { data: f32 }, |
| 1480 | 1464 | float_f64: struct { data: *Float64 }, |
| ... | ... | @@ -1491,7 +1475,7 @@ pub const Index = enum(u32) { |
| 1491 | 1475 | bytes: struct { data: *Bytes }, |
| 1492 | 1476 | aggregate: struct { |
| 1493 | 1477 | const @"data.ty.data.len orelse data.ty.data.fields_len" = opaque {}; |
| 1494 | | data: *Aggregate, |
| 1478 | data: *Tag.Aggregate, |
| 1495 | 1479 | @"trailing.element_values.len": *@"data.ty.data.len orelse data.ty.data.fields_len", |
| 1496 | 1480 | trailing: struct { element_values: []Index }, |
| 1497 | 1481 | }, |
| ... | ... | @@ -1944,7 +1928,7 @@ pub const Tag = enum(u8) { |
| 1944 | 1928 | /// data is `NullTerminatedString` of the error name. |
| 1945 | 1929 | enum_literal, |
| 1946 | 1930 | /// An enum tag value. |
| 1947 | | /// data is extra index of `Key.EnumTag`. |
| 1931 | /// data is extra index of `EnumTag`. |
| 1948 | 1932 | enum_tag, |
| 1949 | 1933 | /// An f16 value. |
| 1950 | 1934 | /// data is float value bitcasted to u16 and zero-extended. |
| ... | ... | @@ -2121,6 +2105,14 @@ pub const Tag = enum(u8) { |
| 2121 | 2105 | _: u28 = 0, |
| 2122 | 2106 | }; |
| 2123 | 2107 | }; |
| 2108 | |
| 2109 | /// Trailing: |
| 2110 | /// 0. element: Index for each len |
| 2111 | /// len is determined by the aggregate type. |
| 2112 | pub const Aggregate = struct { |
| 2113 | /// The type of the aggregate. |
| 2114 | ty: Index, |
| 2115 | }; |
| 2124 | 2116 | }; |
| 2125 | 2117 | |
| 2126 | 2118 | /// Trailing: |
| ... | ... | @@ -2161,14 +2153,6 @@ pub const Bytes = struct { |
| 2161 | 2153 | bytes: String, |
| 2162 | 2154 | }; |
| 2163 | 2155 | |
| 2164 | | /// Trailing: |
| 2165 | | /// 0. element: Index for each len |
| 2166 | | /// len is determined by the aggregate type. |
| 2167 | | pub const Aggregate = struct { |
| 2168 | | /// The type of the aggregate. |
| 2169 | | ty: Index, |
| 2170 | | }; |
| 2171 | | |
| 2172 | 2156 | pub const Repeated = struct { |
| 2173 | 2157 | /// The type of the aggregate. |
| 2174 | 2158 | ty: Index, |
| ... | ... | @@ -2982,7 +2966,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2982 | 2966 | } }; |
| 2983 | 2967 | }, |
| 2984 | 2968 | .aggregate => { |
| 2985 | | const extra = ip.extraDataTrail(Aggregate, data); |
| 2969 | const extra = ip.extraDataTrail(Tag.Aggregate, data); |
| 2986 | 2970 | const len = @intCast(u32, ip.aggregateTypeLenIncludingSentinel(extra.data.ty)); |
| 2987 | 2971 | const fields = @ptrCast([]const Index, ip.extra.items[extra.end..][0..len]); |
| 2988 | 2972 | return .{ .aggregate = .{ |
| ... | ... | @@ -3014,7 +2998,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 3014 | 2998 | } }; |
| 3015 | 2999 | }, |
| 3016 | 3000 | .enum_literal => .{ .enum_literal = @intToEnum(NullTerminatedString, data) }, |
| 3017 | | .enum_tag => .{ .enum_tag = ip.extraData(Key.EnumTag, data) }, |
| 3001 | .enum_tag => .{ .enum_tag = ip.extraData(Tag.EnumTag, data) }, |
| 3018 | 3002 | |
| 3019 | 3003 | .memoized_decl => .{ .memoized_decl = ip.extraData(Key.MemoizedDecl, data) }, |
| 3020 | 3004 | .memoized_call => { |
| ... | ... | @@ -3989,11 +3973,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3989 | 3973 | |
| 3990 | 3974 | try ip.extra.ensureUnusedCapacity( |
| 3991 | 3975 | gpa, |
| 3992 | | @typeInfo(Aggregate).Struct.fields.len + len_including_sentinel, |
| 3976 | @typeInfo(Tag.Aggregate).Struct.fields.len + len_including_sentinel, |
| 3993 | 3977 | ); |
| 3994 | 3978 | ip.items.appendAssumeCapacity(.{ |
| 3995 | 3979 | .tag = .aggregate, |
| 3996 | | .data = ip.addExtraAssumeCapacity(Aggregate{ |
| 3980 | .data = ip.addExtraAssumeCapacity(Tag.Aggregate{ |
| 3997 | 3981 | .ty = aggregate.ty, |
| 3998 | 3982 | }), |
| 3999 | 3983 | }); |
| ... | ... | @@ -4992,7 +4976,7 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 4992 | 4976 | .error_set_error, .error_union_error => @sizeOf(Key.Error), |
| 4993 | 4977 | .error_union_payload => @sizeOf(Tag.TypeValue), |
| 4994 | 4978 | .enum_literal => 0, |
| 4995 | | .enum_tag => @sizeOf(Key.EnumTag), |
| 4979 | .enum_tag => @sizeOf(Tag.EnumTag), |
| 4996 | 4980 | |
| 4997 | 4981 | .bytes => b: { |
| 4998 | 4982 | const info = ip.extraData(Bytes, data); |
| ... | ... | @@ -5001,9 +4985,9 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 5001 | 4985 | @boolToInt(ip.string_bytes.items[@enumToInt(info.bytes) + len - 1] != 0); |
| 5002 | 4986 | }, |
| 5003 | 4987 | .aggregate => b: { |
| 5004 | | const info = ip.extraData(Aggregate, data); |
| 4988 | const info = ip.extraData(Tag.Aggregate, data); |
| 5005 | 4989 | const fields_len = @intCast(u32, ip.aggregateTypeLenIncludingSentinel(info.ty)); |
| 5006 | | break :b @sizeOf(Aggregate) + (@sizeOf(Index) * fields_len); |
| 4990 | break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len); |
| 5007 | 4991 | }, |
| 5008 | 4992 | .repeated => @sizeOf(Repeated), |
| 5009 | 4993 | |