authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-05 15:49:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-08 15:16:40-04:00
log91930a4ff08d275ec16507aed58a73a02742f831
tree462147ea4e9b7f77b87188173381ea1ab6a42c29
parentcf654b52d68f20a403965e70371a9ad193370d8c

stage2: fix not re-loading source file for updates after errors


3 files changed, 93 insertions(+), 11 deletions(-)

src-self-hosted/Module.zig+26-9
...@@ -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 }
596598
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 }
599604
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}
10931096
1097fn 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
1094fn resolveDecl(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Decl {1106fn 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}
14861499
1500fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.CompileError) InnerError!*Inst {
1501 return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg});
1502}
1503
1487fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoint) InnerError!*Inst {1504fn 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){});
src-self-hosted/main.zig+15-1
...@@ -407,7 +407,21 @@ fn buildOutputType(...@@ -407,7 +407,21 @@ fn buildOutputType(
407 std.debug.warn("-fno-emit-bin not supported yet", .{});407 std.debug.warn("-fno-emit-bin not supported yet", .{});
408 process.exit(1);408 process.exit(1);
409 },409 },
410 .yes_default_path => try std.fmt.allocPrint(arena, "{}{}", .{ root_name, target_info.target.exeFileExt() }),410 .yes_default_path => switch (output_mode) {
411 .Exe => try std.fmt.allocPrint(arena, "{}{}", .{ root_name, target_info.target.exeFileExt() }),
412 .Lib => blk: {
413 const suffix = switch (link_mode orelse .Static) {
414 .Static => target_info.target.staticLibSuffix(),
415 .Dynamic => target_info.target.dynamicLibSuffix(),
416 };
417 break :blk try std.fmt.allocPrint(arena, "{}{}{}", .{
418 target_info.target.libPrefix(),
419 root_name,
420 suffix,
421 });
422 },
423 .Obj => try std.fmt.allocPrint(arena, "{}{}", .{ root_name, target_info.target.oFileExt() }),
424 },
411 .yes => |p| p,425 .yes => |p| p,
412 };426 };
413427
src-self-hosted/zir.zig+52-1
...@@ -27,6 +27,7 @@ pub const Inst = struct {...@@ -27,6 +27,7 @@ pub const Inst = struct {
27 pub const Tag = enum {27 pub const Tag = enum {
28 breakpoint,28 breakpoint,
29 call,29 call,
30 compileerror,
30 /// Represents a pointer to a global decl by name.31 /// Represents a pointer to a global decl by name.
31 declref,32 declref,
32 /// The syntax `@foo` is equivalent to `declval("foo")`.33 /// The syntax `@foo` is equivalent to `declval("foo")`.
...@@ -62,6 +63,7 @@ pub const Inst = struct {...@@ -62,6 +63,7 @@ pub const Inst = struct {
62 .call => Call,63 .call => Call,
63 .declref => DeclRef,64 .declref => DeclRef,
64 .declval => DeclVal,65 .declval => DeclVal,
66 .compileerror => CompileError,
65 .str => Str,67 .str => Str,
66 .int => Int,68 .int => Int,
67 .ptrtoint => PtrToInt,69 .ptrtoint => PtrToInt,
...@@ -135,6 +137,16 @@ pub const Inst = struct {...@@ -135,6 +137,16 @@ pub const Inst = struct {
135 kw_args: struct {},137 kw_args: struct {},
136 };138 };
137139
140 pub const CompileError = struct {
141 pub const base_tag = Tag.compileerror;
142 base: Inst,
143
144 positionals: struct {
145 msg: []const u8,
146 },
147 kw_args: struct {},
148 };
149
138 pub const Str = struct {150 pub const Str = struct {
139 pub const base_tag = Tag.str;151 pub const base_tag = Tag.str;
140 base: Inst,152 base: Inst,
...@@ -513,6 +525,7 @@ pub const Module = struct {...@@ -513,6 +525,7 @@ pub const Module = struct {
513 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),525 .call => return self.writeInstToStreamGeneric(stream, .call, decl, inst_table),
514 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),526 .declref => return self.writeInstToStreamGeneric(stream, .declref, decl, inst_table),
515 .declval => return self.writeInstToStreamGeneric(stream, .declval, decl, inst_table),527 .declval => return self.writeInstToStreamGeneric(stream, .declval, decl, inst_table),
528 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, decl, inst_table),
516 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),529 .str => return self.writeInstToStreamGeneric(stream, .str, decl, inst_table),
517 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),530 .int => return self.writeInstToStreamGeneric(stream, .int, decl, inst_table),
518 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),531 .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, decl, inst_table),
...@@ -917,6 +930,7 @@ const Parser = struct {...@@ -917,6 +930,7 @@ const Parser = struct {
917 try requireEatBytes(self, ")");930 try requireEatBytes(self, ")");
918931
919 inst_specific.base.contents = self.source[contents_start..self.i];932 inst_specific.base.contents = self.source[contents_start..self.i];
933 //std.debug.warn("parsed {} = '{}'\n", .{ inst_specific.base.name, inst_specific.base.contents });
920934
921 return &inst_specific.base;935 return &inst_specific.base;
922 }936 }
...@@ -1230,7 +1244,44 @@ const EmitZIR = struct {...@@ -1230,7 +1244,44 @@ const EmitZIR = struct {
1230 var instructions = std.ArrayList(*Inst).init(self.allocator);1244 var instructions = std.ArrayList(*Inst).init(self.allocator);
1231 defer instructions.deinit();1245 defer instructions.deinit();
12321246
1233 try self.emitBody(module_fn.analysis.success, &inst_table, &instructions);1247 switch (module_fn.analysis) {
1248 .queued => unreachable,
1249 .in_progress => unreachable,
1250 .success => |body| {
1251 try self.emitBody(body, &inst_table, &instructions);
1252 },
1253 .sema_failure => {
1254 const err_msg = self.old_module.failed_decls.getValue(module_fn.owner_decl).?;
1255 const fail_inst = try self.arena.allocator.create(Inst.CompileError);
1256 fail_inst.* = .{
1257 .base = .{
1258 .name = try self.autoName(),
1259 .src = src,
1260 .tag = Inst.CompileError.base_tag,
1261 },
1262 .positionals = .{
1263 .msg = try self.arena.allocator.dupe(u8, err_msg.msg),
1264 },
1265 .kw_args = .{},
1266 };
1267 try instructions.append(&fail_inst.base);
1268 },
1269 .dependency_failure => {
1270 const fail_inst = try self.arena.allocator.create(Inst.CompileError);
1271 fail_inst.* = .{
1272 .base = .{
1273 .name = try self.autoName(),
1274 .src = src,
1275 .tag = Inst.CompileError.base_tag,
1276 },
1277 .positionals = .{
1278 .msg = try self.arena.allocator.dupe(u8, "depends on another failed Decl"),
1279 },
1280 .kw_args = .{},
1281 };
1282 try instructions.append(&fail_inst.base);
1283 },
1284 }
12341285
1235 const fn_type = try self.emitType(src, module_fn.fn_type);1286 const fn_type = try self.emitType(src, module_fn.fn_type);
12361287