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 {...@@ -4072,15 +4072,53 @@ pub fn navValIsConst(zcu: *const Zcu, val: InternPool.Index) bool {
4072 };4072 };
4073}4073}
40744074
4075pub const CodegenFailError = error{
4076 /// Indicates the error message has been already stored at `Zcu.failed_codegen`.
4077 CodegenFail,
4078 OutOfMemory,
4079};
4080
4075pub fn codegenFail(4081pub fn codegenFail(
4076 zcu: *Zcu,4082 zcu: *Zcu,
4077 nav_index: InternPool.Nav.Index,4083 nav_index: InternPool.Nav.Index,
4078 comptime format: []const u8,4084 comptime format: []const u8,
4079 args: anytype,4085 args: anytype,
4080) error{ CodegenFail, OutOfMemory } {4086) CodegenFailError {
4081 const gpa = zcu.gpa;4087 const gpa = zcu.gpa;
4082 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);4088 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
4083 const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args);4089 const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args);
4084 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg);4090 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg);
4085 return error.CodegenFail;4091 return error.CodegenFail;
4086}4092}
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...@@ -1726,7 +1726,6 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
1726 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {1726 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
1727 error.OutOfMemory => return error.OutOfMemory,1727 error.OutOfMemory => return error.OutOfMemory,
1728 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),1728 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
1729 error.LinkFailure => assert(comp.link_diags.hasErrors()),
1730 error.Overflow => {1729 error.Overflow => {
1731 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(1730 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
1732 gpa,1731 gpa,
...@@ -3112,7 +3111,6 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error...@@ -3112,7 +3111,6 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error
3112 lf.updateNav(pt, nav_index) catch |err| switch (err) {3111 lf.updateNav(pt, nav_index) catch |err| switch (err) {
3113 error.OutOfMemory => return error.OutOfMemory,3112 error.OutOfMemory => return error.OutOfMemory,
3114 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),3113 error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
3115 error.LinkFailure => assert(comp.link_diags.hasErrors()),
3116 error.Overflow => {3114 error.Overflow => {
3117 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(3115 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
3118 gpa,3116 gpa,
...@@ -3139,7 +3137,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{...@@ -3139,7 +3137,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{
3139 const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);3137 const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
3140 defer codegen_prog_node.end();3138 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
3144 if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {3142 if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {
3145 // This type failed to resolve. This is a transitive failure.3143 // This type failed to resolve. This is a transitive failure.
...@@ -3148,12 +3146,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{...@@ -3148,12 +3146,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{
31483146
3149 if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) {3147 if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) {
3150 error.OutOfMemory => return error.OutOfMemory,3148 error.OutOfMemory => return error.OutOfMemory,
3151 else => |e| try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create(3149 error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),
3152 gpa,
3153 zcu.typeSrcLoc(ty),
3154 "failed to update container type: {s}",
3155 .{@errorName(e)},
3156 )),
3157 };3150 };
3158}3151}
31593152
src/arch/aarch64/CodeGen.zig+16-36
...@@ -24,7 +24,6 @@ const build_options = @import("build_options");...@@ -24,7 +24,6 @@ const build_options = @import("build_options");
24const Alignment = InternPool.Alignment;24const Alignment = InternPool.Alignment;
2525
26const CodeGenError = codegen.CodeGenError;26const CodeGenError = codegen.CodeGenError;
27const Result = codegen.Result;
2827
29const bits = @import("bits.zig");28const bits = @import("bits.zig");
30const abi = @import("abi.zig");29const abi = @import("abi.zig");
...@@ -51,7 +50,6 @@ debug_output: link.File.DebugInfoOutput,...@@ -51,7 +50,6 @@ debug_output: link.File.DebugInfoOutput,
51target: *const std.Target,50target: *const std.Target,
52func_index: InternPool.Index,51func_index: InternPool.Index,
53owner_nav: InternPool.Nav.Index,52owner_nav: InternPool.Nav.Index,
54err_msg: ?*ErrorMsg,
55args: []MCValue,53args: []MCValue,
56ret_mcv: MCValue,54ret_mcv: MCValue,
57fn_type: Type,55fn_type: Type,
...@@ -167,7 +165,7 @@ const DbgInfoReloc = struct {...@@ -167,7 +165,7 @@ const DbgInfoReloc = struct {
167 name: [:0]const u8,165 name: [:0]const u8,
168 mcv: MCValue,166 mcv: MCValue,
169167
170 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {168 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
171 switch (reloc.tag) {169 switch (reloc.tag) {
172 .arg,170 .arg,
173 .dbg_arg_inline,171 .dbg_arg_inline,
...@@ -181,7 +179,7 @@ const DbgInfoReloc = struct {...@@ -181,7 +179,7 @@ const DbgInfoReloc = struct {
181 }179 }
182 }180 }
183181
184 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {182 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
185 switch (function.debug_output) {183 switch (function.debug_output) {
186 .dwarf => |dw| {184 .dwarf => |dw| {
187 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {185 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -209,7 +207,7 @@ const DbgInfoReloc = struct {...@@ -209,7 +207,7 @@ const DbgInfoReloc = struct {
209 }207 }
210 }208 }
211209
212 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {210 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
213 switch (function.debug_output) {211 switch (function.debug_output) {
214 .dwarf => |dwarf| {212 .dwarf => |dwarf| {
215 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {213 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -327,7 +325,7 @@ pub fn generate(...@@ -327,7 +325,7 @@ pub fn generate(
327 liveness: Liveness,325 liveness: Liveness,
328 code: *std.ArrayList(u8),326 code: *std.ArrayList(u8),
329 debug_output: link.File.DebugInfoOutput,327 debug_output: link.File.DebugInfoOutput,
330) CodeGenError!Result {328) CodeGenError!void {
331 const zcu = pt.zcu;329 const zcu = pt.zcu;
332 const gpa = zcu.gpa;330 const gpa = zcu.gpa;
333 const func = zcu.funcInfo(func_index);331 const func = zcu.funcInfo(func_index);
...@@ -353,7 +351,6 @@ pub fn generate(...@@ -353,7 +351,6 @@ pub fn generate(
353 .bin_file = lf,351 .bin_file = lf,
354 .func_index = func_index,352 .func_index = func_index,
355 .owner_nav = func.owner_nav,353 .owner_nav = func.owner_nav,
356 .err_msg = null,
357 .args = undefined, // populated after `resolveCallingConventionValues`354 .args = undefined, // populated after `resolveCallingConventionValues`
358 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`355 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
359 .fn_type = fn_type,356 .fn_type = fn_type,
...@@ -370,10 +367,7 @@ pub fn generate(...@@ -370,10 +367,7 @@ pub fn generate(
370 defer function.dbg_info_relocs.deinit(gpa);367 defer function.dbg_info_relocs.deinit(gpa);
371368
372 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {369 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
373 error.CodegenFail => return Result{ .fail = function.err_msg.? },370 error.CodegenFail => return error.CodegenFail,
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 },
377 else => |e| return e,371 else => |e| return e,
378 };372 };
379 defer call_info.deinit(&function);373 defer call_info.deinit(&function);
...@@ -384,15 +378,14 @@ pub fn generate(...@@ -384,15 +378,14 @@ pub fn generate(
384 function.max_end_stack = call_info.stack_byte_count;378 function.max_end_stack = call_info.stack_byte_count;
385379
386 function.gen() catch |err| switch (err) {380 function.gen() catch |err| switch (err) {
387 error.CodegenFail => return Result{ .fail = function.err_msg.? },381 error.CodegenFail => return error.CodegenFail,
388 error.OutOfRegisters => return Result{382 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
389 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
390 },
391 else => |e| return e,383 else => |e| return e,
392 };384 };
393385
394 for (function.dbg_info_relocs.items) |reloc| {386 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)});
396 }389 }
397390
398 var mir: Mir = .{391 var mir: Mir = .{
...@@ -417,15 +410,9 @@ pub fn generate(...@@ -417,15 +410,9 @@ pub fn generate(
417 defer emit.deinit();410 defer emit.deinit();
418411
419 emit.emitMir() catch |err| switch (err) {412 emit.emitMir() catch |err| switch (err) {
420 error.EmitFail => return Result{ .fail = emit.err_msg.? },413 error.EmitFail => return function.failMsg(emit.err_msg.?),
421 else => |e| return e,414 else => |e| return e,
422 };415 };
423
424 if (function.err_msg) |em| {
425 return Result{ .fail = em };
426 } else {
427 return Result.ok;
428 }
429}416}
430417
431fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {418fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
...@@ -567,7 +554,7 @@ fn gen(self: *Self) !void {...@@ -567,7 +554,7 @@ fn gen(self: *Self) !void {
567 .data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } },554 .data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } },
568 });555 });
569 } else {556 } else {
570 return self.failSymbol("TODO AArch64: allow larger stacks", .{});557 @panic("TODO AArch64: allow larger stacks");
571 }558 }
572559
573 _ = try self.addInst(.{560 _ = try self.addInst(.{
...@@ -6191,10 +6178,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {...@@ -6191,10 +6178,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
6191 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },6178 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
6192 .load_symbol, .load_tlv, .lea_symbol, .lea_direct => unreachable, // TODO6179 .load_symbol, .load_tlv, .lea_symbol, .lea_direct => unreachable, // TODO
6193 },6180 },
6194 .fail => |msg| {6181 .fail => |msg| return self.failMsg(msg),
6195 self.err_msg = msg;
6196 return error.CodegenFail;
6197 },
6198 };6182 };
6199 return mcv;6183 return mcv;
6200}6184}
...@@ -6355,18 +6339,14 @@ fn wantSafety(self: *Self) bool {...@@ -6355,18 +6339,14 @@ fn wantSafety(self: *Self) bool {
6355 };6339 };
6356}6340}
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 } {
6359 @branchHint(.cold);6343 @branchHint(.cold);
6360 assert(self.err_msg == null);6344 return self.pt.zcu.codegenFail(self.owner_nav, format, args);
6361 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
6362 return error.CodegenFail;
6363}6345}
63646346
6365fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {6347fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
6366 @branchHint(.cold);6348 @branchHint(.cold);
6367 assert(self.err_msg == null);6349 return self.pt.zcu.codegenFailMsg(self.owner_nav, msg);
6368 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
6369 return error.CodegenFail;
6370}6350}
63716351
6372fn parseRegName(name: []const u8) ?Register {6352fn parseRegName(name: []const u8) ?Register {
src/arch/arm/CodeGen.zig+19-31
...@@ -23,7 +23,6 @@ const log = std.log.scoped(.codegen);...@@ -23,7 +23,6 @@ const log = std.log.scoped(.codegen);
23const build_options = @import("build_options");23const build_options = @import("build_options");
24const Alignment = InternPool.Alignment;24const Alignment = InternPool.Alignment;
2525
26const Result = codegen.Result;
27const CodeGenError = codegen.CodeGenError;26const CodeGenError = codegen.CodeGenError;
2827
29const bits = @import("bits.zig");28const bits = @import("bits.zig");
...@@ -245,7 +244,7 @@ const DbgInfoReloc = struct {...@@ -245,7 +244,7 @@ const DbgInfoReloc = struct {
245 name: [:0]const u8,244 name: [:0]const u8,
246 mcv: MCValue,245 mcv: MCValue,
247246
248 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {247 fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
249 switch (reloc.tag) {248 switch (reloc.tag) {
250 .arg,249 .arg,
251 .dbg_arg_inline,250 .dbg_arg_inline,
...@@ -259,7 +258,7 @@ const DbgInfoReloc = struct {...@@ -259,7 +258,7 @@ const DbgInfoReloc = struct {
259 }258 }
260 }259 }
261260
262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {261 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
263 switch (function.debug_output) {262 switch (function.debug_output) {
264 .dwarf => |dw| {263 .dwarf => |dw| {
265 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {264 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -287,7 +286,7 @@ const DbgInfoReloc = struct {...@@ -287,7 +286,7 @@ const DbgInfoReloc = struct {
287 }286 }
288 }287 }
289288
290 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {289 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
291 switch (function.debug_output) {290 switch (function.debug_output) {
292 .dwarf => |dw| {291 .dwarf => |dw| {
293 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {292 const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
...@@ -335,7 +334,7 @@ pub fn generate(...@@ -335,7 +334,7 @@ pub fn generate(
335 liveness: Liveness,334 liveness: Liveness,
336 code: *std.ArrayList(u8),335 code: *std.ArrayList(u8),
337 debug_output: link.File.DebugInfoOutput,336 debug_output: link.File.DebugInfoOutput,
338) CodeGenError!Result {337) CodeGenError!void {
339 const zcu = pt.zcu;338 const zcu = pt.zcu;
340 const gpa = zcu.gpa;339 const gpa = zcu.gpa;
341 const func = zcu.funcInfo(func_index);340 const func = zcu.funcInfo(func_index);
...@@ -377,10 +376,7 @@ pub fn generate(...@@ -377,10 +376,7 @@ pub fn generate(
377 defer function.dbg_info_relocs.deinit(gpa);376 defer function.dbg_info_relocs.deinit(gpa);
378377
379 var call_info = function.resolveCallingConventionValues(func_ty) catch |err| switch (err) {378 var call_info = function.resolveCallingConventionValues(func_ty) catch |err| switch (err) {
380 error.CodegenFail => return Result{ .fail = function.err_msg.? },379 error.CodegenFail => return error.CodegenFail,
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 },
384 else => |e| return e,380 else => |e| return e,
385 };381 };
386 defer call_info.deinit(&function);382 defer call_info.deinit(&function);
...@@ -391,15 +387,14 @@ pub fn generate(...@@ -391,15 +387,14 @@ pub fn generate(
391 function.max_end_stack = call_info.stack_byte_count;387 function.max_end_stack = call_info.stack_byte_count;
392388
393 function.gen() catch |err| switch (err) {389 function.gen() catch |err| switch (err) {
394 error.CodegenFail => return Result{ .fail = function.err_msg.? },390 error.CodegenFail => return error.CodegenFail,
395 error.OutOfRegisters => return Result{391 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
396 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
397 },
398 else => |e| return e,392 else => |e| return e,
399 };393 };
400394
401 for (function.dbg_info_relocs.items) |reloc| {395 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)});
403 }398 }
404399
405 var mir = Mir{400 var mir = Mir{
...@@ -424,15 +419,9 @@ pub fn generate(...@@ -424,15 +419,9 @@ pub fn generate(
424 defer emit.deinit();419 defer emit.deinit();
425420
426 emit.emitMir() catch |err| switch (err) {421 emit.emitMir() catch |err| switch (err) {
427 error.EmitFail => return Result{ .fail = emit.err_msg.? },422 error.EmitFail => return function.failMsg(emit.err_msg.?),
428 else => |e| return e,423 else => |e| return e,
429 };424 };
430
431 if (function.err_msg) |em| {
432 return Result{ .fail = em };
433 } else {
434 return Result.ok;
435 }
436}425}
437426
438fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {427fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
...@@ -6310,20 +6299,19 @@ fn wantSafety(self: *Self) bool {...@@ -6310,20 +6299,19 @@ fn wantSafety(self: *Self) bool {
6310 };6299 };
6311}6300}
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 } {
6314 @branchHint(.cold);6303 @branchHint(.cold);
6315 assert(self.err_msg == null);6304 const zcu = self.pt.zcu;
6316 const gpa = self.gpa;6305 const func = zcu.funcInfo(self.func_index);
6317 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);6306 const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
6318 return error.CodegenFail;6307 return zcu.codegenFailMsg(func.owner_nav, msg);
6319}6308}
63206309
6321fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {6310fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
6322 @branchHint(.cold);6311 @branchHint(.cold);
6323 assert(self.err_msg == null);6312 const zcu = self.pt.zcu;
6324 const gpa = self.gpa;6313 const func = zcu.funcInfo(self.func_index);
6325 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);6314 return zcu.codegenFailMsg(func.owner_nav, msg);
6326 return error.CodegenFail;
6327}6315}
63286316
6329fn parseRegName(name: []const u8) ?Register {6317fn 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);...@@ -32,7 +32,6 @@ const wip_mir_log = std.log.scoped(.wip_mir);
32const Alignment = InternPool.Alignment;32const Alignment = InternPool.Alignment;
3333
34const CodeGenError = codegen.CodeGenError;34const CodeGenError = codegen.CodeGenError;
35const Result = codegen.Result;
3635
37const bits = @import("bits.zig");36const bits = @import("bits.zig");
38const abi = @import("abi.zig");37const abi = @import("abi.zig");
...@@ -62,7 +61,6 @@ gpa: Allocator,...@@ -62,7 +61,6 @@ gpa: Allocator,
62mod: *Package.Module,61mod: *Package.Module,
63target: *const std.Target,62target: *const std.Target,
64debug_output: link.File.DebugInfoOutput,63debug_output: link.File.DebugInfoOutput,
65err_msg: ?*ErrorMsg,
66args: []MCValue,64args: []MCValue,
67ret_mcv: InstTracking,65ret_mcv: InstTracking,
68fn_type: Type,66fn_type: Type,
...@@ -761,7 +759,7 @@ pub fn generate(...@@ -761,7 +759,7 @@ pub fn generate(
761 liveness: Liveness,759 liveness: Liveness,
762 code: *std.ArrayList(u8),760 code: *std.ArrayList(u8),
763 debug_output: link.File.DebugInfoOutput,761 debug_output: link.File.DebugInfoOutput,
764) CodeGenError!Result {762) CodeGenError!void {
765 const zcu = pt.zcu;763 const zcu = pt.zcu;
766 const comp = zcu.comp;764 const comp = zcu.comp;
767 const gpa = zcu.gpa;765 const gpa = zcu.gpa;
...@@ -788,7 +786,6 @@ pub fn generate(...@@ -788,7 +786,6 @@ pub fn generate(
788 .target = &mod.resolved_target.result,786 .target = &mod.resolved_target.result,
789 .debug_output = debug_output,787 .debug_output = debug_output,
790 .owner = .{ .nav_index = func.owner_nav },788 .owner = .{ .nav_index = func.owner_nav },
791 .err_msg = null,
792 .args = undefined, // populated after `resolveCallingConventionValues`789 .args = undefined, // populated after `resolveCallingConventionValues`
793 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`790 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
794 .fn_type = fn_type,791 .fn_type = fn_type,
...@@ -829,10 +826,7 @@ pub fn generate(...@@ -829,10 +826,7 @@ pub fn generate(
829826
830 const fn_info = zcu.typeToFunc(fn_type).?;827 const fn_info = zcu.typeToFunc(fn_type).?;
831 var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) {828 var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) {
832 error.CodegenFail => return Result{ .fail = function.err_msg.? },829 error.CodegenFail => return error.CodegenFail,
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 },
836 else => |e| return e,830 else => |e| return e,
837 };831 };
838832
...@@ -861,10 +855,8 @@ pub fn generate(...@@ -861,10 +855,8 @@ pub fn generate(
861 }));855 }));
862856
863 function.gen() catch |err| switch (err) {857 function.gen() catch |err| switch (err) {
864 error.CodegenFail => return Result{ .fail = function.err_msg.? },858 error.CodegenFail => return error.CodegenFail,
865 error.OutOfRegisters => return Result{859 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
866 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
867 },
868 else => |e| return e,860 else => |e| return e,
869 };861 };
870862
...@@ -895,28 +887,10 @@ pub fn generate(...@@ -895,28 +887,10 @@ pub fn generate(
895 defer emit.deinit();887 defer emit.deinit();
896888
897 emit.emitMir() catch |err| switch (err) {889 emit.emitMir() catch |err| switch (err) {
898 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },890 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
899 error.InvalidInstruction => |e| {891 error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(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 },
912 else => |e| return e,892 else => |e| return e,
913 };893 };
914
915 if (function.err_msg) |em| {
916 return Result{ .fail = em };
917 } else {
918 return Result.ok;
919 }
920}894}
921895
922pub fn generateLazy(896pub fn generateLazy(
...@@ -926,7 +900,7 @@ pub fn generateLazy(...@@ -926,7 +900,7 @@ pub fn generateLazy(
926 lazy_sym: link.File.LazySymbol,900 lazy_sym: link.File.LazySymbol,
927 code: *std.ArrayList(u8),901 code: *std.ArrayList(u8),
928 debug_output: link.File.DebugInfoOutput,902 debug_output: link.File.DebugInfoOutput,
929) CodeGenError!Result {903) CodeGenError!void {
930 const comp = bin_file.comp;904 const comp = bin_file.comp;
931 const gpa = comp.gpa;905 const gpa = comp.gpa;
932 const mod = comp.root_mod;906 const mod = comp.root_mod;
...@@ -941,7 +915,6 @@ pub fn generateLazy(...@@ -941,7 +915,6 @@ pub fn generateLazy(
941 .target = &mod.resolved_target.result,915 .target = &mod.resolved_target.result,
942 .debug_output = debug_output,916 .debug_output = debug_output,
943 .owner = .{ .lazy_sym = lazy_sym },917 .owner = .{ .lazy_sym = lazy_sym },
944 .err_msg = null,
945 .args = undefined, // populated after `resolveCallingConventionValues`918 .args = undefined, // populated after `resolveCallingConventionValues`
946 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`919 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
947 .fn_type = undefined,920 .fn_type = undefined,
...@@ -957,10 +930,8 @@ pub fn generateLazy(...@@ -957,10 +930,8 @@ pub fn generateLazy(
957 defer function.mir_instructions.deinit(gpa);930 defer function.mir_instructions.deinit(gpa);
958931
959 function.genLazy(lazy_sym) catch |err| switch (err) {932 function.genLazy(lazy_sym) catch |err| switch (err) {
960 error.CodegenFail => return Result{ .fail = function.err_msg.? },933 error.CodegenFail => return error.CodegenFail,
961 error.OutOfRegisters => return Result{934 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
962 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
963 },
964 else => |e| return e,935 else => |e| return e,
965 };936 };
966937
...@@ -991,28 +962,10 @@ pub fn generateLazy(...@@ -991,28 +962,10 @@ pub fn generateLazy(
991 defer emit.deinit();962 defer emit.deinit();
992963
993 emit.emitMir() catch |err| switch (err) {964 emit.emitMir() catch |err| switch (err) {
994 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },965 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
995 error.InvalidInstruction => |e| {966 error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(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 },
1008 else => |e| return e,967 else => |e| return e,
1009 };968 };
1010
1011 if (function.err_msg) |em| {
1012 return Result{ .fail = em };
1013 } else {
1014 return Result.ok;
1015 }
1016}969}
1017970
1018const FormatWipMirData = struct {971const FormatWipMirData = struct {
...@@ -4758,19 +4711,19 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4758,19 +4711,19 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
4758 return func.fail("TODO implement codegen airFieldParentPtr", .{});4711 return func.fail("TODO implement codegen airFieldParentPtr", .{});
4759}4712}
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 {
4762 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4715 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4763 const ty = arg.ty.toType();4716 const ty = arg.ty.toType();
4764 if (arg.name == .none) return;4717 if (arg.name == .none) return;
47654718
4766 switch (func.debug_output) {4719 switch (func.debug_output) {
4767 .dwarf => |dw| switch (mcv) {4720 .dwarf => |dw| switch (mcv) {
4768 .register => |reg| try dw.genLocalDebugInfo(4721 .register => |reg| dw.genLocalDebugInfo(
4769 .local_arg,4722 .local_arg,
4770 arg.name.toSlice(func.air),4723 arg.name.toSlice(func.air),
4771 ty,4724 ty,
4772 .{ .reg = reg.dwarfNum() },4725 .{ .reg = reg.dwarfNum() },
4773 ),4726 ) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),
4774 .load_frame => {},4727 .load_frame => {},
4775 else => {},4728 else => {},
4776 },4729 },
...@@ -4779,7 +4732,7 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -4779,7 +4732,7 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4779 }4732 }
4780}4733}
47814734
4782fn airArg(func: *Func, inst: Air.Inst.Index) !void {4735fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
4783 var arg_index = func.arg_index;4736 var arg_index = func.arg_index;
47844737
4785 // we skip over args that have no bits4738 // we skip over args that have no bits
...@@ -5255,7 +5208,7 @@ fn airDbgInlineBlock(func: *Func, inst: Air.Inst.Index) !void {...@@ -5255,7 +5208,7 @@ fn airDbgInlineBlock(func: *Func, inst: Air.Inst.Index) !void {
5255 try func.lowerBlock(inst, @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));5208 try func.lowerBlock(inst, @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
5256}5209}
52575210
5258fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {5211fn airDbgVar(func: *Func, inst: Air.Inst.Index) InnerError!void {
5259 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5212 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
5260 const operand = pl_op.operand;5213 const operand = pl_op.operand;
5261 const ty = func.typeOf(operand);5214 const ty = func.typeOf(operand);
...@@ -5263,7 +5216,8 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {...@@ -5263,7 +5216,8 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
5263 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);5216 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
52645217
5265 const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)];5218 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
5268 return func.finishAir(inst, .unreach, .{ operand, .none, .none });5222 return func.finishAir(inst, .unreach, .{ operand, .none, .none });
5269}5223}
...@@ -8236,10 +8190,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {...@@ -8236,10 +8190,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
8236 return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)});8190 return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)});
8237 },8191 },
8238 },8192 },
8239 .fail => |msg| {8193 .fail => |msg| return func.failMsg(msg),
8240 func.err_msg = msg;
8241 return error.CodegenFail;
8242 },
8243 };8194 };
8244 return mcv;8195 return mcv;
8245}8196}
...@@ -8427,17 +8378,23 @@ fn wantSafety(func: *Func) bool {...@@ -8427,17 +8378,23 @@ fn wantSafety(func: *Func) bool {
8427 };8378 };
8428}8379}
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 } {
8431 @branchHint(.cold);8382 @branchHint(.cold);
8432 assert(func.err_msg == null);8383 const zcu = func.pt.zcu;
8433 func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args);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 }
8434 return error.CodegenFail;8388 return error.CodegenFail;
8435}8389}
84368390
8437fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerError {8391fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
8438 @branchHint(.cold);8392 @branchHint(.cold);
8439 assert(func.err_msg == null);8393 const zcu = func.pt.zcu;
8440 func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args);8394 switch (func.owner) {
8395 .nav_index => |i| return zcu.codegenFailMsg(i, msg),
8396 .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
8397 }
8441 return error.CodegenFail;8398 return error.CodegenFail;
8442}8399}
84438400
src/arch/sparc64/CodeGen.zig+20-24
...@@ -21,7 +21,6 @@ const Emit = @import("Emit.zig");...@@ -21,7 +21,6 @@ const Emit = @import("Emit.zig");
21const Liveness = @import("../../Liveness.zig");21const Liveness = @import("../../Liveness.zig");
22const Type = @import("../../Type.zig");22const Type = @import("../../Type.zig");
23const CodeGenError = codegen.CodeGenError;23const CodeGenError = codegen.CodeGenError;
24const Result = @import("../../codegen.zig").Result;
25const Endian = std.builtin.Endian;24const Endian = std.builtin.Endian;
26const Alignment = InternPool.Alignment;25const Alignment = InternPool.Alignment;
2726
...@@ -268,7 +267,7 @@ pub fn generate(...@@ -268,7 +267,7 @@ pub fn generate(
268 liveness: Liveness,267 liveness: Liveness,
269 code: *std.ArrayList(u8),268 code: *std.ArrayList(u8),
270 debug_output: link.File.DebugInfoOutput,269 debug_output: link.File.DebugInfoOutput,
271) CodeGenError!Result {270) CodeGenError!void {
272 const zcu = pt.zcu;271 const zcu = pt.zcu;
273 const gpa = zcu.gpa;272 const gpa = zcu.gpa;
274 const func = zcu.funcInfo(func_index);273 const func = zcu.funcInfo(func_index);
...@@ -310,10 +309,7 @@ pub fn generate(...@@ -310,10 +309,7 @@ pub fn generate(
310 defer function.exitlude_jump_relocs.deinit(gpa);309 defer function.exitlude_jump_relocs.deinit(gpa);
311310
312 var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) {311 var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) {
313 error.CodegenFail => return Result{ .fail = function.err_msg.? },312 error.CodegenFail => return error.CodegenFail,
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 },
317 else => |e| return e,313 else => |e| return e,
318 };314 };
319 defer call_info.deinit(&function);315 defer call_info.deinit(&function);
...@@ -324,10 +320,8 @@ pub fn generate(...@@ -324,10 +320,8 @@ pub fn generate(
324 function.max_end_stack = call_info.stack_byte_count;320 function.max_end_stack = call_info.stack_byte_count;
325321
326 function.gen() catch |err| switch (err) {322 function.gen() catch |err| switch (err) {
327 error.CodegenFail => return Result{ .fail = function.err_msg.? },323 error.CodegenFail => return error.CodegenFail,
328 error.OutOfRegisters => return Result{324 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
329 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
330 },
331 else => |e| return e,325 else => |e| return e,
332 };326 };
333327
...@@ -351,15 +345,9 @@ pub fn generate(...@@ -351,15 +345,9 @@ pub fn generate(
351 defer emit.deinit();345 defer emit.deinit();
352346
353 emit.emitMir() catch |err| switch (err) {347 emit.emitMir() catch |err| switch (err) {
354 error.EmitFail => return Result{ .fail = emit.err_msg.? },348 error.EmitFail => return function.failMsg(emit.err_msg.?),
355 else => |e| return e,349 else => |e| return e,
356 };350 };
357
358 if (function.err_msg) |em| {
359 return Result{ .fail = em };
360 } else {
361 return Result.ok;
362 }
363}351}
364352
365fn gen(self: *Self) !void {353fn gen(self: *Self) !void {
...@@ -1014,7 +1002,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -1014,7 +1002,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
1014 return bt.finishAir(result);1002 return bt.finishAir(result);
1015}1003}
10161004
1017fn airArg(self: *Self, inst: Air.Inst.Index) !void {1005fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
1018 const pt = self.pt;1006 const pt = self.pt;
1019 const zcu = pt.zcu;1007 const zcu = pt.zcu;
1020 const arg_index = self.arg_index;1008 const arg_index = self.arg_index;
...@@ -1036,7 +1024,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -1036,7 +1024,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1036 }1024 }
1037 };1025 };
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
1041 if (self.liveness.isUnused(inst))1030 if (self.liveness.isUnused(inst))
1042 return self.finishAirBookkeeping();1031 return self.finishAirBookkeeping();
...@@ -3511,12 +3500,19 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)...@@ -3511,12 +3500,19 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
3511 }3500 }
3512}3501}
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 } {
3515 @branchHint(.cold);3504 @branchHint(.cold);
3516 assert(self.err_msg == null);3505 const zcu = self.pt.zcu;
3517 const gpa = self.gpa;3506 const func = zcu.funcInfo(self.func_index);
3518 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);3507 const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
3519 return error.CodegenFail;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);
3520}3516}
35213517
3522/// Called when there are no operands, and the instruction is always unreferenced.3518/// 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;...@@ -19,7 +19,6 @@ const Allocator = mem.Allocator;
19const CodeGenError = codegen.CodeGenError;19const CodeGenError = codegen.CodeGenError;
20const Compilation = @import("../../Compilation.zig");20const Compilation = @import("../../Compilation.zig");
21const ErrorMsg = Zcu.ErrorMsg;21const ErrorMsg = Zcu.ErrorMsg;
22const Result = codegen.Result;
23const Emit = @import("Emit.zig");22const Emit = @import("Emit.zig");
24const Liveness = @import("../../Liveness.zig");23const Liveness = @import("../../Liveness.zig");
25const Lower = @import("Lower.zig");24const Lower = @import("Lower.zig");
...@@ -59,7 +58,6 @@ target: *const std.Target,...@@ -59,7 +58,6 @@ target: *const std.Target,
59owner: Owner,58owner: Owner,
60inline_func: InternPool.Index,59inline_func: InternPool.Index,
61mod: *Package.Module,60mod: *Package.Module,
62err_msg: ?*ErrorMsg,
63arg_index: u32,61arg_index: u32,
64args: []MCValue,62args: []MCValue,
65va_info: union {63va_info: union {
...@@ -821,7 +819,7 @@ pub fn generate(...@@ -821,7 +819,7 @@ pub fn generate(
821 liveness: Liveness,819 liveness: Liveness,
822 code: *std.ArrayList(u8),820 code: *std.ArrayList(u8),
823 debug_output: link.File.DebugInfoOutput,821 debug_output: link.File.DebugInfoOutput,
824) CodeGenError!Result {822) CodeGenError!void {
825 const zcu = pt.zcu;823 const zcu = pt.zcu;
826 const comp = zcu.comp;824 const comp = zcu.comp;
827 const gpa = zcu.gpa;825 const gpa = zcu.gpa;
...@@ -841,7 +839,6 @@ pub fn generate(...@@ -841,7 +839,6 @@ pub fn generate(
841 .debug_output = debug_output,839 .debug_output = debug_output,
842 .owner = .{ .nav_index = func.owner_nav },840 .owner = .{ .nav_index = func.owner_nav },
843 .inline_func = func_index,841 .inline_func = func_index,
844 .err_msg = null,
845 .arg_index = undefined,842 .arg_index = undefined,
846 .args = undefined, // populated after `resolveCallingConventionValues`843 .args = undefined, // populated after `resolveCallingConventionValues`
847 .va_info = undefined, // populated after `resolveCallingConventionValues`844 .va_info = undefined, // populated after `resolveCallingConventionValues`
...@@ -881,15 +878,7 @@ pub fn generate(...@@ -881,15 +878,7 @@ pub fn generate(
881 const fn_info = zcu.typeToFunc(fn_type).?;878 const fn_info = zcu.typeToFunc(fn_type).?;
882 const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*);879 const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*);
883 var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) {880 var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) {
884 error.CodegenFail => return Result{ .fail = function.err_msg.? },881 error.CodegenFail => return error.CodegenFail,
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 },
893 else => |e| return e,882 else => |e| return e,
894 };883 };
895 defer call_info.deinit(&function);884 defer call_info.deinit(&function);
...@@ -926,10 +915,8 @@ pub fn generate(...@@ -926,10 +915,8 @@ pub fn generate(
926 };915 };
927916
928 function.gen() catch |err| switch (err) {917 function.gen() catch |err| switch (err) {
929 error.CodegenFail => return Result{ .fail = function.err_msg.? },918 error.CodegenFail => return error.CodegenFail,
930 error.OutOfRegisters => return Result{919 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
931 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
932 },
933 else => |e| return e,920 else => |e| return e,
934 };921 };
935922
...@@ -953,10 +940,7 @@ pub fn generate(...@@ -953,10 +940,7 @@ pub fn generate(
953 .pic = mod.pic,940 .pic = mod.pic,
954 },941 },
955 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {942 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
956 error.CodegenFail => return Result{ .fail = function.err_msg.? },943 error.CodegenFail => return error.CodegenFail,
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 },
960 else => |e| return e,944 else => |e| return e,
961 },945 },
962 .debug_output = debug_output,946 .debug_output = debug_output,
...@@ -974,29 +958,11 @@ pub fn generate(...@@ -974,29 +958,11 @@ pub fn generate(
974 };958 };
975 defer emit.deinit();959 defer emit.deinit();
976 emit.emitMir() catch |err| switch (err) {960 emit.emitMir() catch |err| switch (err) {
977 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },961 error.LowerFail, error.EmitFail => return function.failMsg(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 };
994962
995 if (function.err_msg) |em| {963 error.InvalidInstruction, error.CannotEncode => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
996 return Result{ .fail = em };964 else => |e| return function.fail("emit MIR failed: {s}", .{@errorName(e)}),
997 } else {965 };
998 return Result.ok;
999 }
1000}966}
1001967
1002pub fn generateLazy(968pub fn generateLazy(
...@@ -1006,7 +972,7 @@ pub fn generateLazy(...@@ -1006,7 +972,7 @@ pub fn generateLazy(
1006 lazy_sym: link.File.LazySymbol,972 lazy_sym: link.File.LazySymbol,
1007 code: *std.ArrayList(u8),973 code: *std.ArrayList(u8),
1008 debug_output: link.File.DebugInfoOutput,974 debug_output: link.File.DebugInfoOutput,
1009) CodeGenError!Result {975) CodeGenError!void {
1010 const comp = bin_file.comp;976 const comp = bin_file.comp;
1011 const gpa = comp.gpa;977 const gpa = comp.gpa;
1012 // This function is for generating global code, so we use the root module.978 // This function is for generating global code, so we use the root module.
...@@ -1022,7 +988,6 @@ pub fn generateLazy(...@@ -1022,7 +988,6 @@ pub fn generateLazy(
1022 .debug_output = debug_output,988 .debug_output = debug_output,
1023 .owner = .{ .lazy_sym = lazy_sym },989 .owner = .{ .lazy_sym = lazy_sym },
1024 .inline_func = undefined,990 .inline_func = undefined,
1025 .err_msg = null,
1026 .arg_index = undefined,991 .arg_index = undefined,
1027 .args = undefined,992 .args = undefined,
1028 .va_info = undefined,993 .va_info = undefined,
...@@ -1038,10 +1003,8 @@ pub fn generateLazy(...@@ -1038,10 +1003,8 @@ pub fn generateLazy(
1038 }1003 }
10391004
1040 function.genLazy(lazy_sym) catch |err| switch (err) {1005 function.genLazy(lazy_sym) catch |err| switch (err) {
1041 error.CodegenFail => return Result{ .fail = function.err_msg.? },1006 error.CodegenFail => return error.CodegenFail,
1042 error.OutOfRegisters => return Result{1007 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
1043 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
1044 },
1045 else => |e| return e,1008 else => |e| return e,
1046 };1009 };
10471010
...@@ -1065,10 +1028,7 @@ pub fn generateLazy(...@@ -1065,10 +1028,7 @@ pub fn generateLazy(
1065 .pic = mod.pic,1028 .pic = mod.pic,
1066 },1029 },
1067 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {1030 .atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
1068 error.CodegenFail => return Result{ .fail = function.err_msg.? },1031 error.CodegenFail => return error.CodegenFail,
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 },
1072 else => |e| return e,1032 else => |e| return e,
1073 },1033 },
1074 .debug_output = debug_output,1034 .debug_output = debug_output,
...@@ -1078,29 +1038,11 @@ pub fn generateLazy(...@@ -1078,29 +1038,11 @@ pub fn generateLazy(
1078 };1038 };
1079 defer emit.deinit();1039 defer emit.deinit();
1080 emit.emitMir() catch |err| switch (err) {1040 emit.emitMir() catch |err| switch (err) {
1081 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },1041 error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
1082 error.InvalidInstruction, error.CannotEncode => |e| {1042 error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}),
1083 const msg = switch (e) {1043 error.CannotEncode => return function.fail("failed to find encode x86 instruction (Zig compiler bug)", .{}),
1084 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",1044 else => |e| return function.fail("failed to emit MIR: {s}", .{@errorName(e)}),
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,
1097 };1045 };
1098
1099 if (function.err_msg) |em| {
1100 return Result{ .fail = em };
1101 } else {
1102 return Result.ok;
1103 }
1104}1046}
11051047
1106const FormatNavData = struct {1048const FormatNavData = struct {
...@@ -19276,10 +19218,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {...@@ -19276,10 +19218,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
19276 .load_got => |sym_index| .{ .lea_got = sym_index },19218 .load_got => |sym_index| .{ .lea_got = sym_index },
19277 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },19219 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
19278 },19220 },
19279 .fail => |msg| {19221 .fail => |msg| return self.failMsg(msg),
19280 self.err_msg = msg;
19281 return error.CodegenFail;
19282 },
19283 };19222 };
19284}19223}
1928519224
...@@ -19592,11 +19531,23 @@ fn resolveCallingConventionValues(...@@ -19592,11 +19531,23 @@ fn resolveCallingConventionValues(
19592 return result;19531 return result;
19593}19532}
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 } {
19596 @branchHint(.cold);19535 @branchHint(.cold);
19597 assert(self.err_msg == null);19536 const zcu = self.pt.zcu;
19598 const gpa = self.gpa;19537 switch (self.owner) {
19599 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);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 }
19600 return error.CodegenFail;19551 return error.CodegenFail;
19601}19552}
1960219553
src/codegen.zig+56-113
...@@ -24,13 +24,6 @@ const Zir = std.zig.Zir;...@@ -24,13 +24,6 @@ const Zir = std.zig.Zir;
24const Alignment = InternPool.Alignment;24const Alignment = InternPool.Alignment;
25const dev = @import("dev.zig");25const 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
34pub const CodeGenError = error{27pub const CodeGenError = error{
35 OutOfMemory,28 OutOfMemory,
36 /// Compiler was asked to operate on a number larger than supported.29 /// Compiler was asked to operate on a number larger than supported.
...@@ -64,7 +57,7 @@ pub fn generateFunction(...@@ -64,7 +57,7 @@ pub fn generateFunction(
64 liveness: Liveness,57 liveness: Liveness,
65 code: *std.ArrayList(u8),58 code: *std.ArrayList(u8),
66 debug_output: link.File.DebugInfoOutput,59 debug_output: link.File.DebugInfoOutput,
67) CodeGenError!Result {60) CodeGenError!void {
68 const zcu = pt.zcu;61 const zcu = pt.zcu;
69 const func = zcu.funcInfo(func_index);62 const func = zcu.funcInfo(func_index);
70 const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;63 const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;
...@@ -89,7 +82,7 @@ pub fn generateLazyFunction(...@@ -89,7 +82,7 @@ pub fn generateLazyFunction(
89 lazy_sym: link.File.LazySymbol,82 lazy_sym: link.File.LazySymbol,
90 code: *std.ArrayList(u8),83 code: *std.ArrayList(u8),
91 debug_output: link.File.DebugInfoOutput,84 debug_output: link.File.DebugInfoOutput,
92) CodeGenError!Result {85) CodeGenError!void {
93 const zcu = pt.zcu;86 const zcu = pt.zcu;
94 const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool);87 const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool);
95 const target = zcu.fileByIndex(file).mod.resolved_target.result;88 const target = zcu.fileByIndex(file).mod.resolved_target.result;
...@@ -120,17 +113,17 @@ pub fn generateLazySymbol(...@@ -120,17 +113,17 @@ pub fn generateLazySymbol(
120 code: *std.ArrayList(u8),113 code: *std.ArrayList(u8),
121 debug_output: link.File.DebugInfoOutput,114 debug_output: link.File.DebugInfoOutput,
122 reloc_parent: link.File.RelocInfo.Parent,115 reloc_parent: link.File.RelocInfo.Parent,
123) CodeGenError!Result {116) CodeGenError!void {
124 _ = reloc_parent;117 _ = reloc_parent;
125118
126 const tracy = trace(@src());119 const tracy = trace(@src());
127 defer tracy.end();120 defer tracy.end();
128121
129 const comp = bin_file.comp;122 const comp = bin_file.comp;
130 const ip = &pt.zcu.intern_pool;123 const zcu = pt.zcu;
124 const ip = &zcu.intern_pool;
131 const target = comp.root_mod.resolved_target.result;125 const target = comp.root_mod.resolved_target.result;
132 const endian = target.cpu.arch.endian();126 const endian = target.cpu.arch.endian();
133 const gpa = comp.gpa;
134127
135 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{128 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
136 @tagName(lazy_sym.kind),129 @tagName(lazy_sym.kind),
...@@ -161,26 +154,29 @@ pub fn generateLazySymbol(...@@ -161,26 +154,29 @@ pub fn generateLazySymbol(
161 string_index += @intCast(err_name.len + 1);154 string_index += @intCast(err_name.len + 1);
162 }155 }
163 mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);156 mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
164 return .ok;157 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") {
165 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") {
166 alignment.* = .@"1";158 alignment.* = .@"1";
167 const enum_ty = Type.fromInterned(lazy_sym.ty);159 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);
169 for (0..tag_names.len) |tag_index| {161 for (0..tag_names.len) |tag_index| {
170 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);162 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
171 try code.ensureUnusedCapacity(tag_name.len + 1);163 try code.ensureUnusedCapacity(tag_name.len + 1);
172 code.appendSliceAssumeCapacity(tag_name);164 code.appendSliceAssumeCapacity(tag_name);
173 code.appendAssumeCapacity(0);165 code.appendAssumeCapacity(0);
174 }166 }
175 return .ok;167 } else {
176 } else return .{ .fail = try .create(168 return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {}", .{
177 gpa,169 @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt),
178 src_loc,170 });
179 "TODO implement generateLazySymbol for {s} {}",171 }
180 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
181 ) };
182}172}
183173
174pub const GenerateSymbolError = error{
175 OutOfMemory,
176 /// Compiler was asked to operate on a number larger than supported.
177 Overflow,
178};
179
184pub fn generateSymbol(180pub fn generateSymbol(
185 bin_file: *link.File,181 bin_file: *link.File,
186 pt: Zcu.PerThread,182 pt: Zcu.PerThread,
...@@ -188,7 +184,7 @@ pub fn generateSymbol(...@@ -188,7 +184,7 @@ pub fn generateSymbol(
188 val: Value,184 val: Value,
189 code: *std.ArrayList(u8),185 code: *std.ArrayList(u8),
190 reloc_parent: link.File.RelocInfo.Parent,186 reloc_parent: link.File.RelocInfo.Parent,
191) CodeGenError!Result {187) GenerateSymbolError!void {
192 const tracy = trace(@src());188 const tracy = trace(@src());
193 defer tracy.end();189 defer tracy.end();
194190
...@@ -204,7 +200,7 @@ pub fn generateSymbol(...@@ -204,7 +200,7 @@ pub fn generateSymbol(
204 if (val.isUndefDeep(zcu)) {200 if (val.isUndefDeep(zcu)) {
205 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;201 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
206 try code.appendNTimes(0xaa, abi_size);202 try code.appendNTimes(0xaa, abi_size);
207 return .ok;203 return;
208 }204 }
209205
210 switch (ip.indexToKey(val.toIntern())) {206 switch (ip.indexToKey(val.toIntern())) {
...@@ -266,7 +262,7 @@ pub fn generateSymbol(...@@ -266,7 +262,7 @@ pub fn generateSymbol(
266262
267 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {263 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
268 try code.writer().writeInt(u16, err_val, endian);264 try code.writer().writeInt(u16, err_val, endian);
269 return .ok;265 return;
270 }266 }
271267
272 const payload_align = payload_ty.abiAlignment(zcu);268 const payload_align = payload_ty.abiAlignment(zcu);
...@@ -281,13 +277,10 @@ pub fn generateSymbol(...@@ -281,13 +277,10 @@ pub fn generateSymbol(
281 // emit payload part of the error union277 // emit payload part of the error union
282 {278 {
283 const begin = code.items.len;279 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) {
285 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),281 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
286 .payload => |payload| payload,282 .payload => |payload| payload,
287 }), code, reloc_parent)) {283 }), code, reloc_parent);
288 .ok => {},
289 .fail => |em| return .{ .fail = em },
290 }
291 const unpadded_end = code.items.len - begin;284 const unpadded_end = code.items.len - begin;
292 const padded_end = abi_align.forward(unpadded_end);285 const padded_end = abi_align.forward(unpadded_end);
293 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;286 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
...@@ -312,10 +305,7 @@ pub fn generateSymbol(...@@ -312,10 +305,7 @@ pub fn generateSymbol(
312 },305 },
313 .enum_tag => |enum_tag| {306 .enum_tag => |enum_tag| {
314 const int_tag_ty = ty.intTagType(zcu);307 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)) {308 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 }
319 },309 },
320 .float => |float| switch (float.storage) {310 .float => |float| switch (float.storage) {
321 .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)),311 .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)),
...@@ -328,19 +318,10 @@ pub fn generateSymbol(...@@ -328,19 +318,10 @@ pub fn generateSymbol(
328 },318 },
329 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),319 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
330 },320 },
331 .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0)) {321 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
332 .ok => {},
333 .fail => |em| return .{ .fail = em },
334 },
335 .slice => |slice| {322 .slice => |slice| {
336 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent)) {323 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent);
337 .ok => {},324 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent);
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 }
344 },325 },
345 .opt => {326 .opt => {
346 const payload_type = ty.optionalChild(zcu);327 const payload_type = ty.optionalChild(zcu);
...@@ -349,10 +330,7 @@ pub fn generateSymbol(...@@ -349,10 +330,7 @@ pub fn generateSymbol(
349330
350 if (ty.optionalReprIsPayload(zcu)) {331 if (ty.optionalReprIsPayload(zcu)) {
351 if (payload_val) |value| {332 if (payload_val) |value| {
352 switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) {333 try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
353 .ok => {},
354 .fail => |em| return Result{ .fail = em },
355 }
356 } else {334 } else {
357 try code.appendNTimes(0, abi_size);335 try code.appendNTimes(0, abi_size);
358 }336 }
...@@ -362,10 +340,7 @@ pub fn generateSymbol(...@@ -362,10 +340,7 @@ pub fn generateSymbol(
362 const value = payload_val orelse Value.fromInterned(try pt.intern(.{340 const value = payload_val orelse Value.fromInterned(try pt.intern(.{
363 .undef = payload_type.toIntern(),341 .undef = payload_type.toIntern(),
364 }));342 }));
365 switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) {343 try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
366 .ok => {},
367 .fail => |em| return Result{ .fail = em },
368 }
369 }344 }
370 try code.writer().writeByte(@intFromBool(payload_val != null));345 try code.writer().writeByte(@intFromBool(payload_val != null));
371 try code.appendNTimes(0, padding);346 try code.appendNTimes(0, padding);
...@@ -377,17 +352,14 @@ pub fn generateSymbol(...@@ -377,17 +352,14 @@ pub fn generateSymbol(
377 .elems, .repeated_elem => {352 .elems, .repeated_elem => {
378 var index: u64 = 0;353 var index: u64 = 0;
379 while (index < array_type.lenIncludingSentinel()) : (index += 1) {354 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) {
381 .bytes => unreachable,356 .bytes => unreachable,
382 .elems => |elems| elems[@intCast(index)],357 .elems => |elems| elems[@intCast(index)],
383 .repeated_elem => |elem| if (index < array_type.len)358 .repeated_elem => |elem| if (index < array_type.len)
384 elem359 elem
385 else360 else
386 array_type.sentinel,361 array_type.sentinel,
387 }), code, reloc_parent)) {362 }), code, reloc_parent);
388 .ok => {},
389 .fail => |em| return .{ .fail = em },
390 }
391 }363 }
392 },364 },
393 },365 },
...@@ -437,16 +409,13 @@ pub fn generateSymbol(...@@ -437,16 +409,13 @@ pub fn generateSymbol(
437 .elems, .repeated_elem => {409 .elems, .repeated_elem => {
438 var index: u64 = 0;410 var index: u64 = 0;
439 while (index < vector_type.len) : (index += 1) {411 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) {
441 .bytes => unreachable,413 .bytes => unreachable,
442 .elems => |elems| elems[414 .elems => |elems| elems[
443 math.cast(usize, index) orelse return error.Overflow415 math.cast(usize, index) orelse return error.Overflow
444 ],416 ],
445 .repeated_elem => |elem| elem,417 .repeated_elem => |elem| elem,
446 }), code, reloc_parent)) {418 }), code, reloc_parent);
447 .ok => {},
448 .fail => |em| return .{ .fail = em },
449 }
450 }419 }
451 },420 },
452 }421 }
...@@ -476,10 +445,7 @@ pub fn generateSymbol(...@@ -476,10 +445,7 @@ pub fn generateSymbol(
476 .repeated_elem => |elem| elem,445 .repeated_elem => |elem| elem,
477 };446 };
478447
479 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) {448 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
480 .ok => {},
481 .fail => |em| return Result{ .fail = em },
482 }
483 const unpadded_field_end = code.items.len - struct_begin;449 const unpadded_field_end = code.items.len - struct_begin;
484450
485 // Pad struct members if required451 // Pad struct members if required
...@@ -518,10 +484,8 @@ pub fn generateSymbol(...@@ -518,10 +484,8 @@ pub fn generateSymbol(
518 return error.Overflow;484 return error.Overflow;
519 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);485 var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
520 defer tmp_list.deinit();486 defer tmp_list.deinit();
521 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent)) {487 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),488 @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items);
523 .fail => |em| return Result{ .fail = em },
524 }
525 } else {489 } else {
526 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;490 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
527 }491 }
...@@ -553,10 +517,7 @@ pub fn generateSymbol(...@@ -553,10 +517,7 @@ pub fn generateSymbol(
553 ) orelse return error.Overflow;517 ) orelse return error.Overflow;
554 if (padding > 0) try code.appendNTimes(0, padding);518 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)) {520 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
557 .ok => {},
558 .fail => |em| return Result{ .fail = em },
559 }
560 }521 }
561522
562 const size = struct_type.sizeUnordered(ip);523 const size = struct_type.sizeUnordered(ip);
...@@ -582,10 +543,7 @@ pub fn generateSymbol(...@@ -582,10 +543,7 @@ pub fn generateSymbol(
582543
583 // Check if we should store the tag first.544 // Check if we should store the tag first.
584 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {545 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)) {546 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
586 .ok => {},
587 .fail => |em| return Result{ .fail = em },
588 }
589 }547 }
590548
591 const union_obj = zcu.typeToUnion(ty).?;549 const union_obj = zcu.typeToUnion(ty).?;
...@@ -595,10 +553,7 @@ pub fn generateSymbol(...@@ -595,10 +553,7 @@ pub fn generateSymbol(
595 if (!field_ty.hasRuntimeBits(zcu)) {553 if (!field_ty.hasRuntimeBits(zcu)) {
596 try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);554 try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
597 } else {555 } else {
598 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) {556 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
599 .ok => {},
600 .fail => |em| return Result{ .fail = em },
601 }
602557
603 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;558 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
604 if (padding > 0) {559 if (padding > 0) {
...@@ -606,17 +561,11 @@ pub fn generateSymbol(...@@ -606,17 +561,11 @@ pub fn generateSymbol(
606 }561 }
607 }562 }
608 } else {563 } else {
609 switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) {564 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
610 .ok => {},
611 .fail => |em| return Result{ .fail = em },
612 }
613 }565 }
614566
615 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {567 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)) {568 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
617 .ok => {},
618 .fail => |em| return Result{ .fail = em },
619 }
620569
621 if (layout.padding > 0) {570 if (layout.padding > 0) {
622 try code.appendNTimes(0, layout.padding);571 try code.appendNTimes(0, layout.padding);
...@@ -625,7 +574,6 @@ pub fn generateSymbol(...@@ -625,7 +574,6 @@ pub fn generateSymbol(
625 },574 },
626 .memoized_call => unreachable,575 .memoized_call => unreachable,
627 }576 }
628 return .ok;
629}577}
630578
631fn lowerPtr(579fn lowerPtr(
...@@ -636,7 +584,7 @@ fn lowerPtr(...@@ -636,7 +584,7 @@ fn lowerPtr(
636 code: *std.ArrayList(u8),584 code: *std.ArrayList(u8),
637 reloc_parent: link.File.RelocInfo.Parent,585 reloc_parent: link.File.RelocInfo.Parent,
638 prev_offset: u64,586 prev_offset: u64,
639) CodeGenError!Result {587) GenerateSymbolError!void {
640 const zcu = pt.zcu;588 const zcu = pt.zcu;
641 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;589 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
642 const offset: u64 = prev_offset + ptr.byte_offset;590 const offset: u64 = prev_offset + ptr.byte_offset;
...@@ -689,7 +637,7 @@ fn lowerUavRef(...@@ -689,7 +637,7 @@ fn lowerUavRef(
689 code: *std.ArrayList(u8),637 code: *std.ArrayList(u8),
690 reloc_parent: link.File.RelocInfo.Parent,638 reloc_parent: link.File.RelocInfo.Parent,
691 offset: u64,639 offset: u64,
692) CodeGenError!Result {640) GenerateSymbolError!void {
693 const zcu = pt.zcu;641 const zcu = pt.zcu;
694 const gpa = zcu.gpa;642 const gpa = zcu.gpa;
695 const ip = &zcu.intern_pool;643 const ip = &zcu.intern_pool;
...@@ -702,14 +650,7 @@ fn lowerUavRef(...@@ -702,14 +650,7 @@ fn lowerUavRef(
702 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";650 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
703 if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {651 if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {
704 try code.appendNTimes(0xaa, ptr_width_bytes);652 try code.appendNTimes(0xaa, ptr_width_bytes);
705 return .ok;653 return;
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 },
713 }654 }
714655
715 switch (lf.tag) {656 switch (lf.tag) {
...@@ -727,11 +668,17 @@ fn lowerUavRef(...@@ -727,11 +668,17 @@ fn lowerUavRef(
727 .pointee = .{ .uav_index = uav.val },668 .pointee = .{ .uav_index = uav.val },
728 });669 });
729 try code.appendNTimes(0, ptr_width_bytes);670 try code.appendNTimes(0, ptr_width_bytes);
730 return .ok;671 return;
731 },672 },
732 else => {},673 else => {},
733 }674 }
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
735 const vaddr = try lf.getUavVAddr(uav_val, .{682 const vaddr = try lf.getUavVAddr(uav_val, .{
736 .parent = reloc_parent,683 .parent = reloc_parent,
737 .offset = code.items.len,684 .offset = code.items.len,
...@@ -744,8 +691,6 @@ fn lowerUavRef(...@@ -744,8 +691,6 @@ fn lowerUavRef(
744 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),691 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
745 else => unreachable,692 else => unreachable,
746 }693 }
747
748 return Result.ok;
749}694}
750695
751fn lowerNavRef(696fn lowerNavRef(
...@@ -756,7 +701,7 @@ fn lowerNavRef(...@@ -756,7 +701,7 @@ fn lowerNavRef(
756 code: *std.ArrayList(u8),701 code: *std.ArrayList(u8),
757 reloc_parent: link.File.RelocInfo.Parent,702 reloc_parent: link.File.RelocInfo.Parent,
758 offset: u64,703 offset: u64,
759) CodeGenError!Result {704) GenerateSymbolError!void {
760 _ = src_loc;705 _ = src_loc;
761 const zcu = pt.zcu;706 const zcu = pt.zcu;
762 const gpa = zcu.gpa;707 const gpa = zcu.gpa;
...@@ -768,7 +713,7 @@ fn lowerNavRef(...@@ -768,7 +713,7 @@ fn lowerNavRef(
768 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";713 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
769 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {714 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
770 try code.appendNTimes(0xaa, ptr_width_bytes);715 try code.appendNTimes(0xaa, ptr_width_bytes);
771 return Result.ok;716 return;
772 }717 }
773718
774 switch (lf.tag) {719 switch (lf.tag) {
...@@ -786,16 +731,16 @@ fn lowerNavRef(...@@ -786,16 +731,16 @@ fn lowerNavRef(
786 .pointee = .{ .nav_index = nav_index },731 .pointee = .{ .nav_index = nav_index },
787 });732 });
788 try code.appendNTimes(0, ptr_width_bytes);733 try code.appendNTimes(0, ptr_width_bytes);
789 return .ok;734 return;
790 },735 },
791 else => {},736 else => {},
792 }737 }
793738
794 const vaddr = try lf.getNavVAddr(pt, nav_index, .{739 const vaddr = lf.getNavVAddr(pt, nav_index, .{
795 .parent = reloc_parent,740 .parent = reloc_parent,
796 .offset = code.items.len,741 .offset = code.items.len,
797 .addend = @intCast(offset),742 .addend = @intCast(offset),
798 });743 }) catch @panic("TODO rework getNavVAddr");
799 const endian = target.cpu.arch.endian();744 const endian = target.cpu.arch.endian();
800 switch (ptr_width_bytes) {745 switch (ptr_width_bytes) {
801 2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),746 2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),
...@@ -803,8 +748,6 @@ fn lowerNavRef(...@@ -803,8 +748,6 @@ fn lowerNavRef(
803 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),748 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
804 else => unreachable,749 else => unreachable,
805 }750 }
806
807 return .ok;
808}751}
809752
810/// Helper struct to denote that the value is in memory but requires a linker relocation fixup:753/// 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 {...@@ -673,7 +673,13 @@ pub const File = struct {
673 }673 }
674 }674 }
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 {
677 switch (base.tag) {683 switch (base.tag) {
678 else => {},684 else => {},
679 inline .elf => |tag| {685 inline .elf => |tag| {
src/link/Coff.zig+57-48
...@@ -754,7 +754,7 @@ fn allocateGlobal(coff: *Coff) !u32 {...@@ -754,7 +754,7 @@ fn allocateGlobal(coff: *Coff) !u32 {
754 return index;754 return index;
755}755}
756756
757fn addGotEntry(coff: *Coff, target: SymbolWithLoc) error{ OutOfMemory, LinkFailure }!void {757fn addGotEntry(coff: *Coff, target: SymbolWithLoc) !void {
758 const gpa = coff.base.comp.gpa;758 const gpa = coff.base.comp.gpa;
759 if (coff.got_table.lookup.contains(target)) return;759 if (coff.got_table.lookup.contains(target)) return;
760 const got_index = try coff.got_table.allocateEntry(gpa, target);760 const got_index = try coff.got_table.allocateEntry(gpa, target);
...@@ -780,7 +780,7 @@ pub fn createAtom(coff: *Coff) !Atom.Index {...@@ -780,7 +780,7 @@ pub fn createAtom(coff: *Coff) !Atom.Index {
780 return atom_index;780 return atom_index;
781}781}
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 {
784 const atom = coff.getAtom(atom_index);784 const atom = coff.getAtom(atom_index);
785 const sym = atom.getSymbol(coff);785 const sym = atom.getSymbol(coff);
786 const align_ok = mem.alignBackward(u32, sym.value, alignment) == sym.value;786 const align_ok = mem.alignBackward(u32, sym.value, alignment) == sym.value;
...@@ -909,12 +909,12 @@ fn writeOffsetTableEntry(coff: *Coff, index: usize) !void {...@@ -909,12 +909,12 @@ fn writeOffsetTableEntry(coff: *Coff, index: usize) !void {
909 .p32 => {909 .p32 => {
910 var buf: [4]u8 = undefined;910 var buf: [4]u8 = undefined;
911 mem.writeInt(u32, &buf, @intCast(entry_value + coff.image_base), .little);911 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);
913 },913 },
914 .p64 => {914 .p64 => {
915 var buf: [8]u8 = undefined;915 var buf: [8]u8 = undefined;
916 mem.writeInt(u64, &buf, entry_value + coff.image_base, .little);916 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);
918 },918 },
919 }919 }
920920
...@@ -1122,7 +1122,7 @@ pub fn updateFunc(...@@ -1122,7 +1122,7 @@ pub fn updateFunc(
1122 var code_buffer = std.ArrayList(u8).init(gpa);1122 var code_buffer = std.ArrayList(u8).init(gpa);
1123 defer code_buffer.deinit();1123 defer code_buffer.deinit();
11241124
1125 const res = codegen.generateFunction(1125 codegen.generateFunction(
1126 &coff.base,1126 &coff.base,
1127 pt,1127 pt,
1128 zcu.navSrcLoc(nav_index),1128 zcu.navSrcLoc(nav_index),
...@@ -1134,7 +1134,7 @@ pub fn updateFunc(...@@ -1134,7 +1134,7 @@ pub fn updateFunc(
1134 ) catch |err| switch (err) {1134 ) catch |err| switch (err) {
1135 error.CodegenFail => return error.CodegenFail,1135 error.CodegenFail => return error.CodegenFail,
1136 error.OutOfMemory => return error.OutOfMemory,1136 error.OutOfMemory => return error.OutOfMemory,
1137 else => |e| {1137 error.Overflow => |e| {
1138 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(1138 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
1139 gpa,1139 gpa,
1140 zcu.navSrcLoc(nav_index),1140 zcu.navSrcLoc(nav_index),
...@@ -1145,15 +1145,8 @@ pub fn updateFunc(...@@ -1145,15 +1145,8 @@ pub fn updateFunc(
1145 return error.CodegenFail;1145 return error.CodegenFail;
1146 },1146 },
1147 };1147 };
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
1158 // Exports will be updated by `Zcu.processExports` after the update.1151 // Exports will be updated by `Zcu.processExports` after the update.
1159}1152}
...@@ -1182,16 +1175,13 @@ fn lowerConst(...@@ -1182,16 +1175,13 @@ fn lowerConst(
1182 try coff.setSymbolName(sym, name);1175 try coff.setSymbolName(sym, name);
1183 sym.section_number = @as(coff_util.SectionNumber, @enumFromInt(sect_id + 1));1176 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, .{
1186 .atom_index = coff.getAtom(atom_index).getSymbolIndex().?,1179 .atom_index = coff.getAtom(atom_index).getSymbolIndex().?,
1187 });1180 });
1188 const code = switch (res) {1181 const code = code_buffer.items;
1189 .ok => code_buffer.items,
1190 .fail => |em| return .{ .fail = em },
1191 };
11921182
1193 const atom = coff.getAtomPtr(atom_index);1183 const atom = coff.getAtomPtr(atom_index);
1194 atom.size = @as(u32, @intCast(code.len));1184 atom.size = @intCast(code.len);
1195 atom.getSymbolPtr(coff).value = try coff.allocateAtom(1185 atom.getSymbolPtr(coff).value = try coff.allocateAtom(
1196 atom_index,1186 atom_index,
1197 atom.size,1187 atom.size,
...@@ -1250,7 +1240,7 @@ pub fn updateNav(...@@ -1250,7 +1240,7 @@ pub fn updateNav(
1250 var code_buffer = std.ArrayList(u8).init(gpa);1240 var code_buffer = std.ArrayList(u8).init(gpa);
1251 defer code_buffer.deinit();1241 defer code_buffer.deinit();
12521242
1253 const res = try codegen.generateSymbol(1243 try codegen.generateSymbol(
1254 &coff.base,1244 &coff.base,
1255 pt,1245 pt,
1256 zcu.navSrcLoc(nav_index),1246 zcu.navSrcLoc(nav_index),
...@@ -1258,15 +1248,8 @@ pub fn updateNav(...@@ -1258,15 +1248,8 @@ pub fn updateNav(
1258 &code_buffer,1248 &code_buffer,
1259 .{ .atom_index = atom.getSymbolIndex().? },1249 .{ .atom_index = atom.getSymbolIndex().? },
1260 );1250 );
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);
1270 }1253 }
12711254
1272 // Exports will be updated by `Zcu.processExports` after the update.1255 // Exports will be updated by `Zcu.processExports` after the update.
...@@ -1278,11 +1261,10 @@ fn updateLazySymbolAtom(...@@ -1278,11 +1261,10 @@ fn updateLazySymbolAtom(
1278 sym: link.File.LazySymbol,1261 sym: link.File.LazySymbol,
1279 atom_index: Atom.Index,1262 atom_index: Atom.Index,
1280 section_index: u16,1263 section_index: u16,
1281) link.File.FlushError!void {1264) !void {
1282 const zcu = pt.zcu;1265 const zcu = pt.zcu;
1283 const comp = coff.base.comp;1266 const comp = coff.base.comp;
1284 const gpa = comp.gpa;1267 const gpa = comp.gpa;
1285 const diags = &comp.link_diags;
12861268
1287 var required_alignment: InternPool.Alignment = .none;1269 var required_alignment: InternPool.Alignment = .none;
1288 var code_buffer = std.ArrayList(u8).init(gpa);1270 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1298,7 +1280,7 @@ fn updateLazySymbolAtom(...@@ -1298,7 +1280,7 @@ fn updateLazySymbolAtom(
1298 const local_sym_index = atom.getSymbolIndex().?;1280 const local_sym_index = atom.getSymbolIndex().?;
12991281
1300 const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;1282 const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1301 const res = codegen.generateLazySymbol(1283 try codegen.generateLazySymbol(
1302 &coff.base,1284 &coff.base,
1303 pt,1285 pt,
1304 src,1286 src,
...@@ -1307,14 +1289,8 @@ fn updateLazySymbolAtom(...@@ -1307,14 +1289,8 @@ fn updateLazySymbolAtom(
1307 &code_buffer,1289 &code_buffer,
1308 .none,1290 .none,
1309 .{ .atom_index = local_sym_index },1291 .{ .atom_index = local_sym_index },
1310 ) catch |err| switch (err) {1292 );
1311 error.CodegenFail => return error.LinkFailure,1293 const code = code_buffer.items;
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 };
13181294
1319 const code_len: u32 = @intCast(code.len);1295 const code_len: u32 = @intCast(code.len);
1320 const symbol = atom.getSymbolPtr(coff);1296 const symbol = atom.getSymbolPtr(coff);
...@@ -1438,7 +1414,10 @@ fn updateNavCode(...@@ -1438,7 +1414,10 @@ fn updateNavCode(
1438 const capacity = atom.capacity(coff);1414 const capacity = atom.capacity(coff);
1439 const need_realloc = code.len > capacity or !required_alignment.check(sym.value);1415 const need_realloc = code.len > capacity or !required_alignment.check(sym.value);
1440 if (need_realloc) {1416 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 };
1442 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });1421 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
1443 log.debug(" (required alignment 0x{x}", .{required_alignment});1422 log.debug(" (required alignment 0x{x}", .{required_alignment});
14441423
...@@ -1446,7 +1425,10 @@ fn updateNavCode(...@@ -1446,7 +1425,10 @@ fn updateNavCode(
1446 sym.value = vaddr;1425 sym.value = vaddr;
1447 log.debug(" (updating GOT entry)", .{});1426 log.debug(" (updating GOT entry)", .{});
1448 const got_entry_index = coff.got_table.lookup.get(.{ .sym_index = sym_index }).?;1427 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 };
1450 coff.markRelocsDirtyByTarget(.{ .sym_index = sym_index });1432 coff.markRelocsDirtyByTarget(.{ .sym_index = sym_index });
1451 }1433 }
1452 } else if (code_len < atom.size) {1434 } else if (code_len < atom.size) {
...@@ -1459,16 +1441,25 @@ fn updateNavCode(...@@ -1459,16 +1441,25 @@ fn updateNavCode(
1459 sym.section_number = @enumFromInt(sect_index + 1);1441 sym.section_number = @enumFromInt(sect_index + 1);
1460 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };1442 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 };
1463 errdefer coff.freeAtom(atom_index);1448 errdefer coff.freeAtom(atom_index);
1464 log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });1449 log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });
1465 coff.getAtomPtr(atom_index).size = code_len;1450 coff.getAtomPtr(atom_index).size = code_len;
1466 sym.value = vaddr;1451 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 };
1469 }1457 }
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 };
1472}1463}
14731464
1474pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void {1465pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void {
...@@ -2229,12 +2220,16 @@ fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Director...@@ -2229,12 +2220,16 @@ fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Director
2229 return null;2220 return null;
2230}2221}
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 {
2233 const tracy = trace(@src());2229 const tracy = trace(@src());
2234 defer tracy.end();2230 defer tracy.end();
22352231
2236 const comp = coff.base.comp;2232 const comp = coff.base.comp;
2237 const gpa = comp.gpa;
2238 const diags = &comp.link_diags;2233 const diags = &comp.link_diags;
22392234
2240 if (coff.llvm_object) |llvm_object| {2235 if (coff.llvm_object) |llvm_object| {
...@@ -2245,6 +2240,20 @@ pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no...@@ -2245,6 +2240,20 @@ pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
2245 const sub_prog_node = prog_node.start("COFF Flush", 0);2240 const sub_prog_node = prog_node.start("COFF Flush", 0);
2246 defer sub_prog_node.end();2241 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
2248 const pt: Zcu.PerThread = .activate(2257 const pt: Zcu.PerThread = .activate(
2249 comp.zcu orelse return diags.fail("linking without zig source is not yet implemented", .{}),2258 comp.zcu orelse return diags.fail("linking without zig source is not yet implemented", .{}),
2250 tid,2259 tid,
...@@ -2757,7 +2766,7 @@ fn writeImportTables(coff: *Coff) !void {...@@ -2757,7 +2766,7 @@ fn writeImportTables(coff: *Coff) !void {
2757 coff.imports_count_dirty = false;2766 coff.imports_count_dirty = false;
2758}2767}
27592768
2760fn writeStrtab(coff: *Coff) link.File.FlushError!void {2769fn writeStrtab(coff: *Coff) !void {
2761 if (coff.strtab_offset == null) return;2770 if (coff.strtab_offset == null) return;
27622771
2763 const comp = coff.base.comp;2772 const comp = coff.base.comp;
src/link/Dwarf.zig+3-9
...@@ -21,7 +21,6 @@ debug_rnglists: DebugRngLists,...@@ -21,7 +21,6 @@ debug_rnglists: DebugRngLists,
21debug_str: StringSection,21debug_str: StringSection,
2222
23pub const UpdateError = error{23pub const UpdateError = error{
24 CodegenFail,
25 ReinterpretDeclRef,24 ReinterpretDeclRef,
26 Unimplemented,25 Unimplemented,
27 OutOfMemory,26 OutOfMemory,
...@@ -1893,17 +1892,15 @@ pub const WipNav = struct {...@@ -1893,17 +1892,15 @@ pub const WipNav = struct {
1893 if (bytes == 0) return;1892 if (bytes == 0) return;
1894 var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa);1893 var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa);
1895 defer wip_nav.debug_info = dim.moveToUnmanaged();1894 defer wip_nav.debug_info = dim.moveToUnmanaged();
1896 switch (try codegen.generateSymbol(1895 try codegen.generateSymbol(
1897 wip_nav.dwarf.bin_file,1896 wip_nav.dwarf.bin_file,
1898 wip_nav.pt,1897 wip_nav.pt,
1899 src_loc,1898 src_loc,
1900 val,1899 val,
1901 &dim,1900 &dim,
1902 .{ .debug_output = .{ .dwarf = wip_nav } },1901 .{ .debug_output = .{ .dwarf = wip_nav } },
1903 )) {1902 );
1904 .ok => assert(dim.items.len == wip_nav.debug_info.items.len + bytes),1903 assert(dim.items.len == wip_nav.debug_info.items.len + bytes);
1905 .fail => unreachable,
1906 }
1907 }1904 }
19081905
1909 const AbbrevCodeForForm = struct {1906 const AbbrevCodeForForm = struct {
...@@ -2346,7 +2343,6 @@ pub fn initWipNav(...@@ -2346,7 +2343,6 @@ pub fn initWipNav(
2346) error{ OutOfMemory, CodegenFail }!?WipNav {2343) error{ OutOfMemory, CodegenFail }!?WipNav {
2347 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {2344 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
2348 error.OutOfMemory => return error.OutOfMemory,2345 error.OutOfMemory => return error.OutOfMemory,
2349 error.CodegenFail => return error.CodegenFail,
2350 else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),2346 else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
2351 };2347 };
2352}2348}
...@@ -2669,7 +2665,6 @@ pub fn finishWipNav(...@@ -2669,7 +2665,6 @@ pub fn finishWipNav(
2669) error{ OutOfMemory, CodegenFail }!void {2665) error{ OutOfMemory, CodegenFail }!void {
2670 return finishWipNavInner(dwarf, pt, nav_index, wip_nav) catch |err| switch (err) {2666 return finishWipNavInner(dwarf, pt, nav_index, wip_nav) catch |err| switch (err) {
2671 error.OutOfMemory => return error.OutOfMemory,2667 error.OutOfMemory => return error.OutOfMemory,
2672 error.CodegenFail => return error.CodegenFail,
2673 else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf: {s}", .{@errorName(e)}),2668 else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf: {s}", .{@errorName(e)}),
2674 };2669 };
2675}2670}
...@@ -2701,7 +2696,6 @@ fn finishWipNavInner(...@@ -2701,7 +2696,6 @@ fn finishWipNavInner(
2701pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {2696pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {
2702 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {2697 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
2703 error.OutOfMemory => return error.OutOfMemory,2698 error.OutOfMemory => return error.OutOfMemory,
2704 error.CodegenFail => return error.CodegenFail,
2705 else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),2699 else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
2706 };2700 };
2707}2701}
src/link/Elf.zig+15-2
...@@ -2368,12 +2368,25 @@ pub fn updateContainerType(...@@ -2368,12 +2368,25 @@ pub fn updateContainerType(
2368 self: *Elf,2368 self: *Elf,
2369 pt: Zcu.PerThread,2369 pt: Zcu.PerThread,
2370 ty: InternPool.Index,2370 ty: InternPool.Index,
2371) link.File.UpdateNavError!void {2371) link.File.UpdateContainerTypeError!void {
2372 if (build_options.skip_non_native and builtin.object_format != .elf) {2372 if (build_options.skip_non_native and builtin.object_format != .elf) {
2373 @panic("Attempted to compile for object format that was disabled by build configuration");2373 @panic("Attempted to compile for object format that was disabled by build configuration");
2374 }2374 }
2375 if (self.llvm_object) |_| return;2375 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 };
2377}2390}
23782391
2379pub fn updateExports(2392pub fn updateExports(
src/link/Elf/ZigObject.zig+9-32
...@@ -1437,7 +1437,7 @@ pub fn updateFunc(...@@ -1437,7 +1437,7 @@ pub fn updateFunc(
1437 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;1437 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
1438 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();1438 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
14391439
1440 const res = try codegen.generateFunction(1440 try codegen.generateFunction(
1441 &elf_file.base,1441 &elf_file.base,
1442 pt,1442 pt,
1443 zcu.navSrcLoc(func.owner_nav),1443 zcu.navSrcLoc(func.owner_nav),
...@@ -1447,14 +1447,7 @@ pub fn updateFunc(...@@ -1447,14 +1447,7 @@ pub fn updateFunc(
1447 &code_buffer,1447 &code_buffer,
1448 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,1448 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
1449 );1449 );
14501450 const code = code_buffer.items;
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 };
14581451
1459 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);1452 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
1460 log.debug("setting shdr({x},{s}) for {}", .{1453 log.debug("setting shdr({x},{s}) for {}", .{
...@@ -1574,7 +1567,7 @@ pub fn updateNav(...@@ -1574,7 +1567,7 @@ pub fn updateNav(
1574 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;1567 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
1575 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();1568 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
15761569
1577 const res = try codegen.generateSymbol(1570 try codegen.generateSymbol(
1578 &elf_file.base,1571 &elf_file.base,
1579 pt,1572 pt,
1580 zcu.navSrcLoc(nav_index),1573 zcu.navSrcLoc(nav_index),
...@@ -1582,14 +1575,7 @@ pub fn updateNav(...@@ -1582,14 +1575,7 @@ pub fn updateNav(
1582 &code_buffer,1575 &code_buffer,
1583 .{ .atom_index = sym_index },1576 .{ .atom_index = sym_index },
1584 );1577 );
15851578 const code = code_buffer.items;
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 };
15931579
1594 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);1580 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
1595 log.debug("setting shdr({x},{s}) for {}", .{1581 log.debug("setting shdr({x},{s}) for {}", .{
...@@ -1612,7 +1598,7 @@ pub fn updateContainerType(...@@ -1612,7 +1598,7 @@ pub fn updateContainerType(
1612 self: *ZigObject,1598 self: *ZigObject,
1613 pt: Zcu.PerThread,1599 pt: Zcu.PerThread,
1614 ty: InternPool.Index,1600 ty: InternPool.Index,
1615) link.File.UpdateNavError!void {1601) !void {
1616 const tracy = trace(@src());1602 const tracy = trace(@src());
1617 defer tracy.end();1603 defer tracy.end();
16181604
...@@ -1643,7 +1629,7 @@ fn updateLazySymbol(...@@ -1643,7 +1629,7 @@ fn updateLazySymbol(
1643 };1629 };
16441630
1645 const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;1631 const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1646 const res = try codegen.generateLazySymbol(1632 try codegen.generateLazySymbol(
1647 &elf_file.base,1633 &elf_file.base,
1648 pt,1634 pt,
1649 src,1635 src,
...@@ -1653,13 +1639,7 @@ fn updateLazySymbol(...@@ -1653,13 +1639,7 @@ fn updateLazySymbol(
1653 .none,1639 .none,
1654 .{ .atom_index = symbol_index },1640 .{ .atom_index = symbol_index },
1655 );1641 );
1656 const code = switch (res) {1642 const code = code_buffer.items;
1657 .ok => code_buffer.items,
1658 .fail => |em| {
1659 log.err("{s}", .{em.msg});
1660 return error.CodegenFail;
1661 },
1662 };
16631643
1664 const output_section_index = switch (sym.kind) {1644 const output_section_index = switch (sym.kind) {
1665 .code => if (self.text_index) |sym_index|1645 .code => if (self.text_index) |sym_index|
...@@ -1732,7 +1712,7 @@ fn lowerConst(...@@ -1732,7 +1712,7 @@ fn lowerConst(
1732 const name_off = try self.addString(gpa, name);1712 const name_off = try self.addString(gpa, name);
1733 const sym_index = try self.newSymbolWithAtom(gpa, name_off);1713 const sym_index = try self.newSymbolWithAtom(gpa, name_off);
17341714
1735 const res = try codegen.generateSymbol(1715 try codegen.generateSymbol(
1736 &elf_file.base,1716 &elf_file.base,
1737 pt,1717 pt,
1738 src_loc,1718 src_loc,
...@@ -1740,10 +1720,7 @@ fn lowerConst(...@@ -1740,10 +1720,7 @@ fn lowerConst(
1740 &code_buffer,1720 &code_buffer,
1741 .{ .atom_index = sym_index },1721 .{ .atom_index = sym_index },
1742 );1722 );
1743 const code = switch (res) {1723 const code = code_buffer.items;
1744 .ok => code_buffer.items,
1745 .fail => |em| return .{ .fail = em },
1746 };
17471724
1748 const local_sym = self.symbol(sym_index);1725 const local_sym = self.symbol(sym_index);
1749 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];1726 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)...@@ -590,7 +590,6 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
590 defer pt.deactivate();590 defer pt.deactivate();
591 dwarf.flushModule(pt) catch |err| switch (err) {591 dwarf.flushModule(pt) catch |err| switch (err) {
592 error.OutOfMemory => return error.OutOfMemory,592 error.OutOfMemory => return error.OutOfMemory,
593 error.CodegenFail => return error.LinkFailure,
594 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),593 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),
595 };594 };
596595
...@@ -796,7 +795,7 @@ pub fn updateFunc(...@@ -796,7 +795,7 @@ pub fn updateFunc(
796 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;795 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
797 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();796 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
798797
799 const res = try codegen.generateFunction(798 try codegen.generateFunction(
800 &macho_file.base,799 &macho_file.base,
801 pt,800 pt,
802 zcu.navSrcLoc(func.owner_nav),801 zcu.navSrcLoc(func.owner_nav),
...@@ -806,14 +805,7 @@ pub fn updateFunc(...@@ -806,14 +805,7 @@ pub fn updateFunc(
806 &code_buffer,805 &code_buffer,
807 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,806 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
808 );807 );
809808 const code = code_buffer.items;
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 };
817809
818 const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);810 const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);
819 const old_rva, const old_alignment = blk: {811 const old_rva, const old_alignment = blk: {
...@@ -914,7 +906,7 @@ pub fn updateNav(...@@ -914,7 +906,7 @@ pub fn updateNav(
914 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;906 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
915 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();907 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
916908
917 const res = try codegen.generateSymbol(909 try codegen.generateSymbol(
918 &macho_file.base,910 &macho_file.base,
919 pt,911 pt,
920 zcu.navSrcLoc(nav_index),912 zcu.navSrcLoc(nav_index),
...@@ -922,14 +914,8 @@ pub fn updateNav(...@@ -922,14 +914,8 @@ pub fn updateNav(
922 &code_buffer,914 &code_buffer,
923 .{ .atom_index = sym_index },915 .{ .atom_index = sym_index },
924 );916 );
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 };
933 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);919 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
934 if (isThreadlocal(macho_file, nav_index))920 if (isThreadlocal(macho_file, nav_index))
935 try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)921 try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)
...@@ -1221,7 +1207,7 @@ fn lowerConst(...@@ -1221,7 +1207,7 @@ fn lowerConst(
1221 const name_str = try self.addString(gpa, name);1207 const name_str = try self.addString(gpa, name);
1222 const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);1208 const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
12231209
1224 const res = try codegen.generateSymbol(1210 try codegen.generateSymbol(
1225 &macho_file.base,1211 &macho_file.base,
1226 pt,1212 pt,
1227 src_loc,1213 src_loc,
...@@ -1229,10 +1215,7 @@ fn lowerConst(...@@ -1229,10 +1215,7 @@ fn lowerConst(
1229 &code_buffer,1215 &code_buffer,
1230 .{ .atom_index = sym_index },1216 .{ .atom_index = sym_index },
1231 );1217 );
1232 const code = switch (res) {1218 const code = code_buffer.items;
1233 .ok => code_buffer.items,
1234 .fail => |em| return .{ .fail = em },
1235 };
12361219
1237 const sym = &self.symbols.items[sym_index];1220 const sym = &self.symbols.items[sym_index];
1238 sym.out_n_sect = output_section_index;1221 sym.out_n_sect = output_section_index;
...@@ -1367,7 +1350,6 @@ fn updateLazySymbol(...@@ -1367,7 +1350,6 @@ fn updateLazySymbol(
1367) !void {1350) !void {
1368 const zcu = pt.zcu;1351 const zcu = pt.zcu;
1369 const gpa = zcu.gpa;1352 const gpa = zcu.gpa;
1370 const diags = &macho_file.base.comp.link_diags;
13711353
1372 var required_alignment: Atom.Alignment = .none;1354 var required_alignment: Atom.Alignment = .none;
1373 var code_buffer = std.ArrayList(u8).init(gpa);1355 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1383,7 +1365,7 @@ fn updateLazySymbol(...@@ -1383,7 +1365,7 @@ fn updateLazySymbol(
1383 };1365 };
13841366
1385 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;1367 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1386 const res = codegen.generateLazySymbol(1368 try codegen.generateLazySymbol(
1387 &macho_file.base,1369 &macho_file.base,
1388 pt,1370 pt,
1389 src,1371 src,
...@@ -1392,15 +1374,8 @@ fn updateLazySymbol(...@@ -1392,15 +1374,8 @@ fn updateLazySymbol(
1392 &code_buffer,1374 &code_buffer,
1393 .none,1375 .none,
1394 .{ .atom_index = symbol_index },1376 .{ .atom_index = symbol_index },
1395 ) catch |err| switch (err) {1377 );
1396 error.CodegenFail => return error.LinkFailure,1378 const code = code_buffer.items;
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 };
14041379
1405 const output_section_index = switch (lazy_sym.kind) {1380 const output_section_index = switch (lazy_sym.kind) {
1406 .code => macho_file.zig_text_sect_index.?,1381 .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...@@ -465,7 +465,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
465 var code_buffer = std.ArrayList(u8).init(gpa);465 var code_buffer = std.ArrayList(u8).init(gpa);
466 defer code_buffer.deinit();466 defer code_buffer.deinit();
467 // TODO we need the symbol index for symbol in the table of locals for the containing atom467 // 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(
469 &self.base,469 &self.base,
470 pt,470 pt,
471 zcu.navSrcLoc(nav_index),471 zcu.navSrcLoc(nav_index),
...@@ -473,10 +473,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde...@@ -473,10 +473,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
473 &code_buffer,473 &code_buffer,
474 .{ .atom_index = @intCast(atom_idx) },474 .{ .atom_index = @intCast(atom_idx) },
475 );475 );
476 const code = switch (res) {476 const code = code_buffer.items;
477 .ok => code_buffer.items,
478 .fail => |em| return zcu.failed_codegen.put(gpa, nav_index, em),
479 };
480 try self.data_nav_table.ensureUnusedCapacity(gpa, 1);477 try self.data_nav_table.ensureUnusedCapacity(gpa, 1);
481 const duped_code = try gpa.dupe(u8, code);478 const duped_code = try gpa.dupe(u8, code);
482 self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } };479 self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } };
...@@ -1081,7 +1078,7 @@ fn updateLazySymbolAtom(...@@ -1081,7 +1078,7 @@ fn updateLazySymbolAtom(
10811078
1082 // generate the code1079 // generate the code
1083 const src = Type.fromInterned(sym.ty).srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;1080 const src = Type.fromInterned(sym.ty).srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;
1084 const res = codegen.generateLazySymbol(1081 codegen.generateLazySymbol(
1085 &self.base,1082 &self.base,
1086 pt,1083 pt,
1087 src,1084 src,
...@@ -1095,10 +1092,7 @@ fn updateLazySymbolAtom(...@@ -1095,10 +1092,7 @@ fn updateLazySymbolAtom(
1095 error.CodegenFail => return error.LinkFailure,1092 error.CodegenFail => return error.LinkFailure,
1096 error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}),1093 error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}),
1097 };1094 };
1098 const code = switch (res) {1095 const code = code_buffer.items;
1099 .ok => code_buffer.items,
1100 .fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}),
1101 };
1102 // duped_code is freed when the atom is freed1096 // duped_code is freed when the atom is freed
1103 const duped_code = try gpa.dupe(u8, code);1097 const duped_code = try gpa.dupe(u8, code);
1104 errdefer gpa.free(duped_code);1098 errdefer gpa.free(duped_code);
...@@ -1408,11 +1402,8 @@ pub fn lowerUav(...@@ -1408,11 +1402,8 @@ pub fn lowerUav(
1408 gop.value_ptr.* = index;1402 gop.value_ptr.* = index;
1409 // we need to free name latex1403 // we need to free name latex
1410 var code_buffer = std.ArrayList(u8).init(gpa);1404 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 });1405 try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
1412 const code = switch (res) {1406 const code = code_buffer.items;
1413 .ok => code_buffer.items,
1414 .fail => |em| return .{ .fail = em },
1415 };
1416 const atom_ptr = self.getAtomPtr(index);1407 const atom_ptr = self.getAtomPtr(index);
1417 atom_ptr.* = .{1408 atom_ptr.* = .{
1418 .type = .d,1409 .type = .d,