authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-10 10:04:33-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-10 11:20:08-04:00
log3d2dfbe8289c2ecb45e1ba1fe79c4d7e21dd26c3
tree921e81c14c12e84cf4970a299b37d2a659c63c2f
parentf93a10f664fbbb67aeda031583a790e2a842fb01

InternPool: add `FileIndex` to `*File` mapping


7 files changed, 314 insertions(+), 251 deletions(-)

src/Compilation.zig+22-19
...@@ -2119,12 +2119,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2119,12 +2119,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2119 }2119 }
21202120
2121 if (comp.module) |zcu| {2121 if (comp.module) |zcu| {
2122 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main };
2123
2122 zcu.compile_log_text.shrinkAndFree(gpa, 0);2124 zcu.compile_log_text.shrinkAndFree(gpa, 0);
21232125
2124 // Make sure std.zig is inside the import_table. We unconditionally need2126 // Make sure std.zig is inside the import_table. We unconditionally need
2125 // it for start.zig.2127 // it for start.zig.
2126 const std_mod = zcu.std_mod;2128 const std_mod = zcu.std_mod;
2127 _ = try zcu.importPkg(std_mod);2129 _ = try pt.importPkg(std_mod);
21282130
2129 // Normally we rely on importing std to in turn import the root source file2131 // Normally we rely on importing std to in turn import the root source file
2130 // in the start code, but when using the stage1 backend that won't happen,2132 // in the start code, but when using the stage1 backend that won't happen,
...@@ -2133,20 +2135,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2133,20 +2135,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2133 // Likewise, in the case of `zig test`, the test runner is the root source file,2135 // Likewise, in the case of `zig test`, the test runner is the root source file,
2134 // and so there is nothing to import the main file.2136 // and so there is nothing to import the main file.
2135 if (comp.config.is_test) {2137 if (comp.config.is_test) {
2136 _ = try zcu.importPkg(zcu.main_mod);2138 _ = try pt.importPkg(zcu.main_mod);
2137 }2139 }
21382140
2139 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {2141 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
2140 _ = try zcu.importPkg(compiler_rt_mod);2142 _ = try pt.importPkg(compiler_rt_mod);
2141 }2143 }
21422144
2143 // Put a work item in for every known source file to detect if2145 // Put a work item in for every known source file to detect if
2144 // it changed, and, if so, re-compute ZIR and then queue the job2146 // it changed, and, if so, re-compute ZIR and then queue the job
2145 // to update it.2147 // to update it.
2146 try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count());2148 try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count());
2147 for (zcu.import_table.values(), 0..) |file, file_index_usize| {2149 for (zcu.import_table.values()) |file_index| {
2148 const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);2150 if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue;
2149 if (file.mod.isBuiltin()) continue;
2150 comp.astgen_work_queue.writeItemAssumeCapacity(file_index);2151 comp.astgen_work_queue.writeItemAssumeCapacity(file_index);
2151 }2152 }
21522153
...@@ -2641,7 +2642,8 @@ fn resolveEmitLoc(...@@ -2641,7 +2642,8 @@ fn resolveEmitLoc(
2641 return slice.ptr;2642 return slice.ptr;
2642}2643}
26432644
2644fn reportMultiModuleErrors(zcu: *Zcu) !void {2645fn reportMultiModuleErrors(pt: Zcu.PerThread) !void {
2646 const zcu = pt.zcu;
2645 const gpa = zcu.gpa;2647 const gpa = zcu.gpa;
2646 const ip = &zcu.intern_pool;2648 const ip = &zcu.intern_pool;
2647 // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to2649 // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to
...@@ -2651,14 +2653,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2651,14 +2653,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2651 // Attach the "some omitted" note to the final error message2653 // Attach the "some omitted" note to the final error message
2652 var last_err: ?*Zcu.ErrorMsg = null;2654 var last_err: ?*Zcu.ErrorMsg = null;
26532655
2654 for (zcu.import_table.values(), 0..) |file, file_index_usize| {2656 for (zcu.import_table.values()) |file_index| {
2657 const file = zcu.fileByIndex(file_index);
2655 if (!file.multi_pkg) continue;2658 if (!file.multi_pkg) continue;
26562659
2657 num_errors += 1;2660 num_errors += 1;
2658 if (num_errors > max_errors) continue;2661 if (num_errors > max_errors) continue;
26592662
2660 const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);
2661
2662 const err = err_blk: {2663 const err = err_blk: {
2663 // Like with errors, let's cap the number of notes to prevent a huge error spew.2664 // Like with errors, let's cap the number of notes to prevent a huge error spew.
2664 const max_notes = 5;2665 const max_notes = 5;
...@@ -2749,8 +2750,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2749,8 +2750,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2749 // to add this flag after reporting the errors however, as otherwise2750 // to add this flag after reporting the errors however, as otherwise
2750 // we'd get an error for every single downstream file, which wouldn't be2751 // we'd get an error for every single downstream file, which wouldn't be
2751 // very useful.2752 // very useful.
2752 for (zcu.import_table.values()) |file| {2753 for (zcu.import_table.values()) |file_index| {
2753 if (file.multi_pkg) file.recursiveMarkMultiPkg(zcu);2754 const file = zcu.fileByIndex(file_index);
2755 if (file.multi_pkg) file.recursiveMarkMultiPkg(pt);
2754 }2756 }
2755}2757}
27562758
...@@ -3443,11 +3445,12 @@ fn performAllTheWorkInner(...@@ -3443,11 +3445,12 @@ fn performAllTheWorkInner(
3443 }3445 }
3444 }3446 }
34453447
3446 if (comp.module) |mod| {3448 if (comp.module) |zcu| {
3447 try reportMultiModuleErrors(mod);3449 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main };
3448 try mod.flushRetryableFailures();3450 try reportMultiModuleErrors(pt);
3449 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);3451 try zcu.flushRetryableFailures();
3450 mod.codegen_prog_node = main_progress_node.start("Code Generation", 0);3452 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
3453 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
3451 }3454 }
34523455
3453 if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});3456 if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});
...@@ -4189,9 +4192,9 @@ fn workerAstGenFile(...@@ -4189,9 +4192,9 @@ fn workerAstGenFile(
4189 comp.mutex.lock();4192 comp.mutex.lock();
4190 defer comp.mutex.unlock();4193 defer comp.mutex.unlock();
41914194
4192 const res = pt.zcu.importFile(file, import_path) catch continue;4195 const res = pt.importFile(file, import_path) catch continue;
4193 if (!res.is_pkg) {4196 if (!res.is_pkg) {
4194 res.file.addReference(pt.zcu.*, .{ .import = .{4197 res.file.addReference(pt.zcu, .{ .import = .{
4195 .file = file_index,4198 .file = file_index,
4196 .token = item.data.token,4199 .token = item.data.token,
4197 } }) catch continue;4200 } }) catch continue;
src/InternPool.zig+76-26
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1//! All interned objects have both a value and a type.1//! All interned objects have both a value and a type.
2//! This data structure is self-contained, with the following exceptions:2//! This data structure is self-contained.
3//! * Module.Namespace has a pointer to Module.File
43
5/// One item per thread, indexed by `tid`, which is dense and unique per thread.4/// One item per thread, indexed by `tid`, which is dense and unique per thread.
6locals: []Local = &.{},5locals: []Local = &.{},
...@@ -79,10 +78,6 @@ const want_multi_threaded = false;...@@ -79,10 +78,6 @@ const want_multi_threaded = false;
79/// Whether a single-threaded intern pool impl is in use.78/// Whether a single-threaded intern pool impl is in use.
80pub const single_threaded = builtin.single_threaded or !want_multi_threaded;79pub const single_threaded = builtin.single_threaded or !want_multi_threaded;
8180
82pub const FileIndex = enum(u32) {
83 _,
84};
85
86pub const TrackedInst = extern struct {81pub const TrackedInst = extern struct {
87 file: FileIndex,82 file: FileIndex,
88 inst: Zir.Inst.Index,83 inst: Zir.Inst.Index,
...@@ -340,6 +335,7 @@ const Local = struct {...@@ -340,6 +335,7 @@ const Local = struct {
340 extra: ListMutate,335 extra: ListMutate,
341 limbs: ListMutate,336 limbs: ListMutate,
342 strings: ListMutate,337 strings: ListMutate,
338 files: ListMutate,
343339
344 decls: BucketListMutate,340 decls: BucketListMutate,
345 namespaces: BucketListMutate,341 namespaces: BucketListMutate,
...@@ -350,6 +346,7 @@ const Local = struct {...@@ -350,6 +346,7 @@ const Local = struct {
350 extra: Extra,346 extra: Extra,
351 limbs: Limbs,347 limbs: Limbs,
352 strings: Strings,348 strings: Strings,
349 files: Files,
353350
354 decls: Decls,351 decls: Decls,
355 namespaces: Namespaces,352 namespaces: Namespaces,
...@@ -370,16 +367,17 @@ const Local = struct {...@@ -370,16 +367,17 @@ const Local = struct {
370 else => @compileError("unsupported host"),367 else => @compileError("unsupported host"),
371 };368 };
372 const Strings = List(struct { u8 });369 const Strings = List(struct { u8 });
370 const Files = List(struct { *Zcu.File });
373371
374 const decls_bucket_width = 8;372 const decls_bucket_width = 8;
375 const decls_bucket_mask = (1 << decls_bucket_width) - 1;373 const decls_bucket_mask = (1 << decls_bucket_width) - 1;
376 const decl_next_free_field = "src_namespace";374 const decl_next_free_field = "src_namespace";
377 const Decls = List(struct { *[1 << decls_bucket_width]Module.Decl });375 const Decls = List(struct { *[1 << decls_bucket_width]Zcu.Decl });
378376
379 const namespaces_bucket_width = 8;377 const namespaces_bucket_width = 8;
380 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;378 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;
381 const namespace_next_free_field = "decl_index";379 const namespace_next_free_field = "decl_index";
382 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Module.Namespace });380 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });
383381
384 const ListMutate = struct {382 const ListMutate = struct {
385 len: u32,383 len: u32,
...@@ -677,6 +675,15 @@ const Local = struct {...@@ -677,6 +675,15 @@ const Local = struct {
677 };675 };
678 }676 }
679677
678 pub fn getMutableFiles(local: *Local, gpa: std.mem.Allocator) Files.Mutable {
679 return .{
680 .gpa = gpa,
681 .arena = &local.mutate.arena,
682 .mutate = &local.mutate.files,
683 .list = &local.shared.files,
684 };
685 }
686
680 /// Rather than allocating Decl objects with an Allocator, we instead allocate687 /// Rather than allocating Decl objects with an Allocator, we instead allocate
681 /// them with this BucketList. This provides four advantages:688 /// them with this BucketList. This provides four advantages:
682 /// * Stable memory so that one thread can access a Decl object while another689 /// * Stable memory so that one thread can access a Decl object while another
...@@ -812,8 +819,6 @@ const Hash = std.hash.Wyhash;...@@ -812,8 +819,6 @@ const Hash = std.hash.Wyhash;
812819
813const InternPool = @This();820const InternPool = @This();
814const Zcu = @import("Zcu.zig");821const Zcu = @import("Zcu.zig");
815/// Deprecated.
816const Module = Zcu;
817const Zir = std.zig.Zir;822const Zir = std.zig.Zir;
818823
819/// An index into `maps` which might be `none`.824/// An index into `maps` which might be `none`.
...@@ -938,6 +943,28 @@ pub const OptionalNamespaceIndex = enum(u32) {...@@ -938,6 +943,28 @@ pub const OptionalNamespaceIndex = enum(u32) {
938 }943 }
939};944};
940945
946pub const FileIndex = enum(u32) {
947 _,
948
949 const Unwrapped = struct {
950 tid: Zcu.PerThread.Id,
951 index: u32,
952
953 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) FileIndex {
954 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
955 assert(unwrapped.index <= ip.getIndexMask(u32));
956 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
957 unwrapped.index);
958 }
959 };
960 fn unwrap(file_index: FileIndex, ip: *const InternPool) Unwrapped {
961 return .{
962 .tid = @enumFromInt(@intFromEnum(file_index) >> ip.tid_shift_32 & ip.getTidMask()),
963 .index = @intFromEnum(file_index) & ip.getIndexMask(u32),
964 };
965 }
966};
967
941/// An index into `strings`.968/// An index into `strings`.
942pub const String = enum(u32) {969pub const String = enum(u32) {
943 /// An empty string.970 /// An empty string.
...@@ -4608,12 +4635,12 @@ pub const FuncAnalysis = packed struct(u32) {...@@ -4608,12 +4635,12 @@ pub const FuncAnalysis = packed struct(u32) {
4608 /// inline, which means no runtime version of the function will be generated.4635 /// inline, which means no runtime version of the function will be generated.
4609 inline_only,4636 inline_only,
4610 in_progress,4637 in_progress,
4611 /// There will be a corresponding ErrorMsg in Module.failed_decls4638 /// There will be a corresponding ErrorMsg in Zcu.failed_decls
4612 sema_failure,4639 sema_failure,
4613 /// This function might be OK but it depends on another Decl which did not4640 /// This function might be OK but it depends on another Decl which did not
4614 /// successfully complete semantic analysis.4641 /// successfully complete semantic analysis.
4615 dependency_failure,4642 dependency_failure,
4616 /// There will be a corresponding ErrorMsg in Module.failed_decls.4643 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
4617 /// Indicates that semantic analysis succeeded, but code generation for4644 /// Indicates that semantic analysis succeeded, but code generation for
4618 /// this function failed.4645 /// this function failed.
4619 codegen_failure,4646 codegen_failure,
...@@ -5210,6 +5237,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5210,6 +5237,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5210 .extra = Local.Extra.empty,5237 .extra = Local.Extra.empty,
5211 .limbs = Local.Limbs.empty,5238 .limbs = Local.Limbs.empty,
5212 .strings = Local.Strings.empty,5239 .strings = Local.Strings.empty,
5240 .files = Local.Files.empty,
52135241
5214 .decls = Local.Decls.empty,5242 .decls = Local.Decls.empty,
5215 .namespaces = Local.Namespaces.empty,5243 .namespaces = Local.Namespaces.empty,
...@@ -5221,6 +5249,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5221,6 +5249,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5221 .extra = Local.ListMutate.empty,5249 .extra = Local.ListMutate.empty,
5222 .limbs = Local.ListMutate.empty,5250 .limbs = Local.ListMutate.empty,
5223 .strings = Local.ListMutate.empty,5251 .strings = Local.ListMutate.empty,
5252 .files = Local.ListMutate.empty,
52245253
5225 .decls = Local.BucketListMutate.empty,5254 .decls = Local.BucketListMutate.empty,
5226 .namespaces = Local.BucketListMutate.empty,5255 .namespaces = Local.BucketListMutate.empty,
...@@ -9213,7 +9242,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9213,7 +9242,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9213 const items_size = (1 + 4) * items_len;9242 const items_size = (1 + 4) * items_len;
9214 const extra_size = 4 * extra_len;9243 const extra_size = 4 * extra_len;
9215 const limbs_size = 8 * limbs_len;9244 const limbs_size = 8 * limbs_len;
9216 const decls_size = @sizeOf(Module.Decl) * decls_len;9245 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
92179246
9218 // TODO: map overhead size is not taken into account9247 // TODO: map overhead size is not taken into account
9219 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;9248 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;
...@@ -9640,29 +9669,22 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -9640,29 +9669,22 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
9640 try bw.flush();9669 try bw.flush();
9641}9670}
96429671
9643pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Module.Decl {9672pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {
9644 return @constCast(ip.declPtrConst(decl_index));9673 return @constCast(ip.declPtrConst(decl_index));
9645}9674}
96469675
9647pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Module.Decl {9676pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl {
9648 const unwrapped_decl_index = decl_index.unwrap(ip);9677 const unwrapped_decl_index = decl_index.unwrap(ip);
9649 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();9678 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();
9650 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];9679 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];
9651 return &decls_bucket[unwrapped_decl_index.index];9680 return &decls_bucket[unwrapped_decl_index.index];
9652}9681}
96539682
9654pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Module.Namespace {
9655 const unwrapped_namespace_index = namespace_index.unwrap(ip);
9656 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
9657 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
9658 return &namespaces_bucket[unwrapped_namespace_index.index];
9659}
9660
9661pub fn createDecl(9683pub fn createDecl(
9662 ip: *InternPool,9684 ip: *InternPool,
9663 gpa: Allocator,9685 gpa: Allocator,
9664 tid: Zcu.PerThread.Id,9686 tid: Zcu.PerThread.Id,
9665 initialization: Module.Decl,9687 initialization: Zcu.Decl,
9666) Allocator.Error!DeclIndex {9688) Allocator.Error!DeclIndex {
9667 const local = ip.getLocal(tid);9689 const local = ip.getLocal(tid);
9668 const free_list_next = local.mutate.decls.free_list;9690 const free_list_next = local.mutate.decls.free_list;
...@@ -9679,7 +9701,7 @@ pub fn createDecl(...@@ -9679,7 +9701,7 @@ pub fn createDecl(
9679 var arena = decls.arena.promote(decls.gpa);9701 var arena = decls.arena.promote(decls.gpa);
9680 defer decls.arena.* = arena.state;9702 defer decls.arena.* = arena.state;
9681 decls.appendAssumeCapacity(.{try arena.allocator().create(9703 decls.appendAssumeCapacity(.{try arena.allocator().create(
9682 [1 << Local.decls_bucket_width]Module.Decl,9704 [1 << Local.decls_bucket_width]Zcu.Decl,
9683 )});9705 )});
9684 }9706 }
9685 const unwrapped_decl_index: DeclIndex.Unwrapped = .{9707 const unwrapped_decl_index: DeclIndex.Unwrapped = .{
...@@ -9702,11 +9724,18 @@ pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex...@@ -9702,11 +9724,18 @@ pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex
9702 local.mutate.decls.free_list = @intFromEnum(decl_index);9724 local.mutate.decls.free_list = @intFromEnum(decl_index);
9703}9725}
97049726
9727pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
9728 const unwrapped_namespace_index = namespace_index.unwrap(ip);
9729 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
9730 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
9731 return &namespaces_bucket[unwrapped_namespace_index.index];
9732}
9733
9705pub fn createNamespace(9734pub fn createNamespace(
9706 ip: *InternPool,9735 ip: *InternPool,
9707 gpa: Allocator,9736 gpa: Allocator,
9708 tid: Zcu.PerThread.Id,9737 tid: Zcu.PerThread.Id,
9709 initialization: Module.Namespace,9738 initialization: Zcu.Namespace,
9710) Allocator.Error!NamespaceIndex {9739) Allocator.Error!NamespaceIndex {
9711 const local = ip.getLocal(tid);9740 const local = ip.getLocal(tid);
9712 const free_list_next = local.mutate.namespaces.free_list;9741 const free_list_next = local.mutate.namespaces.free_list;
...@@ -9724,7 +9753,7 @@ pub fn createNamespace(...@@ -9724,7 +9753,7 @@ pub fn createNamespace(
9724 var arena = namespaces.arena.promote(namespaces.gpa);9753 var arena = namespaces.arena.promote(namespaces.gpa);
9725 defer namespaces.arena.* = arena.state;9754 defer namespaces.arena.* = arena.state;
9726 namespaces.appendAssumeCapacity(.{try arena.allocator().create(9755 namespaces.appendAssumeCapacity(.{try arena.allocator().create(
9727 [1 << Local.namespaces_bucket_width]Module.Namespace,9756 [1 << Local.namespaces_bucket_width]Zcu.Namespace,
9728 )});9757 )});
9729 }9758 }
9730 const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{9759 const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{
...@@ -9756,6 +9785,27 @@ pub fn destroyNamespace(...@@ -9756,6 +9785,27 @@ pub fn destroyNamespace(
9756 local.mutate.namespaces.free_list = @intFromEnum(namespace_index);9785 local.mutate.namespaces.free_list = @intFromEnum(namespace_index);
9757}9786}
97589787
9788pub fn filePtr(ip: *InternPool, file_index: FileIndex) *Zcu.File {
9789 const file_index_unwrapped = file_index.unwrap(ip);
9790 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
9791 return files.view().items(.@"0")[file_index_unwrapped.index];
9792}
9793
9794pub fn createFile(
9795 ip: *InternPool,
9796 gpa: Allocator,
9797 tid: Zcu.PerThread.Id,
9798 file: *Zcu.File,
9799) Allocator.Error!FileIndex {
9800 const files = ip.getLocal(tid).getMutableFiles(gpa);
9801 const file_index_unwrapped: FileIndex.Unwrapped = .{
9802 .tid = tid,
9803 .index = files.mutate.len,
9804 };
9805 try files.append(.{file});
9806 return file_index_unwrapped.wrap(ip);
9807}
9808
9759const EmbeddedNulls = enum {9809const EmbeddedNulls = enum {
9760 no_embedded_nulls,9810 no_embedded_nulls,
9761 maybe_embedded_nulls,9811 maybe_embedded_nulls,
src/Sema.zig+2-2
...@@ -6056,7 +6056,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6056,7 +6056,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
6056 else => |e| return e,6056 else => |e| return e,
6057 };6057 };
60586058
6059 const result = zcu.importPkg(c_import_mod) catch |err|6059 const result = pt.importPkg(c_import_mod) catch |err|
6060 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6060 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60616061
6062 const path_digest = zcu.filePathDigest(result.file_index);6062 const path_digest = zcu.filePathDigest(result.file_index);
...@@ -13950,7 +13950,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13950,7 +13950,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13950 const operand_src = block.tokenOffset(inst_data.src_tok);13950 const operand_src = block.tokenOffset(inst_data.src_tok);
13951 const operand = inst_data.get(sema.code);13951 const operand = inst_data.get(sema.code);
1395213952
13953 const result = zcu.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {13953 const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
13954 error.ImportOutsideModulePath => {13954 error.ImportOutsideModulePath => {
13955 return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});13955 return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});
13956 },13956 },
src/Type.zig+1-1
...@@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {...@@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3451 };3451 };
3452}3452}
34533453
3454pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {3454pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3455 const ip = &zcu.intern_pool;3455 const ip = &zcu.intern_pool;
3456 const tracked = switch (ip.indexToKey(ty.toIntern())) {3456 const tracked = switch (ip.indexToKey(ty.toIntern())) {
3457 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {3457 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
src/Zcu.zig+9-184
...@@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {...@@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
102/// `Compilation.update` of the process for a given `Compilation`.102/// `Compilation.update` of the process for a given `Compilation`.
103///103///
104/// Indexes correspond 1:1 to `files`.104/// Indexes correspond 1:1 to `files`.
105import_table: std.StringArrayHashMapUnmanaged(*File) = .{},105import_table: std.StringArrayHashMapUnmanaged(File.Index) = .{},
106106
107/// The set of all the files which have been loaded with `@embedFile` in the Module.107/// The set of all the files which have been loaded with `@embedFile` in the Module.
108/// We keep track of this in order to iterate over it and check which files have been108/// We keep track of this in order to iterate over it and check which files have been
...@@ -892,7 +892,7 @@ pub const File = struct {...@@ -892,7 +892,7 @@ pub const File = struct {
892 }892 }
893893
894 /// Add a reference to this file during AstGen.894 /// Add a reference to this file during AstGen.
895 pub fn addReference(file: *File, zcu: Zcu, ref: File.Reference) !void {895 pub fn addReference(file: *File, zcu: *Zcu, ref: File.Reference) !void {
896 // Don't add the same module root twice. Note that since we always add module roots at the896 // Don't add the same module root twice. Note that since we always add module roots at the
897 // front of the references array (see below), this loop is actually O(1) on valid code.897 // front of the references array (see below), this loop is actually O(1) on valid code.
898 if (ref == .root) {898 if (ref == .root) {
...@@ -924,7 +924,7 @@ pub const File = struct {...@@ -924,7 +924,7 @@ pub const File = struct {
924924
925 /// Mark this file and every file referenced by it as multi_pkg and report an925 /// Mark this file and every file referenced by it as multi_pkg and report an
926 /// astgen_failure error for them. AstGen must have completed in its entirety.926 /// astgen_failure error for them. AstGen must have completed in its entirety.
927 pub fn recursiveMarkMultiPkg(file: *File, mod: *Module) void {927 pub fn recursiveMarkMultiPkg(file: *File, pt: Zcu.PerThread) void {
928 file.multi_pkg = true;928 file.multi_pkg = true;
929 file.status = .astgen_failure;929 file.status = .astgen_failure;
930930
...@@ -944,9 +944,9 @@ pub const File = struct {...@@ -944,9 +944,9 @@ pub const File = struct {
944 const import_path = file.zir.nullTerminatedString(item.data.name);944 const import_path = file.zir.nullTerminatedString(item.data.name);
945 if (mem.eql(u8, import_path, "builtin")) continue;945 if (mem.eql(u8, import_path, "builtin")) continue;
946946
947 const res = mod.importFile(file, import_path) catch continue;947 const res = pt.importFile(file, import_path) catch continue;
948 if (!res.is_pkg and !res.file.multi_pkg) {948 if (!res.is_pkg and !res.file.multi_pkg) {
949 res.file.recursiveMarkMultiPkg(mod);949 res.file.recursiveMarkMultiPkg(pt);
950 }950 }
951 }951 }
952 }952 }
...@@ -3002,183 +3002,7 @@ pub const ImportFileResult = struct {...@@ -3002,183 +3002,7 @@ pub const ImportFileResult = struct {
3002 is_pkg: bool,3002 is_pkg: bool,
3003};3003};
30043004
3005pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {3005pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
3006 const gpa = zcu.gpa;
3007
3008 // The resolved path is used as the key in the import table, to detect if
3009 // an import refers to the same as another, despite different relative paths
3010 // or differently mapped package names.
3011 const resolved_path = try std.fs.path.resolve(gpa, &.{
3012 mod.root.root_dir.path orelse ".",
3013 mod.root.sub_path,
3014 mod.root_src_path,
3015 });
3016 var keep_resolved_path = false;
3017 defer if (!keep_resolved_path) gpa.free(resolved_path);
3018
3019 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3020 errdefer _ = zcu.import_table.pop();
3021 if (gop.found_existing) {
3022 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
3023 return .{
3024 .file = gop.value_ptr.*,
3025 .file_index = @enumFromInt(gop.index),
3026 .is_new = false,
3027 .is_pkg = true,
3028 };
3029 }
3030
3031 const ip = &zcu.intern_pool;
3032
3033 try ip.files.ensureUnusedCapacity(gpa, 1);
3034
3035 if (mod.builtin_file) |builtin_file| {
3036 keep_resolved_path = true; // It's now owned by import_table.
3037 gop.value_ptr.* = builtin_file;
3038 try builtin_file.addReference(zcu.*, .{ .root = mod });
3039 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
3040 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3041 return .{
3042 .file = builtin_file,
3043 .file_index = @enumFromInt(ip.files.entries.len - 1),
3044 .is_new = false,
3045 .is_pkg = true,
3046 };
3047 }
3048
3049 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
3050 errdefer gpa.free(sub_file_path);
3051
3052 const new_file = try gpa.create(File);
3053 errdefer gpa.destroy(new_file);
3054
3055 keep_resolved_path = true; // It's now owned by import_table.
3056 gop.value_ptr.* = new_file;
3057 new_file.* = .{
3058 .sub_file_path = sub_file_path,
3059 .source = undefined,
3060 .source_loaded = false,
3061 .tree_loaded = false,
3062 .zir_loaded = false,
3063 .stat = undefined,
3064 .tree = undefined,
3065 .zir = undefined,
3066 .status = .never_loaded,
3067 .mod = mod,
3068 };
3069
3070 const path_digest = computePathDigest(zcu, mod, sub_file_path);
3071
3072 try new_file.addReference(zcu.*, .{ .root = mod });
3073 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3074 return .{
3075 .file = new_file,
3076 .file_index = @enumFromInt(ip.files.entries.len - 1),
3077 .is_new = true,
3078 .is_pkg = true,
3079 };
3080}
3081
3082/// Called from a worker thread during AstGen.
3083/// Also called from Sema during semantic analysis.
3084pub fn importFile(
3085 zcu: *Zcu,
3086 cur_file: *File,
3087 import_string: []const u8,
3088) !ImportFileResult {
3089 const mod = cur_file.mod;
3090
3091 if (std.mem.eql(u8, import_string, "std")) {
3092 return zcu.importPkg(zcu.std_mod);
3093 }
3094 if (std.mem.eql(u8, import_string, "root")) {
3095 return zcu.importPkg(zcu.root_mod);
3096 }
3097 if (mod.deps.get(import_string)) |pkg| {
3098 return zcu.importPkg(pkg);
3099 }
3100 if (!mem.endsWith(u8, import_string, ".zig")) {
3101 return error.ModuleNotFound;
3102 }
3103 const gpa = zcu.gpa;
3104
3105 // The resolved path is used as the key in the import table, to detect if
3106 // an import refers to the same as another, despite different relative paths
3107 // or differently mapped package names.
3108 const resolved_path = try std.fs.path.resolve(gpa, &.{
3109 mod.root.root_dir.path orelse ".",
3110 mod.root.sub_path,
3111 cur_file.sub_file_path,
3112 "..",
3113 import_string,
3114 });
3115
3116 var keep_resolved_path = false;
3117 defer if (!keep_resolved_path) gpa.free(resolved_path);
3118
3119 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3120 errdefer _ = zcu.import_table.pop();
3121 if (gop.found_existing) return .{
3122 .file = gop.value_ptr.*,
3123 .file_index = @enumFromInt(gop.index),
3124 .is_new = false,
3125 .is_pkg = false,
3126 };
3127
3128 const ip = &zcu.intern_pool;
3129
3130 try ip.files.ensureUnusedCapacity(gpa, 1);
3131
3132 const new_file = try gpa.create(File);
3133 errdefer gpa.destroy(new_file);
3134
3135 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
3136 mod.root.root_dir.path orelse ".",
3137 mod.root.sub_path,
3138 });
3139 defer gpa.free(resolved_root_path);
3140
3141 const sub_file_path = p: {
3142 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
3143 errdefer gpa.free(relative);
3144
3145 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
3146 break :p relative;
3147 }
3148 return error.ImportOutsideModulePath;
3149 };
3150 errdefer gpa.free(sub_file_path);
3151
3152 log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
3153 resolved_root_path, resolved_path, sub_file_path, import_string,
3154 });
3155
3156 keep_resolved_path = true; // It's now owned by import_table.
3157 gop.value_ptr.* = new_file;
3158 new_file.* = .{
3159 .sub_file_path = sub_file_path,
3160 .source = undefined,
3161 .source_loaded = false,
3162 .tree_loaded = false,
3163 .zir_loaded = false,
3164 .stat = undefined,
3165 .tree = undefined,
3166 .zir = undefined,
3167 .status = .never_loaded,
3168 .mod = mod,
3169 };
3170
3171 const path_digest = computePathDigest(zcu, mod, sub_file_path);
3172 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3173 return .{
3174 .file = new_file,
3175 .file_index = @enumFromInt(ip.files.entries.len - 1),
3176 .is_new = true,
3177 .is_pkg = false,
3178 };
3179}
3180
3181fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
3182 const want_local_cache = mod == zcu.main_mod;3006 const want_local_cache = mod == zcu.main_mod;
3183 var path_hash: Cache.HashHelper = .{};3007 var path_hash: Cache.HashHelper = .{};
3184 path_hash.addBytes(build_options.version);3008 path_hash.addBytes(build_options.version);
...@@ -3710,8 +3534,9 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved...@@ -3710,8 +3534,9 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
3710 return result;3534 return result;
3711}3535}
37123536
3713pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {3537pub fn fileByIndex(zcu: *Zcu, i: File.Index) *File {
3714 return zcu.import_table.values()[@intFromEnum(i)];3538 const ip = &zcu.intern_pool;
3539 return ip.filePtr(i);
3715}3540}
37163541
3717/// Returns the `Decl` of the struct that represents this `File`.3542/// Returns the `Decl` of the struct that represents this `File`.
src/Zcu/PerThread.zig+203-18
...@@ -817,7 +817,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -817,7 +817,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
817817
818/// https://github.com/ziglang/zig/issues/14307818/// https://github.com/ziglang/zig/issues/14307
819pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {819pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
820 const import_file_result = try pt.zcu.importPkg(pkg);820 const import_file_result = try pt.importPkg(pkg);
821 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);821 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
822 if (root_decl_index == .none) {822 if (root_decl_index == .none) {
823 return pt.semaFile(import_file_result.file_index);823 return pt.semaFile(import_file_result.file_index);
...@@ -1081,7 +1081,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1081,7 +1081,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1081 const std_mod = zcu.std_mod;1081 const std_mod = zcu.std_mod;
1082 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;1082 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
1083 // We're in the std module.1083 // We're in the std module.
1084 const std_file_imported = try zcu.importPkg(std_mod);1084 const std_file_imported = try pt.importPkg(std_mod);
1085 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);1085 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
1086 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);1086 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
1087 const std_namespace = std_decl.getInnerNamespace(zcu).?;1087 const std_namespace = std_decl.getInnerNamespace(zcu).?;
...@@ -1356,6 +1356,191 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem...@@ -1356,6 +1356,191 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem
1356 };1356 };
1357}1357}
13581358
1359pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1360 const zcu = pt.zcu;
1361 const gpa = zcu.gpa;
1362
1363 // The resolved path is used as the key in the import table, to detect if
1364 // an import refers to the same as another, despite different relative paths
1365 // or differently mapped package names.
1366 const resolved_path = try std.fs.path.resolve(gpa, &.{
1367 mod.root.root_dir.path orelse ".",
1368 mod.root.sub_path,
1369 mod.root_src_path,
1370 });
1371 var keep_resolved_path = false;
1372 defer if (!keep_resolved_path) gpa.free(resolved_path);
1373
1374 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
1375 errdefer _ = zcu.import_table.pop();
1376 if (gop.found_existing) {
1377 const file_index = gop.value_ptr.*;
1378 const file = zcu.fileByIndex(file_index);
1379 try file.addReference(zcu, .{ .root = mod });
1380 return .{
1381 .file = file,
1382 .file_index = file_index,
1383 .is_new = false,
1384 .is_pkg = true,
1385 };
1386 }
1387
1388 const ip = &zcu.intern_pool;
1389 try ip.files.ensureUnusedCapacity(gpa, 1);
1390
1391 if (mod.builtin_file) |builtin_file| {
1392 const file_index = try ip.createFile(gpa, pt.tid, builtin_file);
1393 keep_resolved_path = true; // It's now owned by import_table.
1394 gop.value_ptr.* = file_index;
1395 try builtin_file.addReference(zcu, .{ .root = mod });
1396 const path_digest = Zcu.computePathDigest(zcu, mod, builtin_file.sub_file_path);
1397 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
1398 return .{
1399 .file = builtin_file,
1400 .file_index = file_index,
1401 .is_new = false,
1402 .is_pkg = true,
1403 };
1404 }
1405
1406 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
1407 errdefer gpa.free(sub_file_path);
1408
1409 const new_file = try gpa.create(Zcu.File);
1410 errdefer gpa.destroy(new_file);
1411
1412 const new_file_index = try ip.createFile(gpa, pt.tid, new_file);
1413 keep_resolved_path = true; // It's now owned by import_table.
1414 gop.value_ptr.* = new_file_index;
1415 new_file.* = .{
1416 .sub_file_path = sub_file_path,
1417 .source = undefined,
1418 .source_loaded = false,
1419 .tree_loaded = false,
1420 .zir_loaded = false,
1421 .stat = undefined,
1422 .tree = undefined,
1423 .zir = undefined,
1424 .status = .never_loaded,
1425 .mod = mod,
1426 };
1427
1428 const path_digest = zcu.computePathDigest(mod, sub_file_path);
1429
1430 try new_file.addReference(zcu, .{ .root = mod });
1431 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
1432 return .{
1433 .file = new_file,
1434 .file_index = new_file_index,
1435 .is_new = true,
1436 .is_pkg = true,
1437 };
1438}
1439
1440/// Called from a worker thread during AstGen.
1441/// Also called from Sema during semantic analysis.
1442pub fn importFile(
1443 pt: Zcu.PerThread,
1444 cur_file: *Zcu.File,
1445 import_string: []const u8,
1446) !Zcu.ImportFileResult {
1447 const zcu = pt.zcu;
1448 const mod = cur_file.mod;
1449
1450 if (std.mem.eql(u8, import_string, "std")) {
1451 return pt.importPkg(zcu.std_mod);
1452 }
1453 if (std.mem.eql(u8, import_string, "root")) {
1454 return pt.importPkg(zcu.root_mod);
1455 }
1456 if (mod.deps.get(import_string)) |pkg| {
1457 return pt.importPkg(pkg);
1458 }
1459 if (!std.mem.endsWith(u8, import_string, ".zig")) {
1460 return error.ModuleNotFound;
1461 }
1462 const gpa = zcu.gpa;
1463
1464 // The resolved path is used as the key in the import table, to detect if
1465 // an import refers to the same as another, despite different relative paths
1466 // or differently mapped package names.
1467 const resolved_path = try std.fs.path.resolve(gpa, &.{
1468 mod.root.root_dir.path orelse ".",
1469 mod.root.sub_path,
1470 cur_file.sub_file_path,
1471 "..",
1472 import_string,
1473 });
1474
1475 var keep_resolved_path = false;
1476 defer if (!keep_resolved_path) gpa.free(resolved_path);
1477
1478 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
1479 errdefer _ = zcu.import_table.pop();
1480 if (gop.found_existing) {
1481 const file_index = gop.value_ptr.*;
1482 return .{
1483 .file = zcu.fileByIndex(file_index),
1484 .file_index = file_index,
1485 .is_new = false,
1486 .is_pkg = false,
1487 };
1488 }
1489
1490 const ip = &zcu.intern_pool;
1491
1492 try ip.files.ensureUnusedCapacity(gpa, 1);
1493
1494 const new_file = try gpa.create(Zcu.File);
1495 errdefer gpa.destroy(new_file);
1496
1497 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
1498 mod.root.root_dir.path orelse ".",
1499 mod.root.sub_path,
1500 });
1501 defer gpa.free(resolved_root_path);
1502
1503 const sub_file_path = p: {
1504 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
1505 errdefer gpa.free(relative);
1506
1507 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
1508 break :p relative;
1509 }
1510 return error.ImportOutsideModulePath;
1511 };
1512 errdefer gpa.free(sub_file_path);
1513
1514 log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
1515 resolved_root_path, resolved_path, sub_file_path, import_string,
1516 });
1517
1518 const new_file_index = try ip.createFile(gpa, pt.tid, new_file);
1519 keep_resolved_path = true; // It's now owned by import_table.
1520 gop.value_ptr.* = new_file_index;
1521 new_file.* = .{
1522 .sub_file_path = sub_file_path,
1523 .source = undefined,
1524 .source_loaded = false,
1525 .tree_loaded = false,
1526 .zir_loaded = false,
1527 .stat = undefined,
1528 .tree = undefined,
1529 .zir = undefined,
1530 .status = .never_loaded,
1531 .mod = mod,
1532 };
1533
1534 const path_digest = zcu.computePathDigest(mod, sub_file_path);
1535 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
1536 return .{
1537 .file = new_file,
1538 .file_index = new_file_index,
1539 .is_new = true,
1540 .is_pkg = false,
1541 };
1542}
1543
1359pub fn embedFile(1544pub fn embedFile(
1360 pt: Zcu.PerThread,1545 pt: Zcu.PerThread,
1361 cur_file: *Zcu.File,1546 cur_file: *Zcu.File,
...@@ -1429,20 +1614,6 @@ pub fn embedFile(...@@ -1429,20 +1614,6 @@ pub fn embedFile(
1429 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);1614 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
1430}1615}
14311616
1432/// Cancel the creation of an anon decl and delete any references to it.
1433/// If other decls depend on this decl, they must be aborted first.
1434pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1435 assert(!pt.zcu.declIsRoot(decl_index));
1436 pt.destroyDecl(decl_index);
1437}
1438
1439/// Finalize the creation of an anon decl.
1440pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1441 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1442 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1443 }
1444}
1445
1446/// https://github.com/ziglang/zig/issues/143071617/// https://github.com/ziglang/zig/issues/14307
1447fn newEmbedFile(1618fn newEmbedFile(
1448 pt: Zcu.PerThread,1619 pt: Zcu.PerThread,
...@@ -1792,6 +1963,20 @@ const ScanDeclIter = struct {...@@ -1792,6 +1963,20 @@ const ScanDeclIter = struct {
1792 }1963 }
1793};1964};
17941965
1966/// Cancel the creation of an anon decl and delete any references to it.
1967/// If other decls depend on this decl, they must be aborted first.
1968pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1969 assert(!pt.zcu.declIsRoot(decl_index));
1970 pt.destroyDecl(decl_index);
1971}
1972
1973/// Finalize the creation of an anon decl.
1974pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1975 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1976 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1977 }
1978}
1979
1795pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {1980pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
1796 const tracy = trace(@src());1981 const tracy = trace(@src());
1797 defer tracy.end();1982 defer tracy.end();
...@@ -2255,7 +2440,7 @@ pub fn populateTestFunctions(...@@ -2255,7 +2440,7 @@ pub fn populateTestFunctions(
2255 const gpa = zcu.gpa;2440 const gpa = zcu.gpa;
2256 const ip = &zcu.intern_pool;2441 const ip = &zcu.intern_pool;
2257 const builtin_mod = zcu.root_mod.getBuiltinDependency();2442 const builtin_mod = zcu.root_mod.getBuiltinDependency();
2258 const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;2443 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
2259 const root_decl_index = zcu.fileRootDecl(builtin_file_index);2444 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
2260 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);2445 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
2261 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);2446 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
...@@ -2923,7 +3108,7 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter...@@ -2923,7 +3108,7 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter
2923 const zcu = pt.zcu;3108 const zcu = pt.zcu;
2924 const gpa = zcu.gpa;3109 const gpa = zcu.gpa;
2925 const ip = &zcu.intern_pool;3110 const ip = &zcu.intern_pool;
2926 const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");3111 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
2927 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;3112 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
2928 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;3113 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
2929 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);3114 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
src/codegen/llvm.zig+1-1
...@@ -2811,7 +2811,7 @@ pub const Object = struct {...@@ -2811,7 +2811,7 @@ pub const Object = struct {
2811 const zcu = pt.zcu;2811 const zcu = pt.zcu;
28122812
2813 const std_mod = zcu.std_mod;2813 const std_mod = zcu.std_mod;
2814 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;2814 const std_file_imported = pt.importPkg(std_mod) catch unreachable;
28152815
2816 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);2816 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
2817 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);2817 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);