| ... | ... | @@ -2783,20 +2783,22 @@ pub const LoadedStructType = struct { |
| 2783 | 2783 | } |
| 2784 | 2784 | |
| 2785 | 2785 | pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool { |
| 2786 | | switch (s.layout) { |
| 2787 | | .@"packed" => { |
| 2788 | | const flag = &s.packedFlagsPtr(ip).field_inits_wip; |
| 2789 | | if (flag.*) return true; |
| 2790 | | flag.* = true; |
| 2791 | | return false; |
| 2792 | | }, |
| 2793 | | .auto, .@"extern" => { |
| 2794 | | const flag = &s.flagsPtr(ip).field_inits_wip; |
| 2795 | | if (flag.*) return true; |
| 2796 | | flag.* = true; |
| 2797 | | return false; |
| 2798 | | }, |
| 2799 | | } |
| 2786 | return switch (s.layout) { |
| 2787 | .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw( |
| 2788 | u32, |
| 2789 | @as(*u32, @ptrCast(s.packedFlagsPtr(ip))), |
| 2790 | .Or, |
| 2791 | @bitCast(Tag.TypeStructPacked.Flags{ .field_inits_wip = true }), |
| 2792 | .acq_rel, |
| 2793 | ))).field_inits_wip, |
| 2794 | .auto, .@"extern" => @as(Tag.TypeStruct.Flags, @bitCast(@atomicRmw( |
| 2795 | u32, |
| 2796 | @as(*u32, @ptrCast(s.flagsPtr(ip))), |
| 2797 | .Or, |
| 2798 | @bitCast(Tag.TypeStruct.Flags{ .field_inits_wip = true }), |
| 2799 | .acq_rel, |
| 2800 | ))).field_inits_wip, |
| 2801 | }; |
| 2800 | 2802 | } |
| 2801 | 2803 | |
| 2802 | 2804 | pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void { |
| ... | ... | @@ -2962,6 +2964,7 @@ pub const LoadedStructType = struct { |
| 2962 | 2964 | pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 2963 | 2965 | const unwrapped_index = index.unwrap(ip); |
| 2964 | 2966 | const extra_list = unwrapped_index.getExtra(ip); |
| 2967 | const extra_items = extra_list.view().items(.@"0"); |
| 2965 | 2968 | const item = unwrapped_index.getItem(ip); |
| 2966 | 2969 | switch (item.tag) { |
| 2967 | 2970 | .type_struct => { |
| ... | ... | @@ -2982,10 +2985,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 2982 | 2985 | .names_map = .none, |
| 2983 | 2986 | .captures = CaptureValue.Slice.empty, |
| 2984 | 2987 | }; |
| 2985 | | const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data); |
| 2986 | | const fields_len = extra.data.fields_len; |
| 2987 | | var extra_index = extra.end; |
| 2988 | | const captures_len = if (extra.data.flags.any_captures) c: { |
| 2988 | const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]); |
| 2989 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]); |
| 2990 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?]; |
| 2991 | const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic)); |
| 2992 | var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len); |
| 2993 | const captures_len = if (flags.any_captures) c: { |
| 2989 | 2994 | const len = extra_list.view().items(.@"0")[extra_index]; |
| 2990 | 2995 | extra_index += 1; |
| 2991 | 2996 | break :c len; |
| ... | ... | @@ -2996,7 +3001,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 2996 | 3001 | .len = captures_len, |
| 2997 | 3002 | }; |
| 2998 | 3003 | extra_index += captures_len; |
| 2999 | | if (extra.data.flags.is_reified) { |
| 3004 | if (flags.is_reified) { |
| 3000 | 3005 | extra_index += 2; // PackedU64 |
| 3001 | 3006 | } |
| 3002 | 3007 | const field_types: Index.Slice = .{ |
| ... | ... | @@ -3005,7 +3010,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3005 | 3010 | .len = fields_len, |
| 3006 | 3011 | }; |
| 3007 | 3012 | extra_index += fields_len; |
| 3008 | | const names_map: OptionalMapIndex, const names = if (!extra.data.flags.is_tuple) n: { |
| 3013 | const names_map: OptionalMapIndex, const names = if (!flags.is_tuple) n: { |
| 3009 | 3014 | const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); |
| 3010 | 3015 | extra_index += 1; |
| 3011 | 3016 | const names: NullTerminatedString.Slice = .{ |
| ... | ... | @@ -3016,7 +3021,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3016 | 3021 | extra_index += fields_len; |
| 3017 | 3022 | break :n .{ names_map, names }; |
| 3018 | 3023 | } else .{ .none, NullTerminatedString.Slice.empty }; |
| 3019 | | const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: { |
| 3024 | const inits: Index.Slice = if (flags.any_default_inits) i: { |
| 3020 | 3025 | const inits: Index.Slice = .{ |
| 3021 | 3026 | .tid = unwrapped_index.tid, |
| 3022 | 3027 | .start = extra_index, |
| ... | ... | @@ -3025,12 +3030,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3025 | 3030 | extra_index += fields_len; |
| 3026 | 3031 | break :i inits; |
| 3027 | 3032 | } else Index.Slice.empty; |
| 3028 | | const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: { |
| 3033 | const namespace: OptionalNamespaceIndex = if (flags.has_namespace) n: { |
| 3029 | 3034 | const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); |
| 3030 | 3035 | extra_index += 1; |
| 3031 | 3036 | break :n n.toOptional(); |
| 3032 | 3037 | } else .none; |
| 3033 | | const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: { |
| 3038 | const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: { |
| 3034 | 3039 | const a: Alignment.Slice = .{ |
| 3035 | 3040 | .tid = unwrapped_index.tid, |
| 3036 | 3041 | .start = extra_index, |
| ... | ... | @@ -3039,7 +3044,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3039 | 3044 | extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable; |
| 3040 | 3045 | break :a a; |
| 3041 | 3046 | } else Alignment.Slice.empty; |
| 3042 | | const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: { |
| 3047 | const comptime_bits: LoadedStructType.ComptimeBits = if (flags.any_comptime_fields) c: { |
| 3043 | 3048 | const len = std.math.divCeil(u32, fields_len, 32) catch unreachable; |
| 3044 | 3049 | const c: LoadedStructType.ComptimeBits = .{ |
| 3045 | 3050 | .tid = unwrapped_index.tid, |
| ... | ... | @@ -3049,7 +3054,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3049 | 3054 | extra_index += len; |
| 3050 | 3055 | break :c c; |
| 3051 | 3056 | } else LoadedStructType.ComptimeBits.empty; |
| 3052 | | const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: { |
| 3057 | const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!flags.is_extern) ro: { |
| 3053 | 3058 | const ro: LoadedStructType.RuntimeOrder.Slice = .{ |
| 3054 | 3059 | .tid = unwrapped_index.tid, |
| 3055 | 3060 | .start = extra_index, |
| ... | ... | @@ -3070,10 +3075,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3070 | 3075 | return .{ |
| 3071 | 3076 | .tid = unwrapped_index.tid, |
| 3072 | 3077 | .extra_index = item.data, |
| 3073 | | .decl = extra.data.decl.toOptional(), |
| 3078 | .decl = decl.toOptional(), |
| 3074 | 3079 | .namespace = namespace, |
| 3075 | | .zir_index = extra.data.zir_index.toOptional(), |
| 3076 | | .layout = if (extra.data.flags.is_extern) .@"extern" else .auto, |
| 3080 | .zir_index = zir_index.toOptional(), |
| 3081 | .layout = if (flags.is_extern) .@"extern" else .auto, |
| 3077 | 3082 | .field_names = names, |
| 3078 | 3083 | .field_types = field_types, |
| 3079 | 3084 | .field_inits = inits, |
| ... | ... | @@ -3086,11 +3091,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3086 | 3091 | }; |
| 3087 | 3092 | }, |
| 3088 | 3093 | .type_struct_packed, .type_struct_packed_inits => { |
| 3089 | | const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data); |
| 3094 | const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]); |
| 3095 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]); |
| 3096 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?]; |
| 3097 | const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]); |
| 3098 | const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]); |
| 3099 | const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic)); |
| 3100 | var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len); |
| 3090 | 3101 | const has_inits = item.tag == .type_struct_packed_inits; |
| 3091 | | const fields_len = extra.data.fields_len; |
| 3092 | | var extra_index = extra.end; |
| 3093 | | const captures_len = if (extra.data.flags.any_captures) c: { |
| 3102 | const captures_len = if (flags.any_captures) c: { |
| 3094 | 3103 | const len = extra_list.view().items(.@"0")[extra_index]; |
| 3095 | 3104 | extra_index += 1; |
| 3096 | 3105 | break :c len; |
| ... | ... | @@ -3101,7 +3110,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3101 | 3110 | .len = captures_len, |
| 3102 | 3111 | }; |
| 3103 | 3112 | extra_index += captures_len; |
| 3104 | | if (extra.data.flags.is_reified) { |
| 3113 | if (flags.is_reified) { |
| 3105 | 3114 | extra_index += 2; // PackedU64 |
| 3106 | 3115 | } |
| 3107 | 3116 | const field_types: Index.Slice = .{ |
| ... | ... | @@ -3128,9 +3137,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3128 | 3137 | return .{ |
| 3129 | 3138 | .tid = unwrapped_index.tid, |
| 3130 | 3139 | .extra_index = item.data, |
| 3131 | | .decl = extra.data.decl.toOptional(), |
| 3132 | | .namespace = extra.data.namespace, |
| 3133 | | .zir_index = extra.data.zir_index.toOptional(), |
| 3140 | .decl = decl.toOptional(), |
| 3141 | .namespace = namespace, |
| 3142 | .zir_index = zir_index.toOptional(), |
| 3134 | 3143 | .layout = .@"packed", |
| 3135 | 3144 | .field_names = field_names, |
| 3136 | 3145 | .field_types = field_types, |
| ... | ... | @@ -3139,7 +3148,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3139 | 3148 | .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty, |
| 3140 | 3149 | .comptime_bits = LoadedStructType.ComptimeBits.empty, |
| 3141 | 3150 | .offsets = LoadedStructType.Offsets.empty, |
| 3142 | | .names_map = extra.data.names_map.toOptional(), |
| 3151 | .names_map = names_map.toOptional(), |
| 3143 | 3152 | .captures = captures, |
| 3144 | 3153 | }; |
| 3145 | 3154 | }, |
| ... | ... | @@ -4476,11 +4485,11 @@ pub const Tag = enum(u8) { |
| 4476 | 4485 | flags: Flags, |
| 4477 | 4486 | |
| 4478 | 4487 | pub const Flags = packed struct(u32) { |
| 4479 | | any_captures: bool, |
| 4488 | any_captures: bool = false, |
| 4480 | 4489 | /// Dependency loop detection when resolving field inits. |
| 4481 | | field_inits_wip: bool, |
| 4482 | | inits_resolved: bool, |
| 4483 | | is_reified: bool, |
| 4490 | field_inits_wip: bool = false, |
| 4491 | inits_resolved: bool = false, |
| 4492 | is_reified: bool = false, |
| 4484 | 4493 | _: u28 = 0, |
| 4485 | 4494 | }; |
| 4486 | 4495 | }; |
| ... | ... | @@ -4526,36 +4535,36 @@ pub const Tag = enum(u8) { |
| 4526 | 4535 | size: u32, |
| 4527 | 4536 | |
| 4528 | 4537 | pub const Flags = packed struct(u32) { |
| 4529 | | any_captures: bool, |
| 4530 | | is_extern: bool, |
| 4531 | | known_non_opv: bool, |
| 4532 | | requires_comptime: RequiresComptime, |
| 4533 | | is_tuple: bool, |
| 4534 | | assumed_runtime_bits: bool, |
| 4535 | | assumed_pointer_aligned: bool, |
| 4536 | | has_namespace: bool, |
| 4537 | | any_comptime_fields: bool, |
| 4538 | | any_default_inits: bool, |
| 4539 | | any_aligned_fields: bool, |
| 4538 | any_captures: bool = false, |
| 4539 | is_extern: bool = false, |
| 4540 | known_non_opv: bool = false, |
| 4541 | requires_comptime: RequiresComptime = @enumFromInt(0), |
| 4542 | is_tuple: bool = false, |
| 4543 | assumed_runtime_bits: bool = false, |
| 4544 | assumed_pointer_aligned: bool = false, |
| 4545 | has_namespace: bool = false, |
| 4546 | any_comptime_fields: bool = false, |
| 4547 | any_default_inits: bool = false, |
| 4548 | any_aligned_fields: bool = false, |
| 4540 | 4549 | /// `.none` until layout_resolved |
| 4541 | | alignment: Alignment, |
| 4550 | alignment: Alignment = @enumFromInt(0), |
| 4542 | 4551 | /// Dependency loop detection when resolving struct alignment. |
| 4543 | | alignment_wip: bool, |
| 4552 | alignment_wip: bool = false, |
| 4544 | 4553 | /// Dependency loop detection when resolving field types. |
| 4545 | | field_types_wip: bool, |
| 4554 | field_types_wip: bool = false, |
| 4546 | 4555 | /// Dependency loop detection when resolving struct layout. |
| 4547 | | layout_wip: bool, |
| 4556 | layout_wip: bool = false, |
| 4548 | 4557 | /// Indicates whether `size`, `alignment`, runtime field order, and |
| 4549 | 4558 | /// field offets are populated. |
| 4550 | | layout_resolved: bool, |
| 4559 | layout_resolved: bool = false, |
| 4551 | 4560 | /// Dependency loop detection when resolving field inits. |
| 4552 | | field_inits_wip: bool, |
| 4561 | field_inits_wip: bool = false, |
| 4553 | 4562 | /// Indicates whether `field_inits` has been resolved. |
| 4554 | | inits_resolved: bool, |
| 4555 | | // The types and all its fields have had their layout resolved. Even through pointer, |
| 4563 | inits_resolved: bool = false, |
| 4564 | // The types and all its fields have had their layout resolved. Even through pointer = false, |
| 4556 | 4565 | // which `layout_resolved` does not ensure. |
| 4557 | | fully_resolved: bool, |
| 4558 | | is_reified: bool, |
| 4566 | fully_resolved: bool = false, |
| 4567 | is_reified: bool = false, |
| 4559 | 4568 | _: u6 = 0, |
| 4560 | 4569 | }; |
| 4561 | 4570 | }; |
| ... | ... | @@ -5400,40 +5409,46 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 5400 | 5409 | .type_struct => .{ .struct_type = ns: { |
| 5401 | 5410 | if (data == 0) break :ns .empty_struct; |
| 5402 | 5411 | const extra_list = unwrapped_index.getExtra(ip); |
| 5403 | | const extra = extraDataTrail(extra_list, Tag.TypeStruct, data); |
| 5404 | | if (extra.data.flags.is_reified) { |
| 5405 | | assert(!extra.data.flags.any_captures); |
| 5412 | const extra_items = extra_list.view().items(.@"0"); |
| 5413 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]); |
| 5414 | const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic)); |
| 5415 | const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len); |
| 5416 | if (flags.is_reified) { |
| 5417 | assert(!flags.any_captures); |
| 5406 | 5418 | break :ns .{ .reified = .{ |
| 5407 | | .zir_index = extra.data.zir_index, |
| 5408 | | .type_hash = extraData(extra_list, PackedU64, extra.end).get(), |
| 5419 | .zir_index = zir_index, |
| 5420 | .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(), |
| 5409 | 5421 | } }; |
| 5410 | 5422 | } |
| 5411 | 5423 | break :ns .{ .declared = .{ |
| 5412 | | .zir_index = extra.data.zir_index, |
| 5413 | | .captures = .{ .owned = if (extra.data.flags.any_captures) .{ |
| 5424 | .zir_index = zir_index, |
| 5425 | .captures = .{ .owned = if (flags.any_captures) .{ |
| 5414 | 5426 | .tid = unwrapped_index.tid, |
| 5415 | | .start = extra.end + 1, |
| 5416 | | .len = extra_list.view().items(.@"0")[extra.end], |
| 5427 | .start = end_extra_index + 1, |
| 5428 | .len = extra_list.view().items(.@"0")[end_extra_index], |
| 5417 | 5429 | } else CaptureValue.Slice.empty }, |
| 5418 | 5430 | } }; |
| 5419 | 5431 | } }, |
| 5420 | 5432 | |
| 5421 | 5433 | .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: { |
| 5422 | 5434 | const extra_list = unwrapped_index.getExtra(ip); |
| 5423 | | const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data); |
| 5424 | | if (extra.data.flags.is_reified) { |
| 5425 | | assert(!extra.data.flags.any_captures); |
| 5435 | const extra_items = extra_list.view().items(.@"0"); |
| 5436 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]); |
| 5437 | const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic)); |
| 5438 | const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len); |
| 5439 | if (flags.is_reified) { |
| 5440 | assert(!flags.any_captures); |
| 5426 | 5441 | break :ns .{ .reified = .{ |
| 5427 | | .zir_index = extra.data.zir_index, |
| 5428 | | .type_hash = extraData(extra_list, PackedU64, extra.end).get(), |
| 5442 | .zir_index = zir_index, |
| 5443 | .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(), |
| 5429 | 5444 | } }; |
| 5430 | 5445 | } |
| 5431 | 5446 | break :ns .{ .declared = .{ |
| 5432 | | .zir_index = extra.data.zir_index, |
| 5433 | | .captures = .{ .owned = if (extra.data.flags.any_captures) .{ |
| 5447 | .zir_index = zir_index, |
| 5448 | .captures = .{ .owned = if (flags.any_captures) .{ |
| 5434 | 5449 | .tid = unwrapped_index.tid, |
| 5435 | | .start = extra.end + 1, |
| 5436 | | .len = extra_list.view().items(.@"0")[extra.end], |
| 5450 | .start = end_extra_index + 1, |
| 5451 | .len = extra_items[end_extra_index], |
| 5437 | 5452 | } else CaptureValue.Slice.empty }, |
| 5438 | 5453 | } }; |
| 5439 | 5454 | } }, |