| ... | ... | @@ -576,8 +576,8 @@ pub const Key = union(enum) { |
| 576 | 576 | return s.layout != .Packed and s.flagsPtr(ip).is_tuple; |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | | pub fn hasReorderedFields(s: @This(), ip: *InternPool) bool { |
| 580 | | return s.layout == .Auto and s.flagsPtr(ip).has_reordered_fields; |
| 579 | pub fn hasReorderedFields(s: @This()) bool { |
| 580 | return s.layout == .Auto; |
| 581 | 581 | } |
| 582 | 582 | |
| 583 | 583 | pub const RuntimeOrderIterator = struct { |
| ... | ... | @@ -591,7 +591,7 @@ pub const Key = union(enum) { |
| 591 | 591 | if (i >= it.struct_type.field_types.len) |
| 592 | 592 | return null; |
| 593 | 593 | |
| 594 | | if (it.struct_type.hasReorderedFields(it.ip)) { |
| 594 | if (it.struct_type.hasReorderedFields()) { |
| 595 | 595 | it.field_index += 1; |
| 596 | 596 | return it.struct_type.runtime_order.get(it.ip)[i].toInt(); |
| 597 | 597 | } |
| ... | ... | @@ -2935,7 +2935,7 @@ pub const Tag = enum(u8) { |
| 2935 | 2935 | /// align: Alignment // for each field in declared order |
| 2936 | 2936 | /// 5. if any_comptime_fields: |
| 2937 | 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 | 2939 | /// field_index: RuntimeOrder // for each field in runtime order |
| 2940 | 2940 | /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved |
| 2941 | 2941 | pub const TypeStruct = struct { |
| ... | ... | @@ -2946,14 +2946,12 @@ pub const Tag = enum(u8) { |
| 2946 | 2946 | size: u32, |
| 2947 | 2947 | |
| 2948 | 2948 | pub const Flags = packed struct(u32) { |
| 2949 | | has_runtime_order: bool, |
| 2950 | 2949 | is_extern: bool, |
| 2951 | 2950 | known_non_opv: bool, |
| 2952 | 2951 | requires_comptime: RequiresComptime, |
| 2953 | 2952 | is_tuple: bool, |
| 2954 | 2953 | assumed_runtime_bits: bool, |
| 2955 | 2954 | has_namespace: bool, |
| 2956 | | has_reordered_fields: bool, |
| 2957 | 2955 | any_comptime_fields: bool, |
| 2958 | 2956 | any_default_inits: bool, |
| 2959 | 2957 | any_aligned_fields: bool, |
| ... | ... | @@ -2970,7 +2968,7 @@ pub const Tag = enum(u8) { |
| 2970 | 2968 | // which `layout_resolved` does not ensure. |
| 2971 | 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 | 5090 | known_non_opv: bool, |
| 5093 | 5091 | requires_comptime: RequiresComptime, |
| 5094 | 5092 | is_tuple: bool, |
| 5093 | any_comptime_fields: bool, |
| 5094 | any_default_inits: bool, |
| 5095 | any_aligned_fields: bool, |
| 5095 | 5096 | }; |
| 5096 | 5097 | |
| 5097 | 5098 | pub fn getStructType( |
| ... | ... | @@ -5099,10 +5100,116 @@ pub fn getStructType( |
| 5099 | 5100 | gpa: Allocator, |
| 5100 | 5101 | ini: StructTypeInit, |
| 5101 | 5102 | ) Allocator.Error!Index { |
| 5102 | | _ = ip; |
| 5103 | | _ = gpa; |
| 5104 | | _ = ini; |
| 5105 | | @panic("TODO"); |
| 5103 | const adapter: KeyAdapter = .{ .intern_pool = ip }; |
| 5104 | const key: Key = .{ |
| 5105 | .struct_type = .{ |
| 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 | 5215 | pub const AnonStructTypeInit = struct { |
| ... | ... | @@ -5468,6 +5575,7 @@ pub fn getErrorSetType( |
| 5468 | 5575 | errdefer ip.items.len -= 1; |
| 5469 | 5576 | |
| 5470 | 5577 | const names_map = try ip.addMap(gpa, names.len); |
| 5578 | assert(names_map == predicted_names_map); |
| 5471 | 5579 | errdefer _ = ip.maps.pop(); |
| 5472 | 5580 | |
| 5473 | 5581 | addStringsToMap(ip, names_map, names); |
| ... | ... | @@ -6846,7 +6954,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 6846 | 6954 | ints += (info.fields_len + 3) / 4; // aligns |
| 6847 | 6955 | if (info.flags.any_comptime_fields) |
| 6848 | 6956 | ints += (info.fields_len + 31) / 32; // comptime bits |
| 6849 | | if (info.flags.has_reordered_fields) |
| 6957 | if (!info.flags.is_extern) |
| 6850 | 6958 | ints += info.fields_len; // runtime order |
| 6851 | 6959 | ints += info.fields_len; // offsets |
| 6852 | 6960 | break :b @sizeOf(u32) * ints; |