| ... | @@ -576,6 +576,8 @@ pub fn update(self: *Module) !void { | ... | @@ -576,6 +576,8 @@ pub fn update(self: *Module) !void { |
| 576 | // TODO Use the cache hash file system to detect which source files changed. | 576 | // TODO Use the cache hash file system to detect which source files changed. |
| 577 | // Here we simulate a full cache miss. | 577 | // Here we simulate a full cache miss. |
| 578 | // Analyze the root source file now. | 578 | // Analyze the root source file now. |
| | 579 | // Source files could have been loaded for any reason; to force a refresh we unload now. |
| | 580 | self.root_scope.unload(self.allocator); |
| 579 | self.analyzeRoot(self.root_scope) catch |err| switch (err) { | 581 | self.analyzeRoot(self.root_scope) catch |err| switch (err) { |
| 580 | error.AnalysisFail => { | 582 | error.AnalysisFail => { |
| 581 | assert(self.totalErrorCount() != 0); | 583 | assert(self.totalErrorCount() != 0); |
| ... | @@ -594,8 +596,11 @@ pub fn update(self: *Module) !void { | ... | @@ -594,8 +596,11 @@ pub fn update(self: *Module) !void { |
| 594 | try self.deleteDecl(decl); | 596 | try self.deleteDecl(decl); |
| 595 | } | 597 | } |
| 596 | | 598 | |
| 597 | // Unload all the source files from memory. | 599 | // If there are any errors, we anticipate the source files being loaded |
| 598 | self.root_scope.unload(self.allocator); | 600 | // to report error messages. Otherwise we unload all source files to save memory. |
| | 601 | if (self.totalErrorCount() == 0) { |
| | 602 | self.root_scope.unload(self.allocator); |
| | 603 | } |
| 599 | | 604 | |
| 600 | try self.bin_file.flush(); | 605 | try self.bin_file.flush(); |
| 601 | self.link_error_flags = self.bin_file.error_flags; | 606 | self.link_error_flags = self.bin_file.error_flags; |
| ... | @@ -878,11 +883,11 @@ fn analyzeRoot(self: *Module, root_scope: *Scope.ZIRModule) !void { | ... | @@ -878,11 +883,11 @@ fn analyzeRoot(self: *Module, root_scope: *Scope.ZIRModule) !void { |
| 878 | const decl = kv.value; | 883 | const decl = kv.value; |
| 879 | deleted_decls.removeAssertDiscard(decl); | 884 | deleted_decls.removeAssertDiscard(decl); |
| 880 | const new_contents_hash = Decl.hashSimpleName(src_decl.contents); | 885 | const new_contents_hash = Decl.hashSimpleName(src_decl.contents); |
| | 886 | //std.debug.warn("'{}' contents: '{}'\n", .{ src_decl.name, src_decl.contents }); |
| 881 | if (!mem.eql(u8, &new_contents_hash, &decl.contents_hash)) { | 887 | if (!mem.eql(u8, &new_contents_hash, &decl.contents_hash)) { |
| 882 | //std.debug.warn("noticed '{}' source changed\n", .{src_decl.name}); | 888 | //std.debug.warn("'{}' {x} => {x}\n", .{ src_decl.name, decl.contents_hash, new_contents_hash }); |
| 883 | decl.analysis = .outdated; | 889 | try self.markOutdatedDecl(decl); |
| 884 | decl.contents_hash = new_contents_hash; | 890 | decl.contents_hash = new_contents_hash; |
| 885 | try self.work_queue.writeItem(.{ .re_analyze_decl = decl }); | | |
| 886 | } | 891 | } |
| 887 | } else if (src_decl.cast(zir.Inst.Export)) |export_inst| { | 892 | } else if (src_decl.cast(zir.Inst.Export)) |export_inst| { |
| 888 | try exports_to_resolve.append(&export_inst.base); | 893 | try exports_to_resolve.append(&export_inst.base); |
| ... | @@ -923,8 +928,7 @@ fn deleteDecl(self: *Module, decl: *Decl) !void { | ... | @@ -923,8 +928,7 @@ fn deleteDecl(self: *Module, decl: *Decl) !void { |
| 923 | for (decl.dependants.items) |dep| { | 928 | for (decl.dependants.items) |dep| { |
| 924 | dep.removeDependency(decl); | 929 | dep.removeDependency(decl); |
| 925 | if (dep.analysis != .outdated) { | 930 | if (dep.analysis != .outdated) { |
| 926 | dep.analysis = .outdated; | 931 | try self.markOutdatedDecl(dep); |
| 927 | try self.work_queue.writeItem(.{ .re_analyze_decl = dep }); | | |
| 928 | } | 932 | } |
| 929 | } | 933 | } |
| 930 | self.deleteDeclExports(decl); | 934 | self.deleteDeclExports(decl); |
| ... | @@ -1083,14 +1087,22 @@ fn reAnalyzeDecl(self: *Module, decl: *Decl, old_inst: *zir.Inst) InnerError!voi | ... | @@ -1083,14 +1087,22 @@ fn reAnalyzeDecl(self: *Module, decl: *Decl, old_inst: *zir.Inst) InnerError!voi |
| 1083 | .codegen_failure_retryable, | 1087 | .codegen_failure_retryable, |
| 1084 | .complete, | 1088 | .complete, |
| 1085 | => if (dep.generation != self.generation) { | 1089 | => if (dep.generation != self.generation) { |
| 1086 | dep.analysis = .outdated; | 1090 | try self.markOutdatedDecl(dep); |
| 1087 | try self.work_queue.writeItem(.{ .re_analyze_decl = dep }); | | |
| 1088 | }, | 1091 | }, |
| 1089 | } | 1092 | } |
| 1090 | } | 1093 | } |
| 1091 | } | 1094 | } |
| 1092 | } | 1095 | } |
| 1093 | | 1096 | |
| | 1097 | fn markOutdatedDecl(self: *Module, decl: *Decl) !void { |
| | 1098 | //std.debug.warn("mark {} outdated\n", .{decl.name}); |
| | 1099 | try self.work_queue.writeItem(.{ .re_analyze_decl = decl }); |
| | 1100 | if (self.failed_decls.remove(decl)) |entry| { |
| | 1101 | self.allocator.destroy(entry.value); |
| | 1102 | } |
| | 1103 | decl.analysis = .outdated; |
| | 1104 | } |
| | 1105 | |
| 1094 | fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl { | 1106 | fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl { |
| 1095 | const hash = Decl.hashSimpleName(old_inst.name); | 1107 | const hash = Decl.hashSimpleName(old_inst.name); |
| 1096 | if (self.decl_table.get(hash)) |kv| { | 1108 | if (self.decl_table.get(hash)) |kv| { |
| ... | @@ -1445,6 +1457,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In | ... | @@ -1445,6 +1457,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In |
| 1445 | switch (old_inst.tag) { | 1457 | switch (old_inst.tag) { |
| 1446 | .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?), | 1458 | .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?), |
| 1447 | .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?), | 1459 | .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?), |
| | 1460 | .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?), |
| 1448 | .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?), | 1461 | .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?), |
| 1449 | .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?), | 1462 | .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?), |
| 1450 | .str => { | 1463 | .str => { |
| ... | @@ -1484,6 +1497,10 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In | ... | @@ -1484,6 +1497,10 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In |
| 1484 | } | 1497 | } |
| 1485 | } | 1498 | } |
| 1486 | | 1499 | |
| | 1500 | fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.CompileError) InnerError!*Inst { |
| | 1501 | return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg}); |
| | 1502 | } |
| | 1503 | |
| 1487 | fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoint) InnerError!*Inst { | 1504 | fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoint) InnerError!*Inst { |
| 1488 | const b = try self.requireRuntimeBlock(scope, inst.base.src); | 1505 | const b = try self.requireRuntimeBlock(scope, inst.base.src); |
| 1489 | return self.addNewInstArgs(b, inst.base.src, Type.initTag(.void), Inst.Breakpoint, Inst.Args(Inst.Breakpoint){}); | 1506 | return self.addNewInstArgs(b, inst.base.src, Type.initTag(.void), Inst.Breakpoint, Inst.Args(Inst.Breakpoint){}); |