| ... | @@ -576,8 +576,8 @@ pub const Key = union(enum) { | ... | @@ -576,8 +576,8 @@ pub const Key = union(enum) { |
| 576 | return s.layout != .Packed and s.flagsPtr(ip).is_tuple; | 576 | return s.layout != .Packed and s.flagsPtr(ip).is_tuple; |
| 577 | } | 577 | } |
| 578 | | 578 | |
| 579 | pub fn hasReorderedFields(s: @This(), ip: *InternPool) bool { | 579 | pub fn hasReorderedFields(s: @This()) bool { |
| 580 | return s.layout == .Auto and s.flagsPtr(ip).has_reordered_fields; | 580 | return s.layout == .Auto; |
| 581 | } | 581 | } |
| 582 | | 582 | |
| 583 | pub const RuntimeOrderIterator = struct { | 583 | pub const RuntimeOrderIterator = struct { |
| ... | @@ -591,7 +591,7 @@ pub const Key = union(enum) { | ... | @@ -591,7 +591,7 @@ pub const Key = union(enum) { |
| 591 | if (i >= it.struct_type.field_types.len) | 591 | if (i >= it.struct_type.field_types.len) |
| 592 | return null; | 592 | return null; |
| 593 | | 593 | |
| 594 | if (it.struct_type.hasReorderedFields(it.ip)) { | 594 | if (it.struct_type.hasReorderedFields()) { |
| 595 | it.field_index += 1; | 595 | it.field_index += 1; |
| 596 | return it.struct_type.runtime_order.get(it.ip)[i].toInt(); | 596 | return it.struct_type.runtime_order.get(it.ip)[i].toInt(); |
| 597 | } | 597 | } |
| ... | @@ -2935,7 +2935,7 @@ pub const Tag = enum(u8) { | ... | @@ -2935,7 +2935,7 @@ pub const Tag = enum(u8) { |
| 2935 | /// align: Alignment // for each field in declared order | 2935 | /// align: Alignment // for each field in declared order |
| 2936 | /// 5. if any_comptime_fields: | 2936 | /// 5. if any_comptime_fields: |
| 2937 | /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0 | 2937 | /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0 |
| 2938 | /// 6. if has_reordered_fields: | 2938 | /// 6. if not is_extern: |
| 2939 | /// field_index: RuntimeOrder // for each field in runtime order | 2939 | /// field_index: RuntimeOrder // for each field in runtime order |
| 2940 | /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved | 2940 | /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved |
| 2941 | pub const TypeStruct = struct { | 2941 | pub const TypeStruct = struct { |
| ... | @@ -2946,14 +2946,12 @@ pub const Tag = enum(u8) { | ... | @@ -2946,14 +2946,12 @@ pub const Tag = enum(u8) { |
| 2946 | size: u32, | 2946 | size: u32, |
| 2947 | | 2947 | |
| 2948 | pub const Flags = packed struct(u32) { | 2948 | pub const Flags = packed struct(u32) { |
| 2949 | has_runtime_order: bool, | | |
| 2950 | is_extern: bool, | 2949 | is_extern: bool, |
| 2951 | known_non_opv: bool, | 2950 | known_non_opv: bool, |
| 2952 | requires_comptime: RequiresComptime, | 2951 | requires_comptime: RequiresComptime, |
| 2953 | is_tuple: bool, | 2952 | is_tuple: bool, |
| 2954 | assumed_runtime_bits: bool, | 2953 | assumed_runtime_bits: bool, |
| 2955 | has_namespace: bool, | 2954 | has_namespace: bool, |
| 2956 | has_reordered_fields: bool, | | |
| 2957 | any_comptime_fields: bool, | 2955 | any_comptime_fields: bool, |
| 2958 | any_default_inits: bool, | 2956 | any_default_inits: bool, |
| 2959 | any_aligned_fields: bool, | 2957 | any_aligned_fields: bool, |
| ... | @@ -2970,7 +2968,7 @@ pub const Tag = enum(u8) { | ... | @@ -2970,7 +2968,7 @@ pub const Tag = enum(u8) { |
| 2970 | // which `layout_resolved` does not ensure. | 2968 | // which `layout_resolved` does not ensure. |
| 2971 | fully_resolved: bool, | 2969 | fully_resolved: bool, |
| 2972 | | 2970 | |
| 2973 | _: u10 = 0, | 2971 | _: u12 = 0, |
| 2974 | }; | 2972 | }; |
| 2975 | }; | 2973 | }; |
| 2976 | }; | 2974 | }; |
| ... | @@ -5092,6 +5090,9 @@ pub const StructTypeInit = struct { | ... | @@ -5092,6 +5090,9 @@ pub const StructTypeInit = struct { |
| 5092 | known_non_opv: bool, | 5090 | known_non_opv: bool, |
| 5093 | requires_comptime: RequiresComptime, | 5091 | requires_comptime: RequiresComptime, |
| 5094 | is_tuple: bool, | 5092 | is_tuple: bool, |
| | 5093 | any_comptime_fields: bool, |
| | 5094 | any_default_inits: bool, |
| | 5095 | any_aligned_fields: bool, |
| 5095 | }; | 5096 | }; |
| 5096 | | 5097 | |
| 5097 | pub fn getStructType( | 5098 | pub fn getStructType( |
| ... | @@ -5099,10 +5100,116 @@ pub fn getStructType( | ... | @@ -5099,10 +5100,116 @@ pub fn getStructType( |
| 5099 | gpa: Allocator, | 5100 | gpa: Allocator, |
| 5100 | ini: StructTypeInit, | 5101 | ini: StructTypeInit, |
| 5101 | ) Allocator.Error!Index { | 5102 | ) Allocator.Error!Index { |
| 5102 | _ = ip; | 5103 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| 5103 | _ = gpa; | 5104 | const key: Key = .{ |
| 5104 | _ = ini; | 5105 | .struct_type = .{ |
| 5105 | @panic("TODO"); | 5106 | // Only the decl matters for hashing and equality purposes. |
| | 5107 | .decl = ini.decl.toOptional(), |
| | 5108 | |
| | 5109 | .extra_index = undefined, |
| | 5110 | .namespace = undefined, |
| | 5111 | .zir_index = undefined, |
| | 5112 | .layout = undefined, |
| | 5113 | .field_names = undefined, |
| | 5114 | .field_types = undefined, |
| | 5115 | .field_inits = undefined, |
| | 5116 | .field_aligns = undefined, |
| | 5117 | .runtime_order = undefined, |
| | 5118 | .comptime_bits = undefined, |
| | 5119 | .offsets = undefined, |
| | 5120 | .names_map = undefined, |
| | 5121 | }, |
| | 5122 | }; |
| | 5123 | const gop = try ip.map.getOrPutAdapted(gpa, key, adapter); |
| | 5124 | if (gop.found_existing) return @enumFromInt(gop.index); |
| | 5125 | errdefer _ = ip.map.pop(); |
| | 5126 | |
| | 5127 | const names_map = try ip.addMap(gpa, ini.fields_len); |
| | 5128 | errdefer _ = ip.maps.pop(); |
| | 5129 | |
| | 5130 | const is_extern = switch (ini.layout) { |
| | 5131 | .Auto => false, |
| | 5132 | .Extern => true, |
| | 5133 | .Packed => { |
| | 5134 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len + |
| | 5135 | ini.fields_len + // types |
| | 5136 | ini.fields_len + // names |
| | 5137 | ini.fields_len); // inits |
| | 5138 | try ip.items.append(gpa, .{ |
| | 5139 | .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed, |
| | 5140 | .data = ip.addExtraAssumeCapacity(Tag.TypeStructPacked{ |
| | 5141 | .decl = ini.decl, |
| | 5142 | .zir_index = ini.zir_index, |
| | 5143 | .fields_len = ini.fields_len, |
| | 5144 | .namespace = ini.namespace, |
| | 5145 | .backing_int_ty = .none, |
| | 5146 | .names_map = names_map, |
| | 5147 | }), |
| | 5148 | }); |
| | 5149 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); |
| | 5150 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len); |
| | 5151 | if (ini.any_default_inits) { |
| | 5152 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); |
| | 5153 | } |
| | 5154 | return @enumFromInt(ip.items.len - 1); |
| | 5155 | }, |
| | 5156 | }; |
| | 5157 | |
| | 5158 | const align_elements_len = if (ini.any_aligned_fields) (ini.fields_len + 3) / 4 else 0; |
| | 5159 | const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4); |
| | 5160 | const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0; |
| | 5161 | |
| | 5162 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStruct).Struct.fields.len + |
| | 5163 | (ini.fields_len * 5) + // types, names, inits, runtime order, offsets |
| | 5164 | align_elements_len + comptime_elements_len + |
| | 5165 | 2); // names_map + namespace |
| | 5166 | try ip.items.append(gpa, .{ |
| | 5167 | .tag = .type_struct, |
| | 5168 | .data = ip.addExtraAssumeCapacity(Tag.TypeStruct{ |
| | 5169 | .decl = ini.decl, |
| | 5170 | .zir_index = ini.zir_index, |
| | 5171 | .fields_len = ini.fields_len, |
| | 5172 | .size = std.math.maxInt(u32), |
| | 5173 | .flags = .{ |
| | 5174 | .is_extern = is_extern, |
| | 5175 | .known_non_opv = ini.known_non_opv, |
| | 5176 | .requires_comptime = ini.requires_comptime, |
| | 5177 | .is_tuple = ini.is_tuple, |
| | 5178 | .assumed_runtime_bits = false, |
| | 5179 | .has_namespace = ini.namespace != .none, |
| | 5180 | .any_comptime_fields = ini.any_comptime_fields, |
| | 5181 | .any_default_inits = ini.any_default_inits, |
| | 5182 | .any_aligned_fields = ini.any_aligned_fields, |
| | 5183 | .alignment = .none, |
| | 5184 | .field_types_wip = false, |
| | 5185 | .layout_wip = false, |
| | 5186 | .layout_resolved = false, |
| | 5187 | .fully_resolved = false, |
| | 5188 | }, |
| | 5189 | }), |
| | 5190 | }); |
| | 5191 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); |
| | 5192 | if (!ini.is_tuple) { |
| | 5193 | ip.extra.appendAssumeCapacity(@intFromEnum(names_map)); |
| | 5194 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len); |
| | 5195 | } |
| | 5196 | if (ini.any_default_inits) { |
| | 5197 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); |
| | 5198 | } |
| | 5199 | if (ini.namespace.unwrap()) |namespace| { |
| | 5200 | ip.extra.appendAssumeCapacity(@intFromEnum(namespace)); |
| | 5201 | } |
| | 5202 | if (ini.any_aligned_fields) { |
| | 5203 | ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len); |
| | 5204 | } |
| | 5205 | if (ini.any_comptime_fields) { |
| | 5206 | ip.extra.appendNTimesAssumeCapacity(0, comptime_elements_len); |
| | 5207 | } |
| | 5208 | if (ini.layout == .Auto) { |
| | 5209 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Key.StructType.RuntimeOrder.unresolved), ini.fields_len); |
| | 5210 | } |
| | 5211 | ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len); |
| | 5212 | return @enumFromInt(ip.items.len - 1); |
| 5106 | } | 5213 | } |
| 5107 | | 5214 | |
| 5108 | pub const AnonStructTypeInit = struct { | 5215 | pub const AnonStructTypeInit = struct { |
| ... | @@ -5468,6 +5575,7 @@ pub fn getErrorSetType( | ... | @@ -5468,6 +5575,7 @@ pub fn getErrorSetType( |
| 5468 | errdefer ip.items.len -= 1; | 5575 | errdefer ip.items.len -= 1; |
| 5469 | | 5576 | |
| 5470 | const names_map = try ip.addMap(gpa, names.len); | 5577 | const names_map = try ip.addMap(gpa, names.len); |
| | 5578 | assert(names_map == predicted_names_map); |
| 5471 | errdefer _ = ip.maps.pop(); | 5579 | errdefer _ = ip.maps.pop(); |
| 5472 | | 5580 | |
| 5473 | addStringsToMap(ip, names_map, names); | 5581 | addStringsToMap(ip, names_map, names); |
| ... | @@ -6846,7 +6954,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -6846,7 +6954,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 6846 | ints += (info.fields_len + 3) / 4; // aligns | 6954 | ints += (info.fields_len + 3) / 4; // aligns |
| 6847 | if (info.flags.any_comptime_fields) | 6955 | if (info.flags.any_comptime_fields) |
| 6848 | ints += (info.fields_len + 31) / 32; // comptime bits | 6956 | ints += (info.fields_len + 31) / 32; // comptime bits |
| 6849 | if (info.flags.has_reordered_fields) | 6957 | if (!info.flags.is_extern) |
| 6850 | ints += info.fields_len; // runtime order | 6958 | ints += info.fields_len; // runtime order |
| 6851 | ints += info.fields_len; // offsets | 6959 | ints += info.fields_len; // offsets |
| 6852 | break :b @sizeOf(u32) * ints; | 6960 | break :b @sizeOf(u32) * ints; |