authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-03 20:35:23-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:35-08:00
log9bf715de74a7d5badeae932afb594b7c6b33afa3
tree302e2c5a42d30e379c5bb2e86c24360ea49ab3fb
parent77accf597d845245847b143e42ec4109c9468480

rework error handling in the backends


15 files changed, 323 insertions(+), 512 deletions(-)

src/Zcu.zig+39-1
......@@ -4072,15 +4072,53 @@ pub fn navValIsConst(zcu: *const Zcu, val: InternPool.Index) bool {
40724072 };
40734073}
40744074
4075pub const CodegenFailError = error{
4076 /// Indicates the error message has been already stored at `Zcu.failed_codegen`.
4077 CodegenFail,
4078 OutOfMemory,
4079};
4080
40754081pub fn codegenFail(
40764082 zcu: *Zcu,
40774083 nav_index: InternPool.Nav.Index,
40784084 comptime format: []const u8,
40794085 args: anytype,
4080) error{ CodegenFail, OutOfMemory } {
4086) CodegenFailError {
40814087 const gpa = zcu.gpa;
40824088 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
40834089 const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args);
40844090 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg);
40854091 return error.CodegenFail;
40864092}
4093
4094pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg) CodegenFailError {
4095 const gpa = zcu.gpa;
4096 {
4097 errdefer msg.deinit(gpa);
4098 try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg);
4099 }
4100 return error.CodegenFail;
4101}
4102
4103pub fn codegenFailType(
4104 zcu: *Zcu,
4105 ty_index: InternPool.Index,
4106 comptime format: []const u8,
4107 args: anytype,
4108) CodegenFailError {
4109 const gpa = zcu.gpa;
4110 try zcu.failed_types.ensureUnusedCapacity(gpa, 1);
4111 const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args);
4112 zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
4113 return error.CodegenFail;
4114}
4115
4116pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) CodegenFailError {
4117 const gpa = zcu.gpa;
4118 {
4119 errdefer msg.deinit(gpa);
4120 try zcu.failed_types.ensureUnusedCapacity(gpa, 1);
4121 }
4122 zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
4123 return error.CodegenFail;
4124}
src/Zcu/PerThread.zig+2-9
......@@ -1726,7 +1726,6 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
17261726 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
17271727 error.OutOfMemory => return error.OutOfMemory,
17281728 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
1729 error.LinkFailure => assert(comp.link_diags.hasErrors()),
17301729 error.Overflow => {
17311730 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
17321731 gpa,
......@@ -3112,7 +3111,6 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error
31123111 lf.updateNav(pt, nav_index) catch |err| switch (err) {
31133112 error.OutOfMemory => return error.OutOfMemory,
31143113 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
3115 error.LinkFailure => assert(comp.link_diags.hasErrors()),
31163114 error.Overflow => {
31173115 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
31183116 gpa,
......@@ -3139,7 +3137,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{
31393137 const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
31403138 defer codegen_prog_node.end();
31413139
3142 if (zcu.failed_types.fetchSwapRemove(ty)) |entry| entry.deinit();
3140 if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(gpa);
31433141
31443142 if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {
31453143 // This type failed to resolve. This is a transitive failure.
......@@ -3148,12 +3146,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{
31483146
31493147 if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) {
31503148 error.OutOfMemory => return error.OutOfMemory,
3151 else => |e| try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create(
3152 gpa,
3153 zcu.typeSrcLoc(ty),
3154 "failed to update container type: {s}",
3155 .{@errorName(e)},
3156 )),
3149 error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),
31573150 };
31583151}
31593152
src/arch/aarch64/CodeGen.zig+16-36
......@@ -24,7 +24,6 @@ const build_options = @import("build_options");
2424const Alignment = InternPool.Alignment;
2525
2626const CodeGenError = codegen.CodeGenError;
27const Result = codegen.Result;
2827
2928const bits = @import("bits.zig");
3029const abi = @import("abi.zig");
......@@ -51,7 +50,6 @@ debug_output: link.File.DebugInfoOutput,
5150target: *const std.Target,
5251func_index: InternPool.Index,
5352owner_nav: InternPool.Nav.Index,
54err_msg: ?*ErrorMsg,
5553args: []MCValue,
5654ret_mcv: MCValue,
5755fn_type: Type,
......@@ -167,7 +165,7 @@ const DbgInfoReloc = struct {
167165 name: [:0]const u8,
168166 mcv: MCValue,
169167
170 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
168 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
171169 switch (reloc.tag) {
172170 .arg,
173171 .dbg_arg_inline,
......@@ -181,7 +179,7 @@ const DbgInfoReloc = struct {
181179 }
182180 }
183181
184 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
182 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
185183 switch (function.debug_output) {
186184 .dwarf => |dw| {
187185 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
......@@ -209,7 +207,7 @@ const DbgInfoReloc = struct {
209207 }
210208 }
211209
212 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
210 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
213211 switch (function.debug_output) {
214212 .dwarf => |dwarf| {
215213 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
......@@ -327,7 +325,7 @@ pub fn generate(
327325 liveness: Liveness,
328326 code: *std.ArrayList(u8),
329327 debug_output: link.File.DebugInfoOutput,
330) CodeGenError!Result {
328) CodeGenError!void {
331329 const zcu = pt.zcu;
332330 const gpa = zcu.gpa;
333331 const func = zcu.funcInfo(func_index);
......@@ -353,7 +351,6 @@ pub fn generate(
353351 .bin_file = lf,
354352 .func_index = func_index,
355353 .owner_nav = func.owner_nav,
356 .err_msg = null,
357354 .args = undefined, // populated after `resolveCallingConventionValues`
358355 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
359356 .fn_type = fn_type,
......@@ -370,10 +367,7 @@ pub fn generate(
370367 defer function.dbg_info_relocs.deinit(gpa);
371368
372369 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
373 error.CodegenFail => return Result{ .fail = function.err_msg.? },
374 error.OutOfRegisters => return Result{
375 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
376 },
370 error.CodegenFail => return error.CodegenFail,
377371 else => |e| return e,
378372 };
379373 defer call_info.deinit(&function);
......@@ -384,15 +378,14 @@ pub fn generate(
384378 function.max_end_stack = call_info.stack_byte_count;
385379
386380 function.gen() catch |err| switch (err) {
387 error.CodegenFail => return Result{ .fail = function.err_msg.? },
388 error.OutOfRegisters => return Result{
389 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
390 },
381 error.CodegenFail => return error.CodegenFail,
382 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
391383 else => |e| return e,
392384 };
393385
394386 for (function.dbg_info_relocs.items) |reloc| {
395 try reloc.genDbgInfo(function);
387 reloc.genDbgInfo(function) catch |err|
388 return function.fail("failed to generate debug info: {s}", .{@errorName(err)});
396389 }
397390
398391 var mir: Mir = .{
......@@ -417,15 +410,9 @@ pub fn generate(
417410 defer emit.deinit();
418411
419412 emit.emitMir() catch |err| switch (err) {
420 error.EmitFail => return Result{ .fail = emit.err_msg.? },
413 error.EmitFail => return function.failMsg(emit.err_msg.?),
421414 else => |e| return e,
422415 };
423
424 if (function.err_msg) |em| {
425 return Result{ .fail = em };
426 } else {
427 return Result.ok;
428 }
429416}
430417
431418fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
......@@ -567,7 +554,7 @@ fn gen(self: *Self) !void {
567554 .data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } },
568555 });
569556 } else {
570 return self.failSymbol("TODO AArch64: allow larger stacks", .{});
557 @panic("TODO AArch64: allow larger stacks");
571558 }
572559
573560 _ = try self.addInst(.{
......@@ -6191,10 +6178,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
61916178 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
61926179 .load_symbol, .load_tlv, .lea_symbol, .lea_direct => unreachable, // TODO
61936180 },
6194 .fail => |msg| {
6195 self.err_msg = msg;
6196 return error.CodegenFail;
6197 },
6181 .fail => |msg| return self.failMsg(msg),
61986182 };
61996183 return mcv;
62006184}
......@@ -6355,18 +6339,14 @@ fn wantSafety(self: *Self) bool {
63556339 };
63566340}
63576341
6358fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
6342fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
63596343 @branchHint(.cold);
6360 assert(self.err_msg == null);
6361 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
6362 return error.CodegenFail;
6344 return self.pt.zcu.codegenFail(self.owner_nav, format, args);
63636345}
63646346
6365fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
6347fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
63666348 @branchHint(.cold);
6367 assert(self.err_msg == null);
6368 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
6369 return error.CodegenFail;
6349 return self.pt.zcu.codegenFailMsg(self.owner_nav, msg);
63706350}
63716351
63726352fn parseRegName(name: []const u8) ?Register {
src/arch/arm/CodeGen.zig+19-31
......@@ -23,7 +23,6 @@ const log = std.log.scoped(.codegen);
2323const build_options = @import("build_options");
2424const Alignment = InternPool.Alignment;
2525
26const Result = codegen.Result;
2726const CodeGenError = codegen.CodeGenError;
2827
2928const bits = @import("bits.zig");
......@@ -245,7 +244,7 @@ const DbgInfoReloc = struct {
245244 name: [:0]const u8,
246245 mcv: MCValue,
247246
248 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
247 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
249248 switch (reloc.tag) {
250249 .arg,
251250 .dbg_arg_inline,
......@@ -259,7 +258,7 @@ const DbgInfoReloc = struct {
259258 }
260259 }
261260
262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
261 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
263262 switch (function.debug_output) {
264263 .dwarf => |dw| {
265264 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
......@@ -287,7 +286,7 @@ const DbgInfoReloc = struct {
287286 }
288287 }
289288
290 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
289 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
291290 switch (function.debug_output) {
292291 .dwarf => |dw| {
293292 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
......@@ -335,7 +334,7 @@ pub fn generate(
335334 liveness: Liveness,
336335 code: *std.ArrayList(u8),
337336 debug_output: link.File.DebugInfoOutput,
338) CodeGenError!Result {
337) CodeGenError!void {
339338 const zcu = pt.zcu;
340339 const gpa = zcu.gpa;
341340 const func = zcu.funcInfo(func_index);
......@@ -377,10 +376,7 @@ pub fn generate(
377376 defer function.dbg_info_relocs.deinit(gpa);
378377
379378 var call_info = function.resolveCallingConventionValues(func_ty) catch |err| switch (err) {
380 error.CodegenFail => return Result{ .fail = function.err_msg.? },
381 error.OutOfRegisters => return Result{
382 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
383 },
379 error.CodegenFail => return error.CodegenFail,
384380 else => |e| return e,
385381 };
386382 defer call_info.deinit(&function);
......@@ -391,15 +387,14 @@ pub fn generate(
391387 function.max_end_stack = call_info.stack_byte_count;
392388
393389 function.gen() catch |err| switch (err) {
394 error.CodegenFail => return Result{ .fail = function.err_msg.? },
395 error.OutOfRegisters => return Result{
396 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
397 },
390 error.CodegenFail => return error.CodegenFail,
391 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
398392 else => |e| return e,
399393 };
400394
401395 for (function.dbg_info_relocs.items) |reloc| {
402 try reloc.genDbgInfo(function);
396 reloc.genDbgInfo(function) catch |err|
397 return function.fail("failed to generate debug info: {s}", .{@errorName(err)});
403398 }
404399
405400 var mir = Mir{
......@@ -424,15 +419,9 @@ pub fn generate(
424419 defer emit.deinit();
425420
426421 emit.emitMir() catch |err| switch (err) {
427 error.EmitFail => return Result{ .fail = emit.err_msg.? },
422 error.EmitFail => return function.failMsg(emit.err_msg.?),
428423 else => |e| return e,
429424 };
430
431 if (function.err_msg) |em| {
432 return Result{ .fail = em };
433 } else {
434 return Result.ok;
435 }
436425}
437426
438427fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
......@@ -6310,20 +6299,19 @@ fn wantSafety(self: *Self) bool {
63106299 };
63116300}
63126301
6313fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
6302fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
63146303 @branchHint(.cold);
6315 assert(self.err_msg == null);
6316 const gpa = self.gpa;
6317 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
6318 return error.CodegenFail;
6304 const zcu = self.pt.zcu;
6305 const func = zcu.funcInfo(self.func_index);
6306 const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
6307 return zcu.codegenFailMsg(func.owner_nav, msg);
63196308}
63206309
6321fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
6310fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
63226311 @branchHint(.cold);
6323 assert(self.err_msg == null);
6324 const gpa = self.gpa;
6325 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
6326 return error.CodegenFail;
6312 const zcu = self.pt.zcu;
6313 const func = zcu.funcInfo(self.func_index);
6314 return zcu.codegenFailMsg(func.owner_nav, msg);
63276315}
63286316
63296317fn parseRegName(name: []const u8) ?Register {
src/arch/riscv64/CodeGen.zig+31-74
......@@ -32,7 +32,6 @@ const wip_mir_log = std.log.scoped(.wip_mir);
3232const Alignment = InternPool.Alignment;
3333
3434const CodeGenError = codegen.CodeGenError;
35const Result = codegen.Result;
3635
3736const bits = @import("bits.zig");
3837const abi = @import("abi.zig");
......@@ -62,7 +61,6 @@ gpa: Allocator,
6261mod: *Package.Module,
6362target: *const std.Target,
6463debug_output: link.File.DebugInfoOutput,
65err_msg: ?*ErrorMsg,
6664args: []MCValue,
6765ret_mcv: InstTracking,
6866fn_type: Type,
......@@ -761,7 +759,7 @@ pub fn generate(
761759 liveness: Liveness,
762760 code: *std.ArrayList(u8),
763761 debug_output: link.File.DebugInfoOutput,
764) CodeGenError!Result {
762) CodeGenError!void {
765763 const zcu = pt.zcu;
766764 const comp = zcu.comp;
767765 const gpa = zcu.gpa;
......@@ -788,7 +786,6 @@ pub fn generate(
788786 .target = &mod.resolved_target.result,
789787 .debug_output = debug_output,
790788 .owner = .{ .nav_index = func.owner_nav },
791 .err_msg = null,
792789 .args = undefined, // populated after `resolveCallingConventionValues`
793790 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
794791 .fn_type = fn_type,
......@@ -829,10 +826,7 @@ pub fn generate(
829826
830827 const fn_info = zcu.typeToFunc(fn_type).?;
831828 var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) {
832 error.CodegenFail => return Result{ .fail = function.err_msg.? },
833 error.OutOfRegisters => return Result{
834 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
835 },
829 error.CodegenFail => return error.CodegenFail,
836830 else => |e| return e,
837831 };
838832
......@@ -861,10 +855,8 @@ pub fn generate(
861855 }));
862856
863857 function.gen() catch |err| switch (err) {
864 error.CodegenFail => return Result{ .fail = function.err_msg.? },
865 error.OutOfRegisters => return Result{
866 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
867 },
858 error.CodegenFail => return error.CodegenFail,
859 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
868860 else => |e| return e,
869861 };
870862
......@@ -895,28 +887,10 @@ pub fn generate(
895887 defer emit.deinit();
896888
897889 emit.emitMir() catch |err| switch (err) {
898 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
899 error.InvalidInstruction => |e| {
900 const msg = switch (e) {
901 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
902 };
903 return Result{
904 .fail = try ErrorMsg.create(
905 gpa,
906 src_loc,
907 "{s} This is a bug in the Zig compiler.",
908 .{msg},
909 ),
910 };
911 },
890 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
891 error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
912892 else => |e| return e,
913893 };
914
915 if (function.err_msg) |em| {
916 return Result{ .fail = em };
917 } else {
918 return Result.ok;
919 }
920894}
921895
922896pub fn generateLazy(
......@@ -926,7 +900,7 @@ pub fn generateLazy(
926900 lazy_sym: link.File.LazySymbol,
927901 code: *std.ArrayList(u8),
928902 debug_output: link.File.DebugInfoOutput,
929) CodeGenError!Result {
903) CodeGenError!void {
930904 const comp = bin_file.comp;
931905 const gpa = comp.gpa;
932906 const mod = comp.root_mod;
......@@ -941,7 +915,6 @@ pub fn generateLazy(
941915 .target = &mod.resolved_target.result,
942916 .debug_output = debug_output,
943917 .owner = .{ .lazy_sym = lazy_sym },
944 .err_msg = null,
945918 .args = undefined, // populated after `resolveCallingConventionValues`
946919 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
947920 .fn_type = undefined,
......@@ -957,10 +930,8 @@ pub fn generateLazy(
957930 defer function.mir_instructions.deinit(gpa);
958931
959932 function.genLazy(lazy_sym) catch |err| switch (err) {
960 error.CodegenFail => return Result{ .fail = function.err_msg.? },
961 error.OutOfRegisters => return Result{
962 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
963 },
933 error.CodegenFail => return error.CodegenFail,
934 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
964935 else => |e| return e,
965936 };
966937
......@@ -991,28 +962,10 @@ pub fn generateLazy(
991962 defer emit.deinit();
992963
993964 emit.emitMir() catch |err| switch (err) {
994 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
995 error.InvalidInstruction => |e| {
996 const msg = switch (e) {
997 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
998 };
999 return Result{
1000 .fail = try ErrorMsg.create(
1001 gpa,
1002 src_loc,
1003 "{s} This is a bug in the Zig compiler.",
1004 .{msg},
1005 ),
1006 };
1007 },
965 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
966 error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
1008967 else => |e| return e,
1009968 };
1010
1011 if (function.err_msg) |em| {
1012 return Result{ .fail = em };
1013 } else {
1014 return Result.ok;
1015 }
1016969}
1017970
1018971const FormatWipMirData = struct {
......@@ -4758,19 +4711,19 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
47584711 return func.fail("TODO implement codegen airFieldParentPtr", .{});
47594712}
47604713
4761fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4714fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerError!void {
47624715 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
47634716 const ty = arg.ty.toType();
47644717 if (arg.name == .none) return;
47654718
47664719 switch (func.debug_output) {
47674720 .dwarf => |dw| switch (mcv) {
4768 .register => |reg| try dw.genLocalDebugInfo(
4721 .register => |reg| dw.genLocalDebugInfo(
47694722 .local_arg,
47704723 arg.name.toSlice(func.air),
47714724 ty,
47724725 .{ .reg = reg.dwarfNum() },
4773 ),
4726 ) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),
47744727 .load_frame => {},
47754728 else => {},
47764729 },
......@@ -4779,7 +4732,7 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
47794732 }
47804733}
47814734
4782fn airArg(func: *Func, inst: Air.Inst.Index) !void {
4735fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
47834736 var arg_index = func.arg_index;
47844737
47854738 // we skip over args that have no bits
......@@ -5255,7 +5208,7 @@ fn airDbgInlineBlock(func: *Func, inst: Air.Inst.Index) !void {
52555208 try func.lowerBlock(inst, @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
52565209}
52575210
5258fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
5211fn airDbgVar(func: *Func, inst: Air.Inst.Index) InnerError!void {
52595212 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
52605213 const operand = pl_op.operand;
52615214 const ty = func.typeOf(operand);
......@@ -5263,7 +5216,8 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
52635216 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
52645217
52655218 const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)];
5266 try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air));
5219 func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air)) catch |err|
5220 return func.fail("failed to generate variable debug info: {s}", .{@errorName(err)});
52675221
52685222 return func.finishAir(inst, .unreach, .{ operand, .none, .none });
52695223}
......@@ -8236,10 +8190,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
82368190 return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)});
82378191 },
82388192 },
8239 .fail => |msg| {
8240 func.err_msg = msg;
8241 return error.CodegenFail;
8242 },
8193 .fail => |msg| return func.failMsg(msg),
82438194 };
82448195 return mcv;
82458196}
......@@ -8427,17 +8378,23 @@ fn wantSafety(func: *Func) bool {
84278378 };
84288379}
84298380
8430fn fail(func: *Func, comptime format: []const u8, args: anytype) InnerError {
8381fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
84318382 @branchHint(.cold);
8432 assert(func.err_msg == null);
8433 func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args);
8383 const zcu = func.pt.zcu;
8384 switch (func.owner) {
8385 .nav_index => |i| return zcu.codegenFail(i, format, args),
8386 .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),
8387 }
84348388 return error.CodegenFail;
84358389}
84368390
8437fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerError {
8391fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
84388392 @branchHint(.cold);
8439 assert(func.err_msg == null);
8440 func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args);
8393 const zcu = func.pt.zcu;
8394 switch (func.owner) {
8395 .nav_index => |i| return zcu.codegenFailMsg(i, msg),
8396 .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
8397 }
84418398 return error.CodegenFail;
84428399}
84438400
src/arch/sparc64/CodeGen.zig+20-24
......@@ -21,7 +21,6 @@ const Emit = @import("Emit.zig");
2121const Liveness = @import("../../Liveness.zig");
2222const Type = @import("../../Type.zig");
2323const CodeGenError = codegen.CodeGenError;
24const Result = @import("../../codegen.zig").Result;
2524const Endian = std.builtin.Endian;
2625const Alignment = InternPool.Alignment;
2726
......@@ -268,7 +267,7 @@ pub fn generate(
268267 liveness: Liveness,
269268 code: *std.ArrayList(u8),
270269 debug_output: link.File.DebugInfoOutput,
271) CodeGenError!Result {
270) CodeGenError!void {
272271 const zcu = pt.zcu;
273272 const gpa = zcu.gpa;
274273 const func = zcu.funcInfo(func_index);
......@@ -310,10 +309,7 @@ pub fn generate(
310309 defer function.exitlude_jump_relocs.deinit(gpa);
311310
312311 var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) {
313 error.CodegenFail => return Result{ .fail = function.err_msg.? },
314 error.OutOfRegisters => return Result{
315 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
316 },
312 error.CodegenFail => return error.CodegenFail,
317313 else => |e| return e,
318314 };
319315 defer call_info.deinit(&function);
......@@ -324,10 +320,8 @@ pub fn generate(
324320 function.max_end_stack = call_info.stack_byte_count;
325321
326322 function.gen() catch |err| switch (err) {
327 error.CodegenFail => return Result{ .fail = function.err_msg.? },
328 error.OutOfRegisters => return Result{
329 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
330 },
323 error.CodegenFail => return error.CodegenFail,
324 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
331325 else => |e| return e,
332326 };
333327
......@@ -351,15 +345,9 @@ pub fn generate(
351345 defer emit.deinit();
352346
353347 emit.emitMir() catch |err| switch (err) {
354 error.EmitFail => return Result{ .fail = emit.err_msg.? },
348 error.EmitFail => return function.failMsg(emit.err_msg.?),
355349 else => |e| return e,
356350 };
357
358 if (function.err_msg) |em| {
359 return Result{ .fail = em };
360 } else {
361 return Result.ok;
362 }
363351}
364352
365353fn gen(self: *Self) !void {
......@@ -1014,7 +1002,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
10141002 return bt.finishAir(result);
10151003}
10161004
1017fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1005fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
10181006 const pt = self.pt;
10191007 const zcu = pt.zcu;
10201008 const arg_index = self.arg_index;
......@@ -1036,7 +1024,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
10361024 }
10371025 };
10381026
1039 try self.genArgDbgInfo(inst, mcv);
1027 self.genArgDbgInfo(inst, mcv) catch |err|
1028 return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});
10401029
10411030 if (self.liveness.isUnused(inst))
10421031 return self.finishAirBookkeeping();
......@@ -3511,12 +3500,19 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
35113500 }
35123501}
35133502
3514fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
3503fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
35153504 @branchHint(.cold);
3516 assert(self.err_msg == null);
3517 const gpa = self.gpa;
3518 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
3519 return error.CodegenFail;
3505 const zcu = self.pt.zcu;
3506 const func = zcu.funcInfo(self.func_index);
3507 const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
3508 return zcu.codegenFailMsg(func.owner_nav, msg);
3509}
3510
3511fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
3512 @branchHint(.cold);
3513 const zcu = self.pt.zcu;
3514 const func = zcu.funcInfo(self.func_index);
3515 return zcu.codegenFailMsg(func.owner_nav, msg);
35203516}
35213517
35223518/// Called when there are no operands, and the instruction is always unreferenced.
src/arch/x86_64/CodeGen.zig+34-83
......@@ -19,7 +19,6 @@ const Allocator = mem.Allocator;
1919const CodeGenError = codegen.CodeGenError;
2020const Compilation = @import("../../Compilation.zig");
2121const ErrorMsg = Zcu.ErrorMsg;
22const Result = codegen.Result;
2322const Emit = @import("Emit.zig");
2423const Liveness = @import("../../Liveness.zig");
2524const Lower = @import("Lower.zig");
......@@ -59,7 +58,6 @@ target: *const std.Target,
5958owner: Owner,
6059inline_func: InternPool.Index,
6160mod: *Package.Module,
62err_msg: ?*ErrorMsg,
6361arg_index: u32,
6462args: []MCValue,
6563va_info: union {
......@@ -821,7 +819,7 @@ pub fn generate(
821819 liveness: Liveness,
822820 code: *std.ArrayList(u8),
823821 debug_output: link.File.DebugInfoOutput,
824) CodeGenError!Result {
822) CodeGenError!void {
825823 const zcu = pt.zcu;
826824 const comp = zcu.comp;
827825 const gpa = zcu.gpa;
......@@ -841,7 +839,6 @@ pub fn generate(
841839 .debug_output = debug_output,
842840 .owner = .{ .nav_index = func.owner_nav },
843841 .inline_func = func_index,
844 .err_msg = null,
845842 .arg_index = undefined,
846843 .args = undefined, // populated after `resolveCallingConventionValues`
847844 .va_info = undefined, // populated after `resolveCallingConventionValues`
......@@ -881,15 +878,7 @@ pub fn generate(
881878 const fn_info = zcu.typeToFunc(fn_type).?;
882879 const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*);
883880 var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) {
884 error.CodegenFail => return Result{ .fail = function.err_msg.? },
885 error.OutOfRegisters => return Result{
886 .fail = try ErrorMsg.create(
887 gpa,
888 src_loc,
889 "CodeGen ran out of registers. This is a bug in the Zig compiler.",
890 .{},
891 ),
892 },
881 error.CodegenFail => return error.CodegenFail,
893882 else => |e| return e,
894883 };
895884 defer call_info.deinit(&function);
......@@ -926,10 +915,8 @@ pub fn generate(
926915 };
927916
928917 function.gen() catch |err| switch (err) {
929 error.CodegenFail => return Result{ .fail = function.err_msg.? },
930 error.OutOfRegisters => return Result{
931 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
932 },
918 error.CodegenFail => return error.CodegenFail,
919 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
933920 else => |e| return e,
934921 };
935922
......@@ -953,10 +940,7 @@ pub fn generate(
953940 .pic = mod.pic,
954941 },
955942 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
956 error.CodegenFail => return Result{ .fail = function.err_msg.? },
957 error.OutOfRegisters => return Result{
958 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
959 },
943 error.CodegenFail => return error.CodegenFail,
960944 else => |e| return e,
961945 },
962946 .debug_output = debug_output,
......@@ -974,29 +958,11 @@ pub fn generate(
974958 };
975959 defer emit.deinit();
976960 emit.emitMir() catch |err| switch (err) {
977 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
978 error.InvalidInstruction, error.CannotEncode => |e| {
979 const msg = switch (e) {
980 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
981 error.CannotEncode => "CodeGen failed to encode the instruction.",
982 };
983 return Result{
984 .fail = try ErrorMsg.create(
985 gpa,
986 src_loc,
987 "{s} This is a bug in the Zig compiler.",
988 .{msg},
989 ),
990 };
991 },
992 else => |e| return e,
993 };
961 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
994962
995 if (function.err_msg) |em| {
996 return Result{ .fail = em };
997 } else {
998 return Result.ok;
999 }
963 error.InvalidInstruction, error.CannotEncode => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
964 else => |e| return function.fail("emit MIR failed: {s}", .{@errorName(e)}),
965 };
1000966}
1001967
1002968pub fn generateLazy(
......@@ -1006,7 +972,7 @@ pub fn generateLazy(
1006972 lazy_sym: link.File.LazySymbol,
1007973 code: *std.ArrayList(u8),
1008974 debug_output: link.File.DebugInfoOutput,
1009) CodeGenError!Result {
975) CodeGenError!void {
1010976 const comp = bin_file.comp;
1011977 const gpa = comp.gpa;
1012978 // This function is for generating global code, so we use the root module.
......@@ -1022,7 +988,6 @@ pub fn generateLazy(
1022988 .debug_output = debug_output,
1023989 .owner = .{ .lazy_sym = lazy_sym },
1024990 .inline_func = undefined,
1025 .err_msg = null,
1026991 .arg_index = undefined,
1027992 .args = undefined,
1028993 .va_info = undefined,
......@@ -1038,10 +1003,8 @@ pub fn generateLazy(
10381003 }
10391004
10401005 function.genLazy(lazy_sym) catch |err| switch (err) {
1041 error.CodegenFail => return Result{ .fail = function.err_msg.? },
1042 error.OutOfRegisters => return Result{
1043 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
1044 },
1006 error.CodegenFail => return error.CodegenFail,
1007 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
10451008 else => |e| return e,
10461009 };
10471010
......@@ -1065,10 +1028,7 @@ pub fn generateLazy(
10651028 .pic = mod.pic,
10661029 },
10671030 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
1068 error.CodegenFail => return Result{ .fail = function.err_msg.? },
1069 error.OutOfRegisters => return Result{
1070 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
1071 },
1031 error.CodegenFail => return error.CodegenFail,
10721032 else => |e| return e,
10731033 },
10741034 .debug_output = debug_output,
......@@ -1078,29 +1038,11 @@ pub fn generateLazy(
10781038 };
10791039 defer emit.deinit();
10801040 emit.emitMir() catch |err| switch (err) {
1081 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
1082 error.InvalidInstruction, error.CannotEncode => |e| {
1083 const msg = switch (e) {
1084 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
1085 error.CannotEncode => "CodeGen failed to encode the instruction.",
1086 };
1087 return Result{
1088 .fail = try ErrorMsg.create(
1089 gpa,
1090 src_loc,
1091 "{s} This is a bug in the Zig compiler.",
1092 .{msg},
1093 ),
1094 };
1095 },
1096 else => |e| return e,
1041 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
1042 error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}),
1043 error.CannotEncode => return function.fail("failed to find encode x86 instruction (Zig compiler bug)", .{}),
1044 else => |e| return function.fail("failed to emit MIR: {s}", .{@errorName(e)}),
10971045 };
1098
1099 if (function.err_msg) |em| {
1100 return Result{ .fail = em };
1101 } else {
1102 return Result.ok;
1103 }
11041046}
11051047
11061048const FormatNavData = struct {
......@@ -19276,10 +19218,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
1927619218 .load_got => |sym_index| .{ .lea_got = sym_index },
1927719219 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
1927819220 },
19279 .fail => |msg| {
19280 self.err_msg = msg;
19281 return error.CodegenFail;
19282 },
19221 .fail => |msg| return self.failMsg(msg),
1928319222 };
1928419223}
1928519224
......@@ -19592,11 +19531,23 @@ fn resolveCallingConventionValues(
1959219531 return result;
1959319532}
1959419533
19595fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
19534fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
1959619535 @branchHint(.cold);
19597 assert(self.err_msg == null);
19598 const gpa = self.gpa;
19599 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
19536 const zcu = self.pt.zcu;
19537 switch (self.owner) {
19538 .nav_index => |i| return zcu.codegenFail(i, format, args),
19539 .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),
19540 }
19541 return error.CodegenFail;
19542}
19543
19544fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
19545 @branchHint(.cold);
19546 const zcu = self.pt.zcu;
19547 switch (self.owner) {
19548 .nav_index => |i| return zcu.codegenFailMsg(i, msg),
19549 .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
19550 }
1960019551 return error.CodegenFail;
1960119552}
1960219553
src/codegen.zig+56-113
......@@ -24,13 +24,6 @@ const Zir = std.zig.Zir;
2424const Alignment = InternPool.Alignment;
2525const dev = @import("dev.zig");
2626
27pub const Result = union(enum) {
28 /// The `code` parameter passed to `generateSymbol` has the value.
29 ok,
30 /// There was a codegen error.
31 fail: *ErrorMsg,
32};
33
3427pub const CodeGenError = error{
3528 OutOfMemory,
3629 /// Compiler was asked to operate on a number larger than supported.
......@@ -64,7 +57,7 @@ pub fn generateFunction(
6457 liveness: Liveness,
6558 code: *std.ArrayList(u8),
6659 debug_output: link.File.DebugInfoOutput,
67) CodeGenError!Result {
60) CodeGenError!void {
6861 const zcu = pt.zcu;
6962 const func = zcu.funcInfo(func_index);
7063 const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;
......@@ -89,7 +82,7 @@ pub fn generateLazyFunction(
8982 lazy_sym: link.File.LazySymbol,
9083 code: *std.ArrayList(u8),
9184 debug_output: link.File.DebugInfoOutput,
92) CodeGenError!Result {
85) CodeGenError!void {
9386 const zcu = pt.zcu;
9487 const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool);
9588 const target = zcu.fileByIndex(file).mod.resolved_target.result;
......@@ -120,17 +113,17 @@ pub fn generateLazySymbol(
120113 code: *std.ArrayList(u8),
121114 debug_output: link.File.DebugInfoOutput,
122115 reloc_parent: link.File.RelocInfo.Parent,
123) CodeGenError!Result {
116) CodeGenError!void {
124117 _ = reloc_parent;
125118
126119 const tracy = trace(@src());
127120 defer tracy.end();
128121
129122 const comp = bin_file.comp;
130 const ip = &pt.zcu.intern_pool;
123 const zcu = pt.zcu;
124 const ip = &zcu.intern_pool;
131125 const target = comp.root_mod.resolved_target.result;
132126 const endian = target.cpu.arch.endian();
133 const gpa = comp.gpa;
134127
135128 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
136129 @tagName(lazy_sym.kind),
......@@ -161,26 +154,29 @@ pub fn generateLazySymbol(
161154 string_index += @intCast(err_name.len + 1);
162155 }
163156 mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
164 return .ok;
165 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") {
157 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") {
166158 alignment.* = .@"1";
167159 const enum_ty = Type.fromInterned(lazy_sym.ty);
168 const tag_names = enum_ty.enumFields(pt.zcu);
160 const tag_names = enum_ty.enumFields(zcu);
169161 for (0..tag_names.len) |tag_index| {
170162 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
171163 try code.ensureUnusedCapacity(tag_name.len + 1);
172164 code.appendSliceAssumeCapacity(tag_name);
173165 code.appendAssumeCapacity(0);
174166 }
175 return .ok;
176 } else return .{ .fail = try .create(
177 gpa,
178 src_loc,
179 "TODO implement generateLazySymbol for {s} {}",
180 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
181 ) };
167 } else {
168 return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {}", .{
169 @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt),
170 });
171 }
182172}
183173
174pub const GenerateSymbolError = error{
175 OutOfMemory,
176 /// Compiler was asked to operate on a number larger than supported.
177 Overflow,
178};
179
184180pub fn generateSymbol(
185181 bin_file: *link.File,
186182 pt: Zcu.PerThread,
......@@ -188,7 +184,7 @@ pub fn generateSymbol(
188184 val: Value,
189185 code: *std.ArrayList(u8),
190186 reloc_parent: link.File.RelocInfo.Parent,
191) CodeGenError!Result {
187) GenerateSymbolError!void {
192188 const tracy = trace(@src());
193189 defer tracy.end();
194190
......@@ -204,7 +200,7 @@ pub fn generateSymbol(
204200 if (val.isUndefDeep(zcu)) {
205201 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
206202 try code.appendNTimes(0xaa, abi_size);
207 return .ok;
203 return;
208204 }
209205
210206 switch (ip.indexToKey(val.toIntern())) {
......@@ -266,7 +262,7 @@ pub fn generateSymbol(
266262
267263 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
268264 try code.writer().writeInt(u16, err_val, endian);
269 return .ok;
265 return;
270266 }
271267
272268 const payload_align = payload_ty.abiAlignment(zcu);
......@@ -281,13 +277,10 @@ pub fn generateSymbol(
281277 // emit payload part of the error union
282278 {
283279 const begin = code.items.len;
284 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
280 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
285281 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
286282 .payload => |payload| payload,
287 }), code, reloc_parent)) {
288 .ok => {},
289 .fail => |em| return .{ .fail = em },
290 }
283 }), code, reloc_parent);
291284 const unpadded_end = code.items.len - begin;
292285 const padded_end = abi_align.forward(unpadded_end);
293286 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
......@@ -312,10 +305,7 @@ pub fn generateSymbol(
312305 },
313306 .enum_tag => |enum_tag| {
314307 const int_tag_ty = ty.intTagType(zcu);
315 switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent)) {
316 .ok => {},
317 .fail => |em| return .{ .fail = em },
318 }
308 try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent);
319309 },
320310 .float => |float| switch (float.storage) {
321311 .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)),
......@@ -328,19 +318,10 @@ pub fn generateSymbol(
328318 },
329319 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
330320 },
331 .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0)) {
332 .ok => {},
333 .fail => |em| return .{ .fail = em },
334 },
321 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
335322 .slice => |slice| {
336 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent)) {
337 .ok => {},
338 .fail => |em| return .{ .fail = em },
339 }
340 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent)) {
341 .ok => {},
342 .fail => |em| return .{ .fail = em },
343 }
323 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent);
324 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent);
344325 },
345326 .opt => {
346327 const payload_type = ty.optionalChild(zcu);
......@@ -349,10 +330,7 @@ pub fn generateSymbol(
349330
350331 if (ty.optionalReprIsPayload(zcu)) {
351332 if (payload_val) |value| {
352 switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) {
353 .ok => {},
354 .fail => |em| return Result{ .fail = em },
355 }
333 try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
356334 } else {
357335 try code.appendNTimes(0, abi_size);
358336 }
......@@ -362,10 +340,7 @@ pub fn generateSymbol(
362340 const value = payload_val orelse Value.fromInterned(try pt.intern(.{
363341 .undef = payload_type.toIntern(),
364342 }));
365 switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) {
366 .ok => {},
367 .fail => |em| return Result{ .fail = em },
368 }
343 try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
369344 }
370345 try code.writer().writeByte(@intFromBool(payload_val != null));
371346 try code.appendNTimes(0, padding);
......@@ -377,17 +352,14 @@ pub fn generateSymbol(
377352 .elems, .repeated_elem => {
378353 var index: u64 = 0;
379354 while (index < array_type.lenIncludingSentinel()) : (index += 1) {
380 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
355 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
381356 .bytes => unreachable,
382357 .elems => |elems| elems[@intCast(index)],
383358 .repeated_elem => |elem| if (index < array_type.len)
384359 elem
385360 else
386361 array_type.sentinel,
387 }), code, reloc_parent)) {
388 .ok => {},
389 .fail => |em| return .{ .fail = em },
390 }
362 }), code, reloc_parent);
391363 }
392364 },
393365 },
......@@ -437,16 +409,13 @@ pub fn generateSymbol(
437409 .elems, .repeated_elem => {
438410 var index: u64 = 0;
439411 while (index < vector_type.len) : (index += 1) {
440 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
412 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
441413 .bytes => unreachable,
442414 .elems => |elems| elems[
443415 math.cast(usize, index) orelse return error.Overflow
444416 ],
445417 .repeated_elem => |elem| elem,
446 }), code, reloc_parent)) {
447 .ok => {},
448 .fail => |em| return .{ .fail = em },
449 }
418 }), code, reloc_parent);
450419 }
451420 },
452421 }
......@@ -476,10 +445,7 @@ pub fn generateSymbol(
476445 .repeated_elem => |elem| elem,
477446 };
478447
479 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) {
480 .ok => {},
481 .fail => |em| return Result{ .fail = em },
482 }
448 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
483449 const unpadded_field_end = code.items.len - struct_begin;
484450
485451 // Pad struct members if required
......@@ -518,10 +484,8 @@ pub fn generateSymbol(
518484 return error.Overflow;
519485 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
520486 defer tmp_list.deinit();
521 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent)) {
522 .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items),
523 .fail => |em| return Result{ .fail = em },
524 }
487 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent);
488 @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items);
525489 } else {
526490 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
527491 }
......@@ -553,10 +517,7 @@ pub fn generateSymbol(
553517 ) orelse return error.Overflow;
554518 if (padding > 0) try code.appendNTimes(0, padding);
555519
556 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) {
557 .ok => {},
558 .fail => |em| return Result{ .fail = em },
559 }
520 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
560521 }
561522
562523 const size = struct_type.sizeUnordered(ip);
......@@ -582,10 +543,7 @@ pub fn generateSymbol(
582543
583544 // Check if we should store the tag first.
584545 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
585 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) {
586 .ok => {},
587 .fail => |em| return Result{ .fail = em },
588 }
546 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
589547 }
590548
591549 const union_obj = zcu.typeToUnion(ty).?;
......@@ -595,10 +553,7 @@ pub fn generateSymbol(
595553 if (!field_ty.hasRuntimeBits(zcu)) {
596554 try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
597555 } else {
598 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) {
599 .ok => {},
600 .fail => |em| return Result{ .fail = em },
601 }
556 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
602557
603558 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
604559 if (padding > 0) {
......@@ -606,17 +561,11 @@ pub fn generateSymbol(
606561 }
607562 }
608563 } else {
609 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) {
610 .ok => {},
611 .fail => |em| return Result{ .fail = em },
612 }
564 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
613565 }
614566
615567 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
616 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) {
617 .ok => {},
618 .fail => |em| return Result{ .fail = em },
619 }
568 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
620569
621570 if (layout.padding > 0) {
622571 try code.appendNTimes(0, layout.padding);
......@@ -625,7 +574,6 @@ pub fn generateSymbol(
625574 },
626575 .memoized_call => unreachable,
627576 }
628 return .ok;
629577}
630578
631579fn lowerPtr(
......@@ -636,7 +584,7 @@ fn lowerPtr(
636584 code: *std.ArrayList(u8),
637585 reloc_parent: link.File.RelocInfo.Parent,
638586 prev_offset: u64,
639) CodeGenError!Result {
587) GenerateSymbolError!void {
640588 const zcu = pt.zcu;
641589 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
642590 const offset: u64 = prev_offset + ptr.byte_offset;
......@@ -689,7 +637,7 @@ fn lowerUavRef(
689637 code: *std.ArrayList(u8),
690638 reloc_parent: link.File.RelocInfo.Parent,
691639 offset: u64,
692) CodeGenError!Result {
640) GenerateSymbolError!void {
693641 const zcu = pt.zcu;
694642 const gpa = zcu.gpa;
695643 const ip = &zcu.intern_pool;
......@@ -702,14 +650,7 @@ fn lowerUavRef(
702650 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
703651 if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {
704652 try code.appendNTimes(0xaa, ptr_width_bytes);
705 return .ok;
706 }
707
708 const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
709 const res = try lf.lowerUav(pt, uav_val, uav_align, src_loc);
710 switch (res) {
711 .mcv => {},
712 .fail => |em| return .{ .fail = em },
653 return;
713654 }
714655
715656 switch (lf.tag) {
......@@ -727,11 +668,17 @@ fn lowerUavRef(
727668 .pointee = .{ .uav_index = uav.val },
728669 });
729670 try code.appendNTimes(0, ptr_width_bytes);
730 return .ok;
671 return;
731672 },
732673 else => {},
733674 }
734675
676 const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
677 switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) {
678 .mcv => {},
679 .fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}),
680 }
681
735682 const vaddr = try lf.getUavVAddr(uav_val, .{
736683 .parent = reloc_parent,
737684 .offset = code.items.len,
......@@ -744,8 +691,6 @@ fn lowerUavRef(
744691 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
745692 else => unreachable,
746693 }
747
748 return Result.ok;
749694}
750695
751696fn lowerNavRef(
......@@ -756,7 +701,7 @@ fn lowerNavRef(
756701 code: *std.ArrayList(u8),
757702 reloc_parent: link.File.RelocInfo.Parent,
758703 offset: u64,
759) CodeGenError!Result {
704) GenerateSymbolError!void {
760705 _ = src_loc;
761706 const zcu = pt.zcu;
762707 const gpa = zcu.gpa;
......@@ -768,7 +713,7 @@ fn lowerNavRef(
768713 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
769714 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
770715 try code.appendNTimes(0xaa, ptr_width_bytes);
771 return Result.ok;
716 return;
772717 }
773718
774719 switch (lf.tag) {
......@@ -786,16 +731,16 @@ fn lowerNavRef(
786731 .pointee = .{ .nav_index = nav_index },
787732 });
788733 try code.appendNTimes(0, ptr_width_bytes);
789 return .ok;
734 return;
790735 },
791736 else => {},
792737 }
793738
794 const vaddr = try lf.getNavVAddr(pt, nav_index, .{
739 const vaddr = lf.getNavVAddr(pt, nav_index, .{
795740 .parent = reloc_parent,
796741 .offset = code.items.len,
797742 .addend = @intCast(offset),
798 });
743 }) catch @panic("TODO rework getNavVAddr");
799744 const endian = target.cpu.arch.endian();
800745 switch (ptr_width_bytes) {
801746 2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),
......@@ -803,8 +748,6 @@ fn lowerNavRef(
803748 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
804749 else => unreachable,
805750 }
806
807 return .ok;
808751}
809752
810753/// Helper struct to denote that the value is in memory but requires a linker relocation fixup:
src/link.zig+7-1
......@@ -673,7 +673,13 @@ pub const File = struct {
673673 }
674674 }
675675
676 pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateNavError!void {
676 pub const UpdateContainerTypeError = error{
677 OutOfMemory,
678 /// `Zcu.failed_types` is already populated with the error message.
679 TypeFailureReported,
680 };
681
682 pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {
677683 switch (base.tag) {
678684 else => {},
679685 inline .elf => |tag| {
src/link/Coff.zig+57-48
......@@ -754,7 +754,7 @@ fn allocateGlobal(coff: *Coff) !u32 {
754754 return index;
755755}
756756
757fn addGotEntry(coff: *Coff, target: SymbolWithLoc) error{ OutOfMemory, LinkFailure }!void {
757fn addGotEntry(coff: *Coff, target: SymbolWithLoc) !void {
758758 const gpa = coff.base.comp.gpa;
759759 if (coff.got_table.lookup.contains(target)) return;
760760 const got_index = try coff.got_table.allocateEntry(gpa, target);
......@@ -780,7 +780,7 @@ pub fn createAtom(coff: *Coff) !Atom.Index {
780780 return atom_index;
781781}
782782
783fn growAtom(coff: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) link.File.UpdateNavError!u32 {
783fn growAtom(coff: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 {
784784 const atom = coff.getAtom(atom_index);
785785 const sym = atom.getSymbol(coff);
786786 const align_ok = mem.alignBackward(u32, sym.value, alignment) == sym.value;
......@@ -909,12 +909,12 @@ fn writeOffsetTableEntry(coff: *Coff, index: usize) !void {
909909 .p32 => {
910910 var buf: [4]u8 = undefined;
911911 mem.writeInt(u32, &buf, @intCast(entry_value + coff.image_base), .little);
912 try coff.pwriteAll(&buf, file_offset);
912 try coff.base.file.?.pwriteAll(&buf, file_offset);
913913 },
914914 .p64 => {
915915 var buf: [8]u8 = undefined;
916916 mem.writeInt(u64, &buf, entry_value + coff.image_base, .little);
917 try coff.pwriteAll(&buf, file_offset);
917 try coff.base.file.?.pwriteAll(&buf, file_offset);
918918 },
919919 }
920920
......@@ -1122,7 +1122,7 @@ pub fn updateFunc(
11221122 var code_buffer = std.ArrayList(u8).init(gpa);
11231123 defer code_buffer.deinit();
11241124
1125 const res = codegen.generateFunction(
1125 codegen.generateFunction(
11261126 &coff.base,
11271127 pt,
11281128 zcu.navSrcLoc(nav_index),
......@@ -1134,7 +1134,7 @@ pub fn updateFunc(
11341134 ) catch |err| switch (err) {
11351135 error.CodegenFail => return error.CodegenFail,
11361136 error.OutOfMemory => return error.OutOfMemory,
1137 else => |e| {
1137 error.Overflow => |e| {
11381138 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
11391139 gpa,
11401140 zcu.navSrcLoc(nav_index),
......@@ -1145,15 +1145,8 @@ pub fn updateFunc(
11451145 return error.CodegenFail;
11461146 },
11471147 };
1148 const code = switch (res) {
1149 .ok => code_buffer.items,
1150 .fail => |em| {
1151 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
1152 return;
1153 },
1154 };
11551148
1156 try coff.updateNavCode(pt, nav_index, code, .FUNCTION);
1149 try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);
11571150
11581151 // Exports will be updated by `Zcu.processExports` after the update.
11591152}
......@@ -1182,16 +1175,13 @@ fn lowerConst(
11821175 try coff.setSymbolName(sym, name);
11831176 sym.section_number = @as(coff_util.SectionNumber, @enumFromInt(sect_id + 1));
11841177
1185 const res = try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{
1178 try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{
11861179 .atom_index = coff.getAtom(atom_index).getSymbolIndex().?,
11871180 });
1188 const code = switch (res) {
1189 .ok => code_buffer.items,
1190 .fail => |em| return .{ .fail = em },
1191 };
1181 const code = code_buffer.items;
11921182
11931183 const atom = coff.getAtomPtr(atom_index);
1194 atom.size = @as(u32, @intCast(code.len));
1184 atom.size = @intCast(code.len);
11951185 atom.getSymbolPtr(coff).value = try coff.allocateAtom(
11961186 atom_index,
11971187 atom.size,
......@@ -1250,7 +1240,7 @@ pub fn updateNav(
12501240 var code_buffer = std.ArrayList(u8).init(gpa);
12511241 defer code_buffer.deinit();
12521242
1253 const res = try codegen.generateSymbol(
1243 try codegen.generateSymbol(
12541244 &coff.base,
12551245 pt,
12561246 zcu.navSrcLoc(nav_index),
......@@ -1258,15 +1248,8 @@ pub fn updateNav(
12581248 &code_buffer,
12591249 .{ .atom_index = atom.getSymbolIndex().? },
12601250 );
1261 const code = switch (res) {
1262 .ok => code_buffer.items,
1263 .fail => |em| {
1264 try zcu.failed_codegen.put(gpa, nav_index, em);
1265 return;
1266 },
1267 };
12681251
1269 try coff.updateNavCode(pt, nav_index, code, .NULL);
1252 try coff.updateNavCode(pt, nav_index, code_buffer.items, .NULL);
12701253 }
12711254
12721255 // Exports will be updated by `Zcu.processExports` after the update.
......@@ -1278,11 +1261,10 @@ fn updateLazySymbolAtom(
12781261 sym: link.File.LazySymbol,
12791262 atom_index: Atom.Index,
12801263 section_index: u16,
1281) link.File.FlushError!void {
1264) !void {
12821265 const zcu = pt.zcu;
12831266 const comp = coff.base.comp;
12841267 const gpa = comp.gpa;
1285 const diags = &comp.link_diags;
12861268
12871269 var required_alignment: InternPool.Alignment = .none;
12881270 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1298,7 +1280,7 @@ fn updateLazySymbolAtom(
12981280 const local_sym_index = atom.getSymbolIndex().?;
12991281
13001282 const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1301 const res = codegen.generateLazySymbol(
1283 try codegen.generateLazySymbol(
13021284 &coff.base,
13031285 pt,
13041286 src,
......@@ -1307,14 +1289,8 @@ fn updateLazySymbolAtom(
13071289 &code_buffer,
13081290 .none,
13091291 .{ .atom_index = local_sym_index },
1310 ) catch |err| switch (err) {
1311 error.CodegenFail => return error.LinkFailure,
1312 else => |e| return diags.fail("failed to generate lazy symbol: {s}", .{@errorName(e)}),
1313 };
1314 const code = switch (res) {
1315 .ok => code_buffer.items,
1316 .fail => |em| return diags.fail("failed to generate code: {s}", .{em.msg}),
1317 };
1292 );
1293 const code = code_buffer.items;
13181294
13191295 const code_len: u32 = @intCast(code.len);
13201296 const symbol = atom.getSymbolPtr(coff);
......@@ -1438,7 +1414,10 @@ fn updateNavCode(
14381414 const capacity = atom.capacity(coff);
14391415 const need_realloc = code.len > capacity or !required_alignment.check(sym.value);
14401416 if (need_realloc) {
1441 const vaddr = try coff.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
1417 const vaddr = coff.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)) catch |err| switch (err) {
1418 error.OutOfMemory => return error.OutOfMemory,
1419 else => |e| return coff.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(e)}),
1420 };
14421421 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
14431422 log.debug(" (required alignment 0x{x}", .{required_alignment});
14441423
......@@ -1446,7 +1425,10 @@ fn updateNavCode(
14461425 sym.value = vaddr;
14471426 log.debug(" (updating GOT entry)", .{});
14481427 const got_entry_index = coff.got_table.lookup.get(.{ .sym_index = sym_index }).?;
1449 try coff.writeOffsetTableEntry(got_entry_index);
1428 coff.writeOffsetTableEntry(got_entry_index) catch |err| switch (err) {
1429 error.OutOfMemory => return error.OutOfMemory,
1430 else => |e| return coff.base.cgFail(nav_index, "failed to write offset table entry: {s}", .{@errorName(e)}),
1431 };
14501432 coff.markRelocsDirtyByTarget(.{ .sym_index = sym_index });
14511433 }
14521434 } else if (code_len < atom.size) {
......@@ -1459,16 +1441,25 @@ fn updateNavCode(
14591441 sym.section_number = @enumFromInt(sect_index + 1);
14601442 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14611443
1462 const vaddr = try coff.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
1444 const vaddr = coff.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)) catch |err| switch (err) {
1445 error.OutOfMemory => return error.OutOfMemory,
1446 else => |e| return coff.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(e)}),
1447 };
14631448 errdefer coff.freeAtom(atom_index);
14641449 log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });
14651450 coff.getAtomPtr(atom_index).size = code_len;
14661451 sym.value = vaddr;
14671452
1468 try coff.addGotEntry(.{ .sym_index = sym_index });
1453 coff.addGotEntry(.{ .sym_index = sym_index }) catch |err| switch (err) {
1454 error.OutOfMemory => return error.OutOfMemory,
1455 else => |e| return coff.base.cgFail(nav_index, "failed to add GOT entry: {s}", .{@errorName(e)}),
1456 };
14691457 }
14701458
1471 try coff.writeAtom(atom_index, code);
1459 coff.writeAtom(atom_index, code) catch |err| switch (err) {
1460 error.OutOfMemory => return error.OutOfMemory,
1461 else => |e| return coff.base.cgFail(nav_index, "failed to write atom: {s}", .{@errorName(e)}),
1462 };
14721463}
14731464
14741465pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void {
......@@ -2229,12 +2220,16 @@ fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Director
22292220 return null;
22302221}
22312222
2232pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
2223pub fn flushModule(
2224 coff: *Coff,
2225 arena: Allocator,
2226 tid: Zcu.PerThread.Id,
2227 prog_node: std.Progress.Node,
2228) link.File.FlushError!void {
22332229 const tracy = trace(@src());
22342230 defer tracy.end();
22352231
22362232 const comp = coff.base.comp;
2237 const gpa = comp.gpa;
22382233 const diags = &comp.link_diags;
22392234
22402235 if (coff.llvm_object) |llvm_object| {
......@@ -2245,6 +2240,20 @@ pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
22452240 const sub_prog_node = prog_node.start("COFF Flush", 0);
22462241 defer sub_prog_node.end();
22472242
2243 return flushModuleInner(coff, arena, tid) catch |err| switch (err) {
2244 error.OutOfMemory => return error.OutOfMemory,
2245 error.LinkFailure => return error.LinkFailure,
2246 else => |e| return diags.fail("COFF flush failed: {s}", .{@errorName(e)}),
2247 };
2248}
2249
2250fn flushModuleInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void {
2251 _ = arena;
2252
2253 const comp = coff.base.comp;
2254 const gpa = comp.gpa;
2255 const diags = &comp.link_diags;
2256
22482257 const pt: Zcu.PerThread = .activate(
22492258 comp.zcu orelse return diags.fail("linking without zig source is not yet implemented", .{}),
22502259 tid,
......@@ -2757,7 +2766,7 @@ fn writeImportTables(coff: *Coff) !void {
27572766 coff.imports_count_dirty = false;
27582767}
27592768
2760fn writeStrtab(coff: *Coff) link.File.FlushError!void {
2769fn writeStrtab(coff: *Coff) !void {
27612770 if (coff.strtab_offset == null) return;
27622771
27632772 const comp = coff.base.comp;
src/link/Dwarf.zig+3-9
......@@ -21,7 +21,6 @@ debug_rnglists: DebugRngLists,
2121debug_str: StringSection,
2222
2323pub const UpdateError = error{
24 CodegenFail,
2524 ReinterpretDeclRef,
2625 Unimplemented,
2726 OutOfMemory,
......@@ -1893,17 +1892,15 @@ pub const WipNav = struct {
18931892 if (bytes == 0) return;
18941893 var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa);
18951894 defer wip_nav.debug_info = dim.moveToUnmanaged();
1896 switch (try codegen.generateSymbol(
1895 try codegen.generateSymbol(
18971896 wip_nav.dwarf.bin_file,
18981897 wip_nav.pt,
18991898 src_loc,
19001899 val,
19011900 &dim,
19021901 .{ .debug_output = .{ .dwarf = wip_nav } },
1903 )) {
1904 .ok => assert(dim.items.len == wip_nav.debug_info.items.len + bytes),
1905 .fail => unreachable,
1906 }
1902 );
1903 assert(dim.items.len == wip_nav.debug_info.items.len + bytes);
19071904 }
19081905
19091906 const AbbrevCodeForForm = struct {
......@@ -2346,7 +2343,6 @@ pub fn initWipNav(
23462343) error{ OutOfMemory, CodegenFail }!?WipNav {
23472344 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
23482345 error.OutOfMemory => return error.OutOfMemory,
2349 error.CodegenFail => return error.CodegenFail,
23502346 else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
23512347 };
23522348}
......@@ -2669,7 +2665,6 @@ pub fn finishWipNav(
26692665) error{ OutOfMemory, CodegenFail }!void {
26702666 return finishWipNavInner(dwarf, pt, nav_index, wip_nav) catch |err| switch (err) {
26712667 error.OutOfMemory => return error.OutOfMemory,
2672 error.CodegenFail => return error.CodegenFail,
26732668 else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf: {s}", .{@errorName(e)}),
26742669 };
26752670}
......@@ -2701,7 +2696,6 @@ fn finishWipNavInner(
27012696pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {
27022697 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
27032698 error.OutOfMemory => return error.OutOfMemory,
2704 error.CodegenFail => return error.CodegenFail,
27052699 else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
27062700 };
27072701}
src/link/Elf.zig+15-2
......@@ -2368,12 +2368,25 @@ pub fn updateContainerType(
23682368 self: *Elf,
23692369 pt: Zcu.PerThread,
23702370 ty: InternPool.Index,
2371) link.File.UpdateNavError!void {
2371) link.File.UpdateContainerTypeError!void {
23722372 if (build_options.skip_non_native and builtin.object_format != .elf) {
23732373 @panic("Attempted to compile for object format that was disabled by build configuration");
23742374 }
23752375 if (self.llvm_object) |_| return;
2376 return self.zigObjectPtr().?.updateContainerType(pt, ty);
2376 const zcu = pt.zcu;
2377 const gpa = zcu.gpa;
2378 return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) {
2379 error.OutOfMemory => return error.OutOfMemory,
2380 else => |e| {
2381 try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create(
2382 gpa,
2383 zcu.typeSrcLoc(ty),
2384 "failed to update container type: {s}",
2385 .{@errorName(e)},
2386 ));
2387 return error.TypeFailureReported;
2388 },
2389 };
23772390}
23782391
23792392pub fn updateExports(
src/link/Elf/ZigObject.zig+9-32
......@@ -1437,7 +1437,7 @@ pub fn updateFunc(
14371437 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
14381438 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
14391439
1440 const res = try codegen.generateFunction(
1440 try codegen.generateFunction(
14411441 &elf_file.base,
14421442 pt,
14431443 zcu.navSrcLoc(func.owner_nav),
......@@ -1447,14 +1447,7 @@ pub fn updateFunc(
14471447 &code_buffer,
14481448 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
14491449 );
1450
1451 const code = switch (res) {
1452 .ok => code_buffer.items,
1453 .fail => |em| {
1454 try zcu.failed_codegen.put(gpa, func.owner_nav, em);
1455 return;
1456 },
1457 };
1450 const code = code_buffer.items;
14581451
14591452 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
14601453 log.debug("setting shdr({x},{s}) for {}", .{
......@@ -1574,7 +1567,7 @@ pub fn updateNav(
15741567 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
15751568 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
15761569
1577 const res = try codegen.generateSymbol(
1570 try codegen.generateSymbol(
15781571 &elf_file.base,
15791572 pt,
15801573 zcu.navSrcLoc(nav_index),
......@@ -1582,14 +1575,7 @@ pub fn updateNav(
15821575 &code_buffer,
15831576 .{ .atom_index = sym_index },
15841577 );
1585
1586 const code = switch (res) {
1587 .ok => code_buffer.items,
1588 .fail => |em| {
1589 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
1590 return;
1591 },
1592 };
1578 const code = code_buffer.items;
15931579
15941580 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
15951581 log.debug("setting shdr({x},{s}) for {}", .{
......@@ -1612,7 +1598,7 @@ pub fn updateContainerType(
16121598 self: *ZigObject,
16131599 pt: Zcu.PerThread,
16141600 ty: InternPool.Index,
1615) link.File.UpdateNavError!void {
1601) !void {
16161602 const tracy = trace(@src());
16171603 defer tracy.end();
16181604
......@@ -1643,7 +1629,7 @@ fn updateLazySymbol(
16431629 };
16441630
16451631 const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1646 const res = try codegen.generateLazySymbol(
1632 try codegen.generateLazySymbol(
16471633 &elf_file.base,
16481634 pt,
16491635 src,
......@@ -1653,13 +1639,7 @@ fn updateLazySymbol(
16531639 .none,
16541640 .{ .atom_index = symbol_index },
16551641 );
1656 const code = switch (res) {
1657 .ok => code_buffer.items,
1658 .fail => |em| {
1659 log.err("{s}", .{em.msg});
1660 return error.CodegenFail;
1661 },
1662 };
1642 const code = code_buffer.items;
16631643
16641644 const output_section_index = switch (sym.kind) {
16651645 .code => if (self.text_index) |sym_index|
......@@ -1732,7 +1712,7 @@ fn lowerConst(
17321712 const name_off = try self.addString(gpa, name);
17331713 const sym_index = try self.newSymbolWithAtom(gpa, name_off);
17341714
1735 const res = try codegen.generateSymbol(
1715 try codegen.generateSymbol(
17361716 &elf_file.base,
17371717 pt,
17381718 src_loc,
......@@ -1740,10 +1720,7 @@ fn lowerConst(
17401720 &code_buffer,
17411721 .{ .atom_index = sym_index },
17421722 );
1743 const code = switch (res) {
1744 .ok => code_buffer.items,
1745 .fail => |em| return .{ .fail = em },
1746 };
1723 const code = code_buffer.items;
17471724
17481725 const local_sym = self.symbol(sym_index);
17491726 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];
src/link/MachO/ZigObject.zig+9-34
......@@ -590,7 +590,6 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
590590 defer pt.deactivate();
591591 dwarf.flushModule(pt) catch |err| switch (err) {
592592 error.OutOfMemory => return error.OutOfMemory,
593 error.CodegenFail => return error.LinkFailure,
594593 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),
595594 };
596595
......@@ -796,7 +795,7 @@ pub fn updateFunc(
796795 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
797796 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
798797
799 const res = try codegen.generateFunction(
798 try codegen.generateFunction(
800799 &macho_file.base,
801800 pt,
802801 zcu.navSrcLoc(func.owner_nav),
......@@ -806,14 +805,7 @@ pub fn updateFunc(
806805 &code_buffer,
807806 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
808807 );
809
810 const code = switch (res) {
811 .ok => code_buffer.items,
812 .fail => |em| {
813 try zcu.failed_codegen.put(gpa, func.owner_nav, em);
814 return error.CodegenFail;
815 },
816 };
808 const code = code_buffer.items;
817809
818810 const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);
819811 const old_rva, const old_alignment = blk: {
......@@ -914,7 +906,7 @@ pub fn updateNav(
914906 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
915907 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
916908
917 const res = try codegen.generateSymbol(
909 try codegen.generateSymbol(
918910 &macho_file.base,
919911 pt,
920912 zcu.navSrcLoc(nav_index),
......@@ -922,14 +914,8 @@ pub fn updateNav(
922914 &code_buffer,
923915 .{ .atom_index = sym_index },
924916 );
917 const code = code_buffer.items;
925918
926 const code = switch (res) {
927 .ok => code_buffer.items,
928 .fail => |em| {
929 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
930 return;
931 },
932 };
933919 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
934920 if (isThreadlocal(macho_file, nav_index))
935921 try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)
......@@ -1221,7 +1207,7 @@ fn lowerConst(
12211207 const name_str = try self.addString(gpa, name);
12221208 const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
12231209
1224 const res = try codegen.generateSymbol(
1210 try codegen.generateSymbol(
12251211 &macho_file.base,
12261212 pt,
12271213 src_loc,
......@@ -1229,10 +1215,7 @@ fn lowerConst(
12291215 &code_buffer,
12301216 .{ .atom_index = sym_index },
12311217 );
1232 const code = switch (res) {
1233 .ok => code_buffer.items,
1234 .fail => |em| return .{ .fail = em },
1235 };
1218 const code = code_buffer.items;
12361219
12371220 const sym = &self.symbols.items[sym_index];
12381221 sym.out_n_sect = output_section_index;
......@@ -1367,7 +1350,6 @@ fn updateLazySymbol(
13671350) !void {
13681351 const zcu = pt.zcu;
13691352 const gpa = zcu.gpa;
1370 const diags = &macho_file.base.comp.link_diags;
13711353
13721354 var required_alignment: Atom.Alignment = .none;
13731355 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1383,7 +1365,7 @@ fn updateLazySymbol(
13831365 };
13841366
13851367 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1386 const res = codegen.generateLazySymbol(
1368 try codegen.generateLazySymbol(
13871369 &macho_file.base,
13881370 pt,
13891371 src,
......@@ -1392,15 +1374,8 @@ fn updateLazySymbol(
13921374 &code_buffer,
13931375 .none,
13941376 .{ .atom_index = symbol_index },
1395 ) catch |err| switch (err) {
1396 error.CodegenFail => return error.LinkFailure,
1397 error.OutOfMemory => return error.OutOfMemory,
1398 else => |e| return diags.fail("failed to codegen symbol: {s}", .{@errorName(e)}),
1399 };
1400 const code = switch (res) {
1401 .ok => code_buffer.items,
1402 .fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}),
1403 };
1377 );
1378 const code = code_buffer.items;
14041379
14051380 const output_section_index = switch (lazy_sym.kind) {
14061381 .code => macho_file.zig_text_sect_index.?,
src/link/Plan9.zig+6-15
......@@ -465,7 +465,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
465465 var code_buffer = std.ArrayList(u8).init(gpa);
466466 defer code_buffer.deinit();
467467 // TODO we need the symbol index for symbol in the table of locals for the containing atom
468 const res = try codegen.generateSymbol(
468 try codegen.generateSymbol(
469469 &self.base,
470470 pt,
471471 zcu.navSrcLoc(nav_index),
......@@ -473,10 +473,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
473473 &code_buffer,
474474 .{ .atom_index = @intCast(atom_idx) },
475475 );
476 const code = switch (res) {
477 .ok => code_buffer.items,
478 .fail => |em| return zcu.failed_codegen.put(gpa, nav_index, em),
479 };
476 const code = code_buffer.items;
480477 try self.data_nav_table.ensureUnusedCapacity(gpa, 1);
481478 const duped_code = try gpa.dupe(u8, code);
482479 self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } };
......@@ -1081,7 +1078,7 @@ fn updateLazySymbolAtom(
10811078
10821079 // generate the code
10831080 const src = Type.fromInterned(sym.ty).srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;
1084 const res = codegen.generateLazySymbol(
1081 codegen.generateLazySymbol(
10851082 &self.base,
10861083 pt,
10871084 src,
......@@ -1095,10 +1092,7 @@ fn updateLazySymbolAtom(
10951092 error.CodegenFail => return error.LinkFailure,
10961093 error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}),
10971094 };
1098 const code = switch (res) {
1099 .ok => code_buffer.items,
1100 .fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}),
1101 };
1095 const code = code_buffer.items;
11021096 // duped_code is freed when the atom is freed
11031097 const duped_code = try gpa.dupe(u8, code);
11041098 errdefer gpa.free(duped_code);
......@@ -1408,11 +1402,8 @@ pub fn lowerUav(
14081402 gop.value_ptr.* = index;
14091403 // we need to free name latex
14101404 var code_buffer = std.ArrayList(u8).init(gpa);
1411 const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
1412 const code = switch (res) {
1413 .ok => code_buffer.items,
1414 .fail => |em| return .{ .fail = em },
1415 };
1405 try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
1406 const code = code_buffer.items;
14161407 const atom_ptr = self.getAtomPtr(index);
14171408 atom_ptr.* = .{
14181409 .type = .d,