| author | |
| committer | |
| log | 5ff45b3f44e7f1272b655b366cee4089d0aa8509 |
| tree | 7a2987020988e85f60eff90db71ca08a3bdf6864 |
| parent | a271f12a149239ab6e6361423589687e32f64cda |
4 files changed, 50 insertions(+), 7 deletions(-)
BRANCH_TODO-1| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | * look for cached zir code |
| 2 | 2 | * save zir code to cache |
| 3 | * use list of imported strings to queue up more astgen tasks | |
| 4 | 3 | * keep track of file dependencies/dependants |
| 5 | 4 | * unload files from memory when a dependency is dropped |
| 6 | 5 | * implement zir error notes |
src/Compilation.zig+30-1| ... | ... | @@ -30,6 +30,7 @@ const c_codegen = @import("codegen/c.zig"); |
| 30 | 30 | const ThreadPool = @import("ThreadPool.zig"); |
| 31 | 31 | const WaitGroup = @import("WaitGroup.zig"); |
| 32 | 32 | const libtsan = @import("libtsan.zig"); |
| 33 | const Zir = @import("Zir.zig"); | |
| 33 | 34 | |
| 34 | 35 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| 35 | 36 | gpa: *Allocator, |
| ... | ... | @@ -431,7 +432,6 @@ pub const AllErrors = struct { |
| 431 | 432 | ) !void { |
| 432 | 433 | assert(file.zir_loaded); |
| 433 | 434 | assert(file.tree_loaded); |
| 434 | const Zir = @import("Zir.zig"); | |
| 435 | 435 | const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)]; |
| 436 | 436 | assert(payload_index != 0); |
| 437 | 437 | |
| ... | ... | @@ -2120,6 +2120,35 @@ fn workerAstGenFile( |
| 2120 | 2120 | }; |
| 2121 | 2121 | }, |
| 2122 | 2122 | }; |
| 2123 | ||
| 2124 | // Pre-emptively look for `@import` paths and queue them up. | |
| 2125 | // If we experience an error preemptively fetching the | |
| 2126 | // file, just ignore it and let it happen again later during Sema. | |
| 2127 | assert(file.zir_loaded); | |
| 2128 | const imports_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.imports)]; | |
| 2129 | if (imports_index != 0) { | |
| 2130 | const imports_len = file.zir.extra[imports_index]; | |
| 2131 | ||
| 2132 | for (file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| { | |
| 2133 | const import_path = file.zir.nullTerminatedString(str_index); | |
| 2134 | ||
| 2135 | const import_result = blk: { | |
| 2136 | const lock = comp.mutex.acquire(); | |
| 2137 | defer lock.release(); | |
| 2138 | ||
| 2139 | break :blk mod.importFile(file.pkg, import_path) catch continue; | |
| 2140 | }; | |
| 2141 | if (import_result.is_new) { | |
| 2142 | wg.start(); | |
| 2143 | comp.thread_pool.spawn(workerAstGenFile, .{ | |
| 2144 | comp, import_result.file, prog_node, wg, | |
| 2145 | }) catch { | |
| 2146 | wg.finish(); | |
| 2147 | continue; | |
| 2148 | }; | |
| 2149 | } | |
| 2150 | } | |
| 2151 | } | |
| 2123 | 2152 | } |
| 2124 | 2153 | |
| 2125 | 2154 | pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest { |
src/Module.zig+18-3| ... | ... | @@ -2628,7 +2628,16 @@ pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !vo |
| 2628 | 2628 | depender.dependencies.putAssumeCapacity(dependee, {}); |
| 2629 | 2629 | } |
| 2630 | 2630 | |
| 2631 | pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !*Scope.File { | |
| 2631 | pub const ImportFileResult = struct { | |
| 2632 | file: *Scope.File, | |
| 2633 | is_new: bool, | |
| 2634 | }; | |
| 2635 | ||
| 2636 | pub fn importFile( | |
| 2637 | mod: *Module, | |
| 2638 | cur_pkg: *Package, | |
| 2639 | import_string: []const u8, | |
| 2640 | ) !ImportFileResult { | |
| 2632 | 2641 | const gpa = mod.gpa; |
| 2633 | 2642 | |
| 2634 | 2643 | const cur_pkg_dir_path = cur_pkg.root_src_directory.path orelse "."; |
| ... | ... | @@ -2642,7 +2651,10 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !* |
| 2642 | 2651 | defer if (!keep_resolved_path) gpa.free(resolved_path); |
| 2643 | 2652 | |
| 2644 | 2653 | const gop = try mod.import_table.getOrPut(gpa, resolved_path); |
| 2645 | if (gop.found_existing) return gop.entry.value; | |
| 2654 | if (gop.found_existing) return ImportFileResult{ | |
| 2655 | .file = gop.entry.value, | |
| 2656 | .is_new = false, | |
| 2657 | }; | |
| 2646 | 2658 | |
| 2647 | 2659 | if (found_pkg == null) { |
| 2648 | 2660 | const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); |
| ... | ... | @@ -2671,7 +2683,10 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !* |
| 2671 | 2683 | .namespace = undefined, |
| 2672 | 2684 | }; |
| 2673 | 2685 | keep_resolved_path = true; |
| 2674 | return new_file; | |
| 2686 | return ImportFileResult{ | |
| 2687 | .file = new_file, | |
| 2688 | .is_new = true, | |
| 2689 | }; | |
| 2675 | 2690 | } |
| 2676 | 2691 | |
| 2677 | 2692 | pub fn analyzeNamespace( |
src/Sema.zig+2-2| ... | ... | @@ -3904,7 +3904,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! |
| 3904 | 3904 | const src = inst_data.src(); |
| 3905 | 3905 | const operand = inst_data.get(sema.code); |
| 3906 | 3906 | |
| 3907 | const file = mod.importFile(block.getFileScope().pkg, operand) catch |err| switch (err) { | |
| 3907 | const result = mod.importFile(block.getFileScope().pkg, operand) catch |err| switch (err) { | |
| 3908 | 3908 | error.ImportOutsidePkgPath => { |
| 3909 | 3909 | return mod.fail(&block.base, src, "import of file outside package path: '{s}'", .{operand}); |
| 3910 | 3910 | }, |
| ... | ... | @@ -3914,7 +3914,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! |
| 3914 | 3914 | return mod.fail(&block.base, src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); |
| 3915 | 3915 | }, |
| 3916 | 3916 | }; |
| 3917 | return mod.constType(sema.arena, src, file.namespace.ty); | |
| 3917 | return mod.constType(sema.arena, src, result.file.namespace.ty); | |
| 3918 | 3918 | } |
| 3919 | 3919 | |
| 3920 | 3920 | fn zirShl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |