mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
rework error handling in the backends
This commit is contained in:
parent
77accf597d
commit
9bf715de74
40
src/Zcu.zig
40
src/Zcu.zig
@ -4072,15 +4072,53 @@ pub fn navValIsConst(zcu: *const Zcu, val: InternPool.Index) bool {
|
||||
};
|
||||
}
|
||||
|
||||
pub const CodegenFailError = error{
|
||||
/// Indicates the error message has been already stored at `Zcu.failed_codegen`.
|
||||
CodegenFail,
|
||||
OutOfMemory,
|
||||
};
|
||||
|
||||
pub fn codegenFail(
|
||||
zcu: *Zcu,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) error{ CodegenFail, OutOfMemory } {
|
||||
) CodegenFailError {
|
||||
const gpa = zcu.gpa;
|
||||
try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
|
||||
const msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(nav_index), format, args);
|
||||
zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, msg);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg) CodegenFailError {
|
||||
const gpa = zcu.gpa;
|
||||
{
|
||||
errdefer msg.deinit(gpa);
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg);
|
||||
}
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
pub fn codegenFailType(
|
||||
zcu: *Zcu,
|
||||
ty_index: InternPool.Index,
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) CodegenFailError {
|
||||
const gpa = zcu.gpa;
|
||||
try zcu.failed_types.ensureUnusedCapacity(gpa, 1);
|
||||
const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args);
|
||||
zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) CodegenFailError {
|
||||
const gpa = zcu.gpa;
|
||||
{
|
||||
errdefer msg.deinit(gpa);
|
||||
try zcu.failed_types.ensureUnusedCapacity(gpa, 1);
|
||||
}
|
||||
zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
@ -1726,7 +1726,6 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
|
||||
error.LinkFailure => assert(comp.link_diags.hasErrors()),
|
||||
error.Overflow => {
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
@ -3112,7 +3111,6 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error
|
||||
lf.updateNav(pt, nav_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
|
||||
error.LinkFailure => assert(comp.link_diags.hasErrors()),
|
||||
error.Overflow => {
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
@ -3139,7 +3137,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{
|
||||
const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
|
||||
defer codegen_prog_node.end();
|
||||
|
||||
if (zcu.failed_types.fetchSwapRemove(ty)) |entry| entry.deinit();
|
||||
if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(gpa);
|
||||
|
||||
if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {
|
||||
// This type failed to resolve. This is a transitive failure.
|
||||
@ -3148,12 +3146,7 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) error{
|
||||
|
||||
if (comp.bin_file) |lf| lf.updateContainerType(pt, ty) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
zcu.typeSrcLoc(ty),
|
||||
"failed to update container type: {s}",
|
||||
.{@errorName(e)},
|
||||
)),
|
||||
error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,6 @@ const build_options = @import("build_options");
|
||||
const Alignment = InternPool.Alignment;
|
||||
|
||||
const CodeGenError = codegen.CodeGenError;
|
||||
const Result = codegen.Result;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
const abi = @import("abi.zig");
|
||||
@ -51,7 +50,6 @@ debug_output: link.File.DebugInfoOutput,
|
||||
target: *const std.Target,
|
||||
func_index: InternPool.Index,
|
||||
owner_nav: InternPool.Nav.Index,
|
||||
err_msg: ?*ErrorMsg,
|
||||
args: []MCValue,
|
||||
ret_mcv: MCValue,
|
||||
fn_type: Type,
|
||||
@ -167,7 +165,7 @@ const DbgInfoReloc = struct {
|
||||
name: [:0]const u8,
|
||||
mcv: MCValue,
|
||||
|
||||
fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
|
||||
fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
switch (reloc.tag) {
|
||||
.arg,
|
||||
.dbg_arg_inline,
|
||||
@ -181,7 +179,7 @@ const DbgInfoReloc = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
|
||||
fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
switch (function.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
|
||||
@ -209,7 +207,7 @@ const DbgInfoReloc = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
|
||||
fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
switch (function.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
|
||||
@ -327,7 +325,7 @@ pub fn generate(
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const func = zcu.funcInfo(func_index);
|
||||
@ -353,7 +351,6 @@ pub fn generate(
|
||||
.bin_file = lf,
|
||||
.func_index = func_index,
|
||||
.owner_nav = func.owner_nav,
|
||||
.err_msg = null,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
|
||||
.fn_type = fn_type,
|
||||
@ -370,10 +367,7 @@ pub fn generate(
|
||||
defer function.dbg_info_relocs.deinit(gpa);
|
||||
|
||||
var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
};
|
||||
defer call_info.deinit(&function);
|
||||
@ -384,15 +378,14 @@ pub fn generate(
|
||||
function.max_end_stack = call_info.stack_byte_count;
|
||||
|
||||
function.gen() catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
for (function.dbg_info_relocs.items) |reloc| {
|
||||
try reloc.genDbgInfo(function);
|
||||
reloc.genDbgInfo(function) catch |err|
|
||||
return function.fail("failed to generate debug info: {s}", .{@errorName(err)});
|
||||
}
|
||||
|
||||
var mir: Mir = .{
|
||||
@ -417,15 +410,9 @@ pub fn generate(
|
||||
defer emit.deinit();
|
||||
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.EmitFail => return Result{ .fail = emit.err_msg.? },
|
||||
error.EmitFail => return function.failMsg(emit.err_msg.?),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
}
|
||||
|
||||
fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
|
||||
@ -567,7 +554,7 @@ fn gen(self: *Self) !void {
|
||||
.data = .{ .rr_imm12_sh = .{ .rd = .sp, .rn = .sp, .imm12 = size } },
|
||||
});
|
||||
} else {
|
||||
return self.failSymbol("TODO AArch64: allow larger stacks", .{});
|
||||
@panic("TODO AArch64: allow larger stacks");
|
||||
}
|
||||
|
||||
_ = try self.addInst(.{
|
||||
@ -6191,10 +6178,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
|
||||
.load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
|
||||
.load_symbol, .load_tlv, .lea_symbol, .lea_direct => unreachable, // TODO
|
||||
},
|
||||
.fail => |msg| {
|
||||
self.err_msg = msg;
|
||||
return error.CodegenFail;
|
||||
},
|
||||
.fail => |msg| return self.failMsg(msg),
|
||||
};
|
||||
return mcv;
|
||||
}
|
||||
@ -6355,18 +6339,14 @@ fn wantSafety(self: *Self) bool {
|
||||
};
|
||||
}
|
||||
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
return self.pt.zcu.codegenFail(self.owner_nav, format, args);
|
||||
}
|
||||
|
||||
fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(self.err_msg == null);
|
||||
self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
return self.pt.zcu.codegenFailMsg(self.owner_nav, msg);
|
||||
}
|
||||
|
||||
fn parseRegName(name: []const u8) ?Register {
|
||||
|
||||
@ -23,7 +23,6 @@ const log = std.log.scoped(.codegen);
|
||||
const build_options = @import("build_options");
|
||||
const Alignment = InternPool.Alignment;
|
||||
|
||||
const Result = codegen.Result;
|
||||
const CodeGenError = codegen.CodeGenError;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
@ -245,7 +244,7 @@ const DbgInfoReloc = struct {
|
||||
name: [:0]const u8,
|
||||
mcv: MCValue,
|
||||
|
||||
fn genDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
|
||||
fn genDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
switch (reloc.tag) {
|
||||
.arg,
|
||||
.dbg_arg_inline,
|
||||
@ -259,7 +258,7 @@ const DbgInfoReloc = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
|
||||
fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
switch (function.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
|
||||
@ -287,7 +286,7 @@ const DbgInfoReloc = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) CodeGenError!void {
|
||||
fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
switch (function.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
const loc: link.File.Dwarf.Loc = switch (reloc.mcv) {
|
||||
@ -335,7 +334,7 @@ pub fn generate(
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const func = zcu.funcInfo(func_index);
|
||||
@ -377,10 +376,7 @@ pub fn generate(
|
||||
defer function.dbg_info_relocs.deinit(gpa);
|
||||
|
||||
var call_info = function.resolveCallingConventionValues(func_ty) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
};
|
||||
defer call_info.deinit(&function);
|
||||
@ -391,15 +387,14 @@ pub fn generate(
|
||||
function.max_end_stack = call_info.stack_byte_count;
|
||||
|
||||
function.gen() catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
for (function.dbg_info_relocs.items) |reloc| {
|
||||
try reloc.genDbgInfo(function);
|
||||
reloc.genDbgInfo(function) catch |err|
|
||||
return function.fail("failed to generate debug info: {s}", .{@errorName(err)});
|
||||
}
|
||||
|
||||
var mir = Mir{
|
||||
@ -424,15 +419,9 @@ pub fn generate(
|
||||
defer emit.deinit();
|
||||
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.EmitFail => return Result{ .fail = emit.err_msg.? },
|
||||
error.EmitFail => return function.failMsg(emit.err_msg.?),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
}
|
||||
|
||||
fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
|
||||
@ -6310,20 +6299,19 @@ fn wantSafety(self: *Self) bool {
|
||||
};
|
||||
}
|
||||
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(self.err_msg == null);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
const zcu = self.pt.zcu;
|
||||
const func = zcu.funcInfo(self.func_index);
|
||||
const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
|
||||
return zcu.codegenFailMsg(func.owner_nav, msg);
|
||||
}
|
||||
|
||||
fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(self.err_msg == null);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
const zcu = self.pt.zcu;
|
||||
const func = zcu.funcInfo(self.func_index);
|
||||
return zcu.codegenFailMsg(func.owner_nav, msg);
|
||||
}
|
||||
|
||||
fn parseRegName(name: []const u8) ?Register {
|
||||
|
||||
@ -32,7 +32,6 @@ const wip_mir_log = std.log.scoped(.wip_mir);
|
||||
const Alignment = InternPool.Alignment;
|
||||
|
||||
const CodeGenError = codegen.CodeGenError;
|
||||
const Result = codegen.Result;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
const abi = @import("abi.zig");
|
||||
@ -62,7 +61,6 @@ gpa: Allocator,
|
||||
mod: *Package.Module,
|
||||
target: *const std.Target,
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
err_msg: ?*ErrorMsg,
|
||||
args: []MCValue,
|
||||
ret_mcv: InstTracking,
|
||||
fn_type: Type,
|
||||
@ -761,7 +759,7 @@ pub fn generate(
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const comp = zcu.comp;
|
||||
const gpa = zcu.gpa;
|
||||
@ -788,7 +786,6 @@ pub fn generate(
|
||||
.target = &mod.resolved_target.result,
|
||||
.debug_output = debug_output,
|
||||
.owner = .{ .nav_index = func.owner_nav },
|
||||
.err_msg = null,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
|
||||
.fn_type = fn_type,
|
||||
@ -829,10 +826,7 @@ pub fn generate(
|
||||
|
||||
const fn_info = zcu.typeToFunc(fn_type).?;
|
||||
var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@ -861,10 +855,8 @@ pub fn generate(
|
||||
}));
|
||||
|
||||
function.gen() catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@ -895,28 +887,10 @@ pub fn generate(
|
||||
defer emit.deinit();
|
||||
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
|
||||
error.InvalidInstruction => |e| {
|
||||
const msg = switch (e) {
|
||||
error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
|
||||
};
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"{s} This is a bug in the Zig compiler.",
|
||||
.{msg},
|
||||
),
|
||||
};
|
||||
},
|
||||
error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
|
||||
error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generateLazy(
|
||||
@ -926,7 +900,7 @@ pub fn generateLazy(
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const comp = bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
const mod = comp.root_mod;
|
||||
@ -941,7 +915,6 @@ pub fn generateLazy(
|
||||
.target = &mod.resolved_target.result,
|
||||
.debug_output = debug_output,
|
||||
.owner = .{ .lazy_sym = lazy_sym },
|
||||
.err_msg = null,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
|
||||
.fn_type = undefined,
|
||||
@ -957,10 +930,8 @@ pub fn generateLazy(
|
||||
defer function.mir_instructions.deinit(gpa);
|
||||
|
||||
function.genLazy(lazy_sym) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@ -991,28 +962,10 @@ pub fn generateLazy(
|
||||
defer emit.deinit();
|
||||
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
|
||||
error.InvalidInstruction => |e| {
|
||||
const msg = switch (e) {
|
||||
error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
|
||||
};
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"{s} This is a bug in the Zig compiler.",
|
||||
.{msg},
|
||||
),
|
||||
};
|
||||
},
|
||||
error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
|
||||
error.InvalidInstruction => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
}
|
||||
|
||||
const FormatWipMirData = struct {
|
||||
@ -4758,19 +4711,19 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
|
||||
return func.fail("TODO implement codegen airFieldParentPtr", .{});
|
||||
}
|
||||
|
||||
fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
fn genArgDbgInfo(func: *const Func, inst: Air.Inst.Index, mcv: MCValue) InnerError!void {
|
||||
const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
|
||||
const ty = arg.ty.toType();
|
||||
if (arg.name == .none) return;
|
||||
|
||||
switch (func.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
.register => |reg| try dw.genLocalDebugInfo(
|
||||
.register => |reg| dw.genLocalDebugInfo(
|
||||
.local_arg,
|
||||
arg.name.toSlice(func.air),
|
||||
ty,
|
||||
.{ .reg = reg.dwarfNum() },
|
||||
),
|
||||
) catch |err| return func.fail("failed to generate debug info: {s}", .{@errorName(err)}),
|
||||
.load_frame => {},
|
||||
else => {},
|
||||
},
|
||||
@ -4779,7 +4732,7 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn airArg(func: *Func, inst: Air.Inst.Index) !void {
|
||||
fn airArg(func: *Func, inst: Air.Inst.Index) InnerError!void {
|
||||
var arg_index = func.arg_index;
|
||||
|
||||
// we skip over args that have no bits
|
||||
@ -5255,7 +5208,7 @@ fn airDbgInlineBlock(func: *Func, inst: Air.Inst.Index) !void {
|
||||
try func.lowerBlock(inst, @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]));
|
||||
}
|
||||
|
||||
fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
|
||||
fn airDbgVar(func: *Func, inst: Air.Inst.Index) InnerError!void {
|
||||
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const operand = pl_op.operand;
|
||||
const ty = func.typeOf(operand);
|
||||
@ -5263,7 +5216,8 @@ fn airDbgVar(func: *Func, inst: Air.Inst.Index) !void {
|
||||
const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
|
||||
|
||||
const tag = func.air.instructions.items(.tag)[@intFromEnum(inst)];
|
||||
try func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air));
|
||||
func.genVarDbgInfo(tag, ty, mcv, name.toSlice(func.air)) catch |err|
|
||||
return func.fail("failed to generate variable debug info: {s}", .{@errorName(err)});
|
||||
|
||||
return func.finishAir(inst, .unreach, .{ operand, .none, .none });
|
||||
}
|
||||
@ -8236,10 +8190,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
|
||||
return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)});
|
||||
},
|
||||
},
|
||||
.fail => |msg| {
|
||||
func.err_msg = msg;
|
||||
return error.CodegenFail;
|
||||
},
|
||||
.fail => |msg| return func.failMsg(msg),
|
||||
};
|
||||
return mcv;
|
||||
}
|
||||
@ -8427,17 +8378,23 @@ fn wantSafety(func: *Func) bool {
|
||||
};
|
||||
}
|
||||
|
||||
fn fail(func: *Func, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(func.err_msg == null);
|
||||
func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args);
|
||||
const zcu = func.pt.zcu;
|
||||
switch (func.owner) {
|
||||
.nav_index => |i| return zcu.codegenFail(i, format, args),
|
||||
.lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),
|
||||
}
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn failSymbol(func: *Func, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(func.err_msg == null);
|
||||
func.err_msg = try ErrorMsg.create(func.gpa, func.src_loc, format, args);
|
||||
const zcu = func.pt.zcu;
|
||||
switch (func.owner) {
|
||||
.nav_index => |i| return zcu.codegenFailMsg(i, msg),
|
||||
.lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
|
||||
}
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ const Emit = @import("Emit.zig");
|
||||
const Liveness = @import("../../Liveness.zig");
|
||||
const Type = @import("../../Type.zig");
|
||||
const CodeGenError = codegen.CodeGenError;
|
||||
const Result = @import("../../codegen.zig").Result;
|
||||
const Endian = std.builtin.Endian;
|
||||
const Alignment = InternPool.Alignment;
|
||||
|
||||
@ -268,7 +267,7 @@ pub fn generate(
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const func = zcu.funcInfo(func_index);
|
||||
@ -310,10 +309,7 @@ pub fn generate(
|
||||
defer function.exitlude_jump_relocs.deinit(gpa);
|
||||
|
||||
var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
};
|
||||
defer call_info.deinit(&function);
|
||||
@ -324,10 +320,8 @@ pub fn generate(
|
||||
function.max_end_stack = call_info.stack_byte_count;
|
||||
|
||||
function.gen() catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@ -351,15 +345,9 @@ pub fn generate(
|
||||
defer emit.deinit();
|
||||
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.EmitFail => return Result{ .fail = emit.err_msg.? },
|
||||
error.EmitFail => return function.failMsg(emit.err_msg.?),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
}
|
||||
|
||||
fn gen(self: *Self) !void {
|
||||
@ -1014,7 +1002,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return bt.finishAir(result);
|
||||
}
|
||||
|
||||
fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
|
||||
const pt = self.pt;
|
||||
const zcu = pt.zcu;
|
||||
const arg_index = self.arg_index;
|
||||
@ -1036,7 +1024,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
}
|
||||
};
|
||||
|
||||
try self.genArgDbgInfo(inst, mcv);
|
||||
self.genArgDbgInfo(inst, mcv) catch |err|
|
||||
return self.fail("failed to generate debug info for parameter: {s}", .{@errorName(err)});
|
||||
|
||||
if (self.liveness.isUnused(inst))
|
||||
return self.finishAirBookkeeping();
|
||||
@ -3511,12 +3500,19 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
|
||||
}
|
||||
}
|
||||
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(self.err_msg == null);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
return error.CodegenFail;
|
||||
const zcu = self.pt.zcu;
|
||||
const func = zcu.funcInfo(self.func_index);
|
||||
const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
|
||||
return zcu.codegenFailMsg(func.owner_nav, msg);
|
||||
}
|
||||
|
||||
fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
const zcu = self.pt.zcu;
|
||||
const func = zcu.funcInfo(self.func_index);
|
||||
return zcu.codegenFailMsg(func.owner_nav, msg);
|
||||
}
|
||||
|
||||
/// Called when there are no operands, and the instruction is always unreferenced.
|
||||
|
||||
@ -19,7 +19,6 @@ const Allocator = mem.Allocator;
|
||||
const CodeGenError = codegen.CodeGenError;
|
||||
const Compilation = @import("../../Compilation.zig");
|
||||
const ErrorMsg = Zcu.ErrorMsg;
|
||||
const Result = codegen.Result;
|
||||
const Emit = @import("Emit.zig");
|
||||
const Liveness = @import("../../Liveness.zig");
|
||||
const Lower = @import("Lower.zig");
|
||||
@ -59,7 +58,6 @@ target: *const std.Target,
|
||||
owner: Owner,
|
||||
inline_func: InternPool.Index,
|
||||
mod: *Package.Module,
|
||||
err_msg: ?*ErrorMsg,
|
||||
arg_index: u32,
|
||||
args: []MCValue,
|
||||
va_info: union {
|
||||
@ -821,7 +819,7 @@ pub fn generate(
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const comp = zcu.comp;
|
||||
const gpa = zcu.gpa;
|
||||
@ -841,7 +839,6 @@ pub fn generate(
|
||||
.debug_output = debug_output,
|
||||
.owner = .{ .nav_index = func.owner_nav },
|
||||
.inline_func = func_index,
|
||||
.err_msg = null,
|
||||
.arg_index = undefined,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.va_info = undefined, // populated after `resolveCallingConventionValues`
|
||||
@ -881,15 +878,7 @@ pub fn generate(
|
||||
const fn_info = zcu.typeToFunc(fn_type).?;
|
||||
const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*);
|
||||
var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"CodeGen ran out of registers. This is a bug in the Zig compiler.",
|
||||
.{},
|
||||
),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
};
|
||||
defer call_info.deinit(&function);
|
||||
@ -926,10 +915,8 @@ pub fn generate(
|
||||
};
|
||||
|
||||
function.gen() catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@ -953,10 +940,7 @@ pub fn generate(
|
||||
.pic = mod.pic,
|
||||
},
|
||||
.atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
},
|
||||
.debug_output = debug_output,
|
||||
@ -974,29 +958,11 @@ pub fn generate(
|
||||
};
|
||||
defer emit.deinit();
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
|
||||
error.InvalidInstruction, error.CannotEncode => |e| {
|
||||
const msg = switch (e) {
|
||||
error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
|
||||
error.CannotEncode => "CodeGen failed to encode the instruction.",
|
||||
};
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"{s} This is a bug in the Zig compiler.",
|
||||
.{msg},
|
||||
),
|
||||
};
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
error.InvalidInstruction, error.CannotEncode => |e| return function.fail("emit MIR failed: {s} (Zig compiler bug)", .{@errorName(e)}),
|
||||
else => |e| return function.fail("emit MIR failed: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn generateLazy(
|
||||
@ -1006,7 +972,7 @@ pub fn generateLazy(
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const comp = bin_file.comp;
|
||||
const gpa = comp.gpa;
|
||||
// This function is for generating global code, so we use the root module.
|
||||
@ -1022,7 +988,6 @@ pub fn generateLazy(
|
||||
.debug_output = debug_output,
|
||||
.owner = .{ .lazy_sym = lazy_sym },
|
||||
.inline_func = undefined,
|
||||
.err_msg = null,
|
||||
.arg_index = undefined,
|
||||
.args = undefined,
|
||||
.va_info = undefined,
|
||||
@ -1038,10 +1003,8 @@ pub fn generateLazy(
|
||||
}
|
||||
|
||||
function.genLazy(lazy_sym) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
@ -1065,10 +1028,7 @@ pub fn generateLazy(
|
||||
.pic = mod.pic,
|
||||
},
|
||||
.atom_index = function.owner.getSymbolIndex(&function) catch |err| switch (err) {
|
||||
error.CodegenFail => return Result{ .fail = function.err_msg.? },
|
||||
error.OutOfRegisters => return Result{
|
||||
.fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
|
||||
},
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return e,
|
||||
},
|
||||
.debug_output = debug_output,
|
||||
@ -1078,29 +1038,11 @@ pub fn generateLazy(
|
||||
};
|
||||
defer emit.deinit();
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
|
||||
error.InvalidInstruction, error.CannotEncode => |e| {
|
||||
const msg = switch (e) {
|
||||
error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
|
||||
error.CannotEncode => "CodeGen failed to encode the instruction.",
|
||||
};
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"{s} This is a bug in the Zig compiler.",
|
||||
.{msg},
|
||||
),
|
||||
};
|
||||
},
|
||||
else => |e| return e,
|
||||
error.LowerFail, error.EmitFail => return function.failMsg(emit.lower.err_msg.?),
|
||||
error.InvalidInstruction => return function.fail("failed to find a viable x86 instruction (Zig compiler bug)", .{}),
|
||||
error.CannotEncode => return function.fail("failed to find encode x86 instruction (Zig compiler bug)", .{}),
|
||||
else => |e| return function.fail("failed to emit MIR: {s}", .{@errorName(e)}),
|
||||
};
|
||||
|
||||
if (function.err_msg) |em| {
|
||||
return Result{ .fail = em };
|
||||
} else {
|
||||
return Result.ok;
|
||||
}
|
||||
}
|
||||
|
||||
const FormatNavData = struct {
|
||||
@ -19276,10 +19218,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
|
||||
.load_got => |sym_index| .{ .lea_got = sym_index },
|
||||
.load_tlv => |sym_index| .{ .lea_tlv = sym_index },
|
||||
},
|
||||
.fail => |msg| {
|
||||
self.err_msg = msg;
|
||||
return error.CodegenFail;
|
||||
},
|
||||
.fail => |msg| return self.failMsg(msg),
|
||||
};
|
||||
}
|
||||
|
||||
@ -19592,11 +19531,23 @@ fn resolveCallingConventionValues(
|
||||
return result;
|
||||
}
|
||||
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
assert(self.err_msg == null);
|
||||
const gpa = self.gpa;
|
||||
self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
|
||||
const zcu = self.pt.zcu;
|
||||
switch (self.owner) {
|
||||
.nav_index => |i| return zcu.codegenFail(i, format, args),
|
||||
.lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),
|
||||
}
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
|
||||
@branchHint(.cold);
|
||||
const zcu = self.pt.zcu;
|
||||
switch (self.owner) {
|
||||
.nav_index => |i| return zcu.codegenFailMsg(i, msg),
|
||||
.lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
|
||||
}
|
||||
return error.CodegenFail;
|
||||
}
|
||||
|
||||
|
||||
169
src/codegen.zig
169
src/codegen.zig
@ -24,13 +24,6 @@ const Zir = std.zig.Zir;
|
||||
const Alignment = InternPool.Alignment;
|
||||
const dev = @import("dev.zig");
|
||||
|
||||
pub const Result = union(enum) {
|
||||
/// The `code` parameter passed to `generateSymbol` has the value.
|
||||
ok,
|
||||
/// There was a codegen error.
|
||||
fail: *ErrorMsg,
|
||||
};
|
||||
|
||||
pub const CodeGenError = error{
|
||||
OutOfMemory,
|
||||
/// Compiler was asked to operate on a number larger than supported.
|
||||
@ -64,7 +57,7 @@ pub fn generateFunction(
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const func = zcu.funcInfo(func_index);
|
||||
const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;
|
||||
@ -89,7 +82,7 @@ pub fn generateLazyFunction(
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool);
|
||||
const target = zcu.fileByIndex(file).mod.resolved_target.result;
|
||||
@ -120,17 +113,17 @@ pub fn generateLazySymbol(
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
) CodeGenError!Result {
|
||||
) CodeGenError!void {
|
||||
_ = reloc_parent;
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const comp = bin_file.comp;
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const endian = target.cpu.arch.endian();
|
||||
const gpa = comp.gpa;
|
||||
|
||||
log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
|
||||
@tagName(lazy_sym.kind),
|
||||
@ -161,26 +154,29 @@ pub fn generateLazySymbol(
|
||||
string_index += @intCast(err_name.len + 1);
|
||||
}
|
||||
mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
|
||||
return .ok;
|
||||
} else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") {
|
||||
} else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") {
|
||||
alignment.* = .@"1";
|
||||
const enum_ty = Type.fromInterned(lazy_sym.ty);
|
||||
const tag_names = enum_ty.enumFields(pt.zcu);
|
||||
const tag_names = enum_ty.enumFields(zcu);
|
||||
for (0..tag_names.len) |tag_index| {
|
||||
const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
|
||||
try code.ensureUnusedCapacity(tag_name.len + 1);
|
||||
code.appendSliceAssumeCapacity(tag_name);
|
||||
code.appendAssumeCapacity(0);
|
||||
}
|
||||
return .ok;
|
||||
} else return .{ .fail = try .create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"TODO implement generateLazySymbol for {s} {}",
|
||||
.{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
|
||||
) };
|
||||
} else {
|
||||
return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {}", .{
|
||||
@tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub const GenerateSymbolError = error{
|
||||
OutOfMemory,
|
||||
/// Compiler was asked to operate on a number larger than supported.
|
||||
Overflow,
|
||||
};
|
||||
|
||||
pub fn generateSymbol(
|
||||
bin_file: *link.File,
|
||||
pt: Zcu.PerThread,
|
||||
@ -188,7 +184,7 @@ pub fn generateSymbol(
|
||||
val: Value,
|
||||
code: *std.ArrayList(u8),
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
) CodeGenError!Result {
|
||||
) GenerateSymbolError!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
@ -204,7 +200,7 @@ pub fn generateSymbol(
|
||||
if (val.isUndefDeep(zcu)) {
|
||||
const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
|
||||
try code.appendNTimes(0xaa, abi_size);
|
||||
return .ok;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ip.indexToKey(val.toIntern())) {
|
||||
@ -266,7 +262,7 @@ pub fn generateSymbol(
|
||||
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
|
||||
try code.writer().writeInt(u16, err_val, endian);
|
||||
return .ok;
|
||||
return;
|
||||
}
|
||||
|
||||
const payload_align = payload_ty.abiAlignment(zcu);
|
||||
@ -281,13 +277,10 @@ pub fn generateSymbol(
|
||||
// emit payload part of the error union
|
||||
{
|
||||
const begin = code.items.len;
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
|
||||
.err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
|
||||
.payload => |payload| payload,
|
||||
}), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
}), code, reloc_parent);
|
||||
const unpadded_end = code.items.len - begin;
|
||||
const padded_end = abi_align.forward(unpadded_end);
|
||||
const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
|
||||
@ -312,10 +305,7 @@ pub fn generateSymbol(
|
||||
},
|
||||
.enum_tag => |enum_tag| {
|
||||
const int_tag_ty = ty.intTagType(zcu);
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent);
|
||||
},
|
||||
.float => |float| switch (float.storage) {
|
||||
.f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)),
|
||||
@ -328,19 +318,10 @@ pub fn generateSymbol(
|
||||
},
|
||||
.f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
|
||||
},
|
||||
.ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
},
|
||||
.ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
|
||||
.slice => |slice| {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent);
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent);
|
||||
},
|
||||
.opt => {
|
||||
const payload_type = ty.optionalChild(zcu);
|
||||
@ -349,10 +330,7 @@ pub fn generateSymbol(
|
||||
|
||||
if (ty.optionalReprIsPayload(zcu)) {
|
||||
if (payload_val) |value| {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
|
||||
} else {
|
||||
try code.appendNTimes(0, abi_size);
|
||||
}
|
||||
@ -362,10 +340,7 @@ pub fn generateSymbol(
|
||||
const value = payload_val orelse Value.fromInterned(try pt.intern(.{
|
||||
.undef = payload_type.toIntern(),
|
||||
}));
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
|
||||
}
|
||||
try code.writer().writeByte(@intFromBool(payload_val != null));
|
||||
try code.appendNTimes(0, padding);
|
||||
@ -377,17 +352,14 @@ pub fn generateSymbol(
|
||||
.elems, .repeated_elem => {
|
||||
var index: u64 = 0;
|
||||
while (index < array_type.lenIncludingSentinel()) : (index += 1) {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
|
||||
.bytes => unreachable,
|
||||
.elems => |elems| elems[@intCast(index)],
|
||||
.repeated_elem => |elem| if (index < array_type.len)
|
||||
elem
|
||||
else
|
||||
array_type.sentinel,
|
||||
}), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
}), code, reloc_parent);
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -437,16 +409,13 @@ pub fn generateSymbol(
|
||||
.elems, .repeated_elem => {
|
||||
var index: u64 = 0;
|
||||
while (index < vector_type.len) : (index += 1) {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
|
||||
.bytes => unreachable,
|
||||
.elems => |elems| elems[
|
||||
math.cast(usize, index) orelse return error.Overflow
|
||||
],
|
||||
.repeated_elem => |elem| elem,
|
||||
}), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
}), code, reloc_parent);
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -476,10 +445,7 @@ pub fn generateSymbol(
|
||||
.repeated_elem => |elem| elem,
|
||||
};
|
||||
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
|
||||
const unpadded_field_end = code.items.len - struct_begin;
|
||||
|
||||
// Pad struct members if required
|
||||
@ -518,10 +484,8 @@ pub fn generateSymbol(
|
||||
return error.Overflow;
|
||||
var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
|
||||
defer tmp_list.deinit();
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent)) {
|
||||
.ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items),
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent);
|
||||
@memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items);
|
||||
} else {
|
||||
Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
|
||||
}
|
||||
@ -553,10 +517,7 @@ pub fn generateSymbol(
|
||||
) orelse return error.Overflow;
|
||||
if (padding > 0) try code.appendNTimes(0, padding);
|
||||
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
|
||||
}
|
||||
|
||||
const size = struct_type.sizeUnordered(ip);
|
||||
@ -582,10 +543,7 @@ pub fn generateSymbol(
|
||||
|
||||
// Check if we should store the tag first.
|
||||
if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
|
||||
}
|
||||
|
||||
const union_obj = zcu.typeToUnion(ty).?;
|
||||
@ -595,10 +553,7 @@ pub fn generateSymbol(
|
||||
if (!field_ty.hasRuntimeBits(zcu)) {
|
||||
try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
|
||||
} else {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
|
||||
|
||||
const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
|
||||
if (padding > 0) {
|
||||
@ -606,17 +561,11 @@ pub fn generateSymbol(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
|
||||
}
|
||||
|
||||
if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
|
||||
switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) {
|
||||
.ok => {},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
|
||||
|
||||
if (layout.padding > 0) {
|
||||
try code.appendNTimes(0, layout.padding);
|
||||
@ -625,7 +574,6 @@ pub fn generateSymbol(
|
||||
},
|
||||
.memoized_call => unreachable,
|
||||
}
|
||||
return .ok;
|
||||
}
|
||||
|
||||
fn lowerPtr(
|
||||
@ -636,7 +584,7 @@ fn lowerPtr(
|
||||
code: *std.ArrayList(u8),
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
prev_offset: u64,
|
||||
) CodeGenError!Result {
|
||||
) GenerateSymbolError!void {
|
||||
const zcu = pt.zcu;
|
||||
const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
|
||||
const offset: u64 = prev_offset + ptr.byte_offset;
|
||||
@ -689,7 +637,7 @@ fn lowerUavRef(
|
||||
code: *std.ArrayList(u8),
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
offset: u64,
|
||||
) CodeGenError!Result {
|
||||
) GenerateSymbolError!void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const ip = &zcu.intern_pool;
|
||||
@ -702,14 +650,7 @@ fn lowerUavRef(
|
||||
const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
|
||||
if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {
|
||||
try code.appendNTimes(0xaa, ptr_width_bytes);
|
||||
return .ok;
|
||||
}
|
||||
|
||||
const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
|
||||
const res = try lf.lowerUav(pt, uav_val, uav_align, src_loc);
|
||||
switch (res) {
|
||||
.mcv => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
return;
|
||||
}
|
||||
|
||||
switch (lf.tag) {
|
||||
@ -727,11 +668,17 @@ fn lowerUavRef(
|
||||
.pointee = .{ .uav_index = uav.val },
|
||||
});
|
||||
try code.appendNTimes(0, ptr_width_bytes);
|
||||
return .ok;
|
||||
return;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
|
||||
switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) {
|
||||
.mcv => {},
|
||||
.fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}),
|
||||
}
|
||||
|
||||
const vaddr = try lf.getUavVAddr(uav_val, .{
|
||||
.parent = reloc_parent,
|
||||
.offset = code.items.len,
|
||||
@ -744,8 +691,6 @@ fn lowerUavRef(
|
||||
8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
return Result.ok;
|
||||
}
|
||||
|
||||
fn lowerNavRef(
|
||||
@ -756,7 +701,7 @@ fn lowerNavRef(
|
||||
code: *std.ArrayList(u8),
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
offset: u64,
|
||||
) CodeGenError!Result {
|
||||
) GenerateSymbolError!void {
|
||||
_ = src_loc;
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
@ -768,7 +713,7 @@ fn lowerNavRef(
|
||||
const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
|
||||
if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
|
||||
try code.appendNTimes(0xaa, ptr_width_bytes);
|
||||
return Result.ok;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (lf.tag) {
|
||||
@ -786,16 +731,16 @@ fn lowerNavRef(
|
||||
.pointee = .{ .nav_index = nav_index },
|
||||
});
|
||||
try code.appendNTimes(0, ptr_width_bytes);
|
||||
return .ok;
|
||||
return;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const vaddr = try lf.getNavVAddr(pt, nav_index, .{
|
||||
const vaddr = lf.getNavVAddr(pt, nav_index, .{
|
||||
.parent = reloc_parent,
|
||||
.offset = code.items.len,
|
||||
.addend = @intCast(offset),
|
||||
});
|
||||
}) catch @panic("TODO rework getNavVAddr");
|
||||
const endian = target.cpu.arch.endian();
|
||||
switch (ptr_width_bytes) {
|
||||
2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),
|
||||
@ -803,8 +748,6 @@ fn lowerNavRef(
|
||||
8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
return .ok;
|
||||
}
|
||||
|
||||
/// Helper struct to denote that the value is in memory but requires a linker relocation fixup:
|
||||
|
||||
@ -673,7 +673,13 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateNavError!void {
|
||||
pub const UpdateContainerTypeError = error{
|
||||
OutOfMemory,
|
||||
/// `Zcu.failed_types` is already populated with the error message.
|
||||
TypeFailureReported,
|
||||
};
|
||||
|
||||
pub fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {
|
||||
switch (base.tag) {
|
||||
else => {},
|
||||
inline .elf => |tag| {
|
||||
|
||||
@ -754,7 +754,7 @@ fn allocateGlobal(coff: *Coff) !u32 {
|
||||
return index;
|
||||
}
|
||||
|
||||
fn addGotEntry(coff: *Coff, target: SymbolWithLoc) error{ OutOfMemory, LinkFailure }!void {
|
||||
fn addGotEntry(coff: *Coff, target: SymbolWithLoc) !void {
|
||||
const gpa = coff.base.comp.gpa;
|
||||
if (coff.got_table.lookup.contains(target)) return;
|
||||
const got_index = try coff.got_table.allocateEntry(gpa, target);
|
||||
@ -780,7 +780,7 @@ pub fn createAtom(coff: *Coff) !Atom.Index {
|
||||
return atom_index;
|
||||
}
|
||||
|
||||
fn growAtom(coff: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) link.File.UpdateNavError!u32 {
|
||||
fn growAtom(coff: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 {
|
||||
const atom = coff.getAtom(atom_index);
|
||||
const sym = atom.getSymbol(coff);
|
||||
const align_ok = mem.alignBackward(u32, sym.value, alignment) == sym.value;
|
||||
@ -909,12 +909,12 @@ fn writeOffsetTableEntry(coff: *Coff, index: usize) !void {
|
||||
.p32 => {
|
||||
var buf: [4]u8 = undefined;
|
||||
mem.writeInt(u32, &buf, @intCast(entry_value + coff.image_base), .little);
|
||||
try coff.pwriteAll(&buf, file_offset);
|
||||
try coff.base.file.?.pwriteAll(&buf, file_offset);
|
||||
},
|
||||
.p64 => {
|
||||
var buf: [8]u8 = undefined;
|
||||
mem.writeInt(u64, &buf, entry_value + coff.image_base, .little);
|
||||
try coff.pwriteAll(&buf, file_offset);
|
||||
try coff.base.file.?.pwriteAll(&buf, file_offset);
|
||||
},
|
||||
}
|
||||
|
||||
@ -1122,7 +1122,7 @@ pub fn updateFunc(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const res = codegen.generateFunction(
|
||||
codegen.generateFunction(
|
||||
&coff.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -1134,7 +1134,7 @@ pub fn updateFunc(
|
||||
) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| {
|
||||
error.Overflow => |e| {
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -1145,15 +1145,8 @@ pub fn updateFunc(
|
||||
return error.CodegenFail;
|
||||
},
|
||||
};
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
try coff.updateNavCode(pt, nav_index, code, .FUNCTION);
|
||||
try coff.updateNavCode(pt, nav_index, code_buffer.items, .FUNCTION);
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
}
|
||||
@ -1182,16 +1175,13 @@ fn lowerConst(
|
||||
try coff.setSymbolName(sym, name);
|
||||
sym.section_number = @as(coff_util.SectionNumber, @enumFromInt(sect_id + 1));
|
||||
|
||||
const res = try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{
|
||||
try codegen.generateSymbol(&coff.base, pt, src_loc, val, &code_buffer, .{
|
||||
.atom_index = coff.getAtom(atom_index).getSymbolIndex().?,
|
||||
});
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const atom = coff.getAtomPtr(atom_index);
|
||||
atom.size = @as(u32, @intCast(code.len));
|
||||
atom.size = @intCast(code.len);
|
||||
atom.getSymbolPtr(coff).value = try coff.allocateAtom(
|
||||
atom_index,
|
||||
atom.size,
|
||||
@ -1250,7 +1240,7 @@ pub fn updateNav(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const res = try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
&coff.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -1258,15 +1248,8 @@ pub fn updateNav(
|
||||
&code_buffer,
|
||||
.{ .atom_index = atom.getSymbolIndex().? },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
try zcu.failed_codegen.put(gpa, nav_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
try coff.updateNavCode(pt, nav_index, code, .NULL);
|
||||
try coff.updateNavCode(pt, nav_index, code_buffer.items, .NULL);
|
||||
}
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
@ -1278,11 +1261,10 @@ fn updateLazySymbolAtom(
|
||||
sym: link.File.LazySymbol,
|
||||
atom_index: Atom.Index,
|
||||
section_index: u16,
|
||||
) link.File.FlushError!void {
|
||||
) !void {
|
||||
const zcu = pt.zcu;
|
||||
const comp = coff.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const diags = &comp.link_diags;
|
||||
|
||||
var required_alignment: InternPool.Alignment = .none;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
@ -1298,7 +1280,7 @@ fn updateLazySymbolAtom(
|
||||
const local_sym_index = atom.getSymbolIndex().?;
|
||||
|
||||
const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
|
||||
const res = codegen.generateLazySymbol(
|
||||
try codegen.generateLazySymbol(
|
||||
&coff.base,
|
||||
pt,
|
||||
src,
|
||||
@ -1307,14 +1289,8 @@ fn updateLazySymbolAtom(
|
||||
&code_buffer,
|
||||
.none,
|
||||
.{ .atom_index = local_sym_index },
|
||||
) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.LinkFailure,
|
||||
else => |e| return diags.fail("failed to generate lazy symbol: {s}", .{@errorName(e)}),
|
||||
};
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return diags.fail("failed to generate code: {s}", .{em.msg}),
|
||||
};
|
||||
);
|
||||
const code = code_buffer.items;
|
||||
|
||||
const code_len: u32 = @intCast(code.len);
|
||||
const symbol = atom.getSymbolPtr(coff);
|
||||
@ -1438,7 +1414,10 @@ fn updateNavCode(
|
||||
const capacity = atom.capacity(coff);
|
||||
const need_realloc = code.len > capacity or !required_alignment.check(sym.value);
|
||||
if (need_realloc) {
|
||||
const vaddr = try coff.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
|
||||
const vaddr = coff.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return coff.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(e)}),
|
||||
};
|
||||
log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
|
||||
log.debug(" (required alignment 0x{x}", .{required_alignment});
|
||||
|
||||
@ -1446,7 +1425,10 @@ fn updateNavCode(
|
||||
sym.value = vaddr;
|
||||
log.debug(" (updating GOT entry)", .{});
|
||||
const got_entry_index = coff.got_table.lookup.get(.{ .sym_index = sym_index }).?;
|
||||
try coff.writeOffsetTableEntry(got_entry_index);
|
||||
coff.writeOffsetTableEntry(got_entry_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return coff.base.cgFail(nav_index, "failed to write offset table entry: {s}", .{@errorName(e)}),
|
||||
};
|
||||
coff.markRelocsDirtyByTarget(.{ .sym_index = sym_index });
|
||||
}
|
||||
} else if (code_len < atom.size) {
|
||||
@ -1459,16 +1441,25 @@ fn updateNavCode(
|
||||
sym.section_number = @enumFromInt(sect_index + 1);
|
||||
sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
|
||||
|
||||
const vaddr = try coff.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
|
||||
const vaddr = coff.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0)) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return coff.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(e)}),
|
||||
};
|
||||
errdefer coff.freeAtom(atom_index);
|
||||
log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });
|
||||
coff.getAtomPtr(atom_index).size = code_len;
|
||||
sym.value = vaddr;
|
||||
|
||||
try coff.addGotEntry(.{ .sym_index = sym_index });
|
||||
coff.addGotEntry(.{ .sym_index = sym_index }) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return coff.base.cgFail(nav_index, "failed to add GOT entry: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
|
||||
try coff.writeAtom(atom_index, code);
|
||||
coff.writeAtom(atom_index, code) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return coff.base.cgFail(nav_index, "failed to write atom: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn freeNav(coff: *Coff, nav_index: InternPool.NavIndex) void {
|
||||
@ -2229,12 +2220,16 @@ fn findLib(arena: Allocator, name: []const u8, lib_directories: []const Director
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
|
||||
pub fn flushModule(
|
||||
coff: *Coff,
|
||||
arena: Allocator,
|
||||
tid: Zcu.PerThread.Id,
|
||||
prog_node: std.Progress.Node,
|
||||
) link.File.FlushError!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const comp = coff.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const diags = &comp.link_diags;
|
||||
|
||||
if (coff.llvm_object) |llvm_object| {
|
||||
@ -2245,6 +2240,20 @@ pub fn flushModule(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
|
||||
const sub_prog_node = prog_node.start("COFF Flush", 0);
|
||||
defer sub_prog_node.end();
|
||||
|
||||
return flushModuleInner(coff, arena, tid) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.LinkFailure => return error.LinkFailure,
|
||||
else => |e| return diags.fail("COFF flush failed: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
|
||||
fn flushModuleInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void {
|
||||
_ = arena;
|
||||
|
||||
const comp = coff.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const diags = &comp.link_diags;
|
||||
|
||||
const pt: Zcu.PerThread = .activate(
|
||||
comp.zcu orelse return diags.fail("linking without zig source is not yet implemented", .{}),
|
||||
tid,
|
||||
@ -2757,7 +2766,7 @@ fn writeImportTables(coff: *Coff) !void {
|
||||
coff.imports_count_dirty = false;
|
||||
}
|
||||
|
||||
fn writeStrtab(coff: *Coff) link.File.FlushError!void {
|
||||
fn writeStrtab(coff: *Coff) !void {
|
||||
if (coff.strtab_offset == null) return;
|
||||
|
||||
const comp = coff.base.comp;
|
||||
|
||||
@ -21,7 +21,6 @@ debug_rnglists: DebugRngLists,
|
||||
debug_str: StringSection,
|
||||
|
||||
pub const UpdateError = error{
|
||||
CodegenFail,
|
||||
ReinterpretDeclRef,
|
||||
Unimplemented,
|
||||
OutOfMemory,
|
||||
@ -1893,17 +1892,15 @@ pub const WipNav = struct {
|
||||
if (bytes == 0) return;
|
||||
var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa);
|
||||
defer wip_nav.debug_info = dim.moveToUnmanaged();
|
||||
switch (try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
wip_nav.dwarf.bin_file,
|
||||
wip_nav.pt,
|
||||
src_loc,
|
||||
val,
|
||||
&dim,
|
||||
.{ .debug_output = .{ .dwarf = wip_nav } },
|
||||
)) {
|
||||
.ok => assert(dim.items.len == wip_nav.debug_info.items.len + bytes),
|
||||
.fail => unreachable,
|
||||
}
|
||||
);
|
||||
assert(dim.items.len == wip_nav.debug_info.items.len + bytes);
|
||||
}
|
||||
|
||||
const AbbrevCodeForForm = struct {
|
||||
@ -2346,7 +2343,6 @@ pub fn initWipNav(
|
||||
) error{ OutOfMemory, CodegenFail }!?WipNav {
|
||||
return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
@ -2669,7 +2665,6 @@ pub fn finishWipNav(
|
||||
) error{ OutOfMemory, CodegenFail }!void {
|
||||
return finishWipNavInner(dwarf, pt, nav_index, wip_nav) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
@ -2701,7 +2696,6 @@ fn finishWipNavInner(
|
||||
pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {
|
||||
return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
|
||||
@ -2368,12 +2368,25 @@ pub fn updateContainerType(
|
||||
self: *Elf,
|
||||
pt: Zcu.PerThread,
|
||||
ty: InternPool.Index,
|
||||
) link.File.UpdateNavError!void {
|
||||
) link.File.UpdateContainerTypeError!void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .elf) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
if (self.llvm_object) |_| return;
|
||||
return self.zigObjectPtr().?.updateContainerType(pt, ty);
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| {
|
||||
try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
zcu.typeSrcLoc(ty),
|
||||
"failed to update container type: {s}",
|
||||
.{@errorName(e)},
|
||||
));
|
||||
return error.TypeFailureReported;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn updateExports(
|
||||
|
||||
@ -1437,7 +1437,7 @@ pub fn updateFunc(
|
||||
var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
|
||||
defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
|
||||
|
||||
const res = try codegen.generateFunction(
|
||||
try codegen.generateFunction(
|
||||
&elf_file.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(func.owner_nav),
|
||||
@ -1447,14 +1447,7 @@ pub fn updateFunc(
|
||||
&code_buffer,
|
||||
if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
|
||||
);
|
||||
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
try zcu.failed_codegen.put(gpa, func.owner_nav, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
|
||||
log.debug("setting shdr({x},{s}) for {}", .{
|
||||
@ -1574,7 +1567,7 @@ pub fn updateNav(
|
||||
var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
|
||||
defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
|
||||
|
||||
const res = try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
&elf_file.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -1582,14 +1575,7 @@ pub fn updateNav(
|
||||
&code_buffer,
|
||||
.{ .atom_index = sym_index },
|
||||
);
|
||||
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
|
||||
log.debug("setting shdr({x},{s}) for {}", .{
|
||||
@ -1612,7 +1598,7 @@ pub fn updateContainerType(
|
||||
self: *ZigObject,
|
||||
pt: Zcu.PerThread,
|
||||
ty: InternPool.Index,
|
||||
) link.File.UpdateNavError!void {
|
||||
) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
@ -1643,7 +1629,7 @@ fn updateLazySymbol(
|
||||
};
|
||||
|
||||
const src = Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
|
||||
const res = try codegen.generateLazySymbol(
|
||||
try codegen.generateLazySymbol(
|
||||
&elf_file.base,
|
||||
pt,
|
||||
src,
|
||||
@ -1653,13 +1639,7 @@ fn updateLazySymbol(
|
||||
.none,
|
||||
.{ .atom_index = symbol_index },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
log.err("{s}", .{em.msg});
|
||||
return error.CodegenFail;
|
||||
},
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const output_section_index = switch (sym.kind) {
|
||||
.code => if (self.text_index) |sym_index|
|
||||
@ -1732,7 +1712,7 @@ fn lowerConst(
|
||||
const name_off = try self.addString(gpa, name);
|
||||
const sym_index = try self.newSymbolWithAtom(gpa, name_off);
|
||||
|
||||
const res = try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
&elf_file.base,
|
||||
pt,
|
||||
src_loc,
|
||||
@ -1740,10 +1720,7 @@ fn lowerConst(
|
||||
&code_buffer,
|
||||
.{ .atom_index = sym_index },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const local_sym = self.symbol(sym_index);
|
||||
const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];
|
||||
|
||||
@ -590,7 +590,6 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
|
||||
defer pt.deactivate();
|
||||
dwarf.flushModule(pt) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => return error.LinkFailure,
|
||||
else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),
|
||||
};
|
||||
|
||||
@ -796,7 +795,7 @@ pub fn updateFunc(
|
||||
var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
|
||||
defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
|
||||
|
||||
const res = try codegen.generateFunction(
|
||||
try codegen.generateFunction(
|
||||
&macho_file.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(func.owner_nav),
|
||||
@ -806,14 +805,7 @@ pub fn updateFunc(
|
||||
&code_buffer,
|
||||
if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
|
||||
);
|
||||
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
try zcu.failed_codegen.put(gpa, func.owner_nav, em);
|
||||
return error.CodegenFail;
|
||||
},
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);
|
||||
const old_rva, const old_alignment = blk: {
|
||||
@ -914,7 +906,7 @@ pub fn updateNav(
|
||||
var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
|
||||
defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
|
||||
|
||||
const res = try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
&macho_file.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -922,14 +914,8 @@ pub fn updateNav(
|
||||
&code_buffer,
|
||||
.{ .atom_index = sym_index },
|
||||
);
|
||||
const code = code_buffer.items;
|
||||
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| {
|
||||
try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
|
||||
return;
|
||||
},
|
||||
};
|
||||
const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
|
||||
if (isThreadlocal(macho_file, nav_index))
|
||||
try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)
|
||||
@ -1221,7 +1207,7 @@ fn lowerConst(
|
||||
const name_str = try self.addString(gpa, name);
|
||||
const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
|
||||
|
||||
const res = try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
&macho_file.base,
|
||||
pt,
|
||||
src_loc,
|
||||
@ -1229,10 +1215,7 @@ fn lowerConst(
|
||||
&code_buffer,
|
||||
.{ .atom_index = sym_index },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
sym.out_n_sect = output_section_index;
|
||||
@ -1367,7 +1350,6 @@ fn updateLazySymbol(
|
||||
) !void {
|
||||
const zcu = pt.zcu;
|
||||
const gpa = zcu.gpa;
|
||||
const diags = &macho_file.base.comp.link_diags;
|
||||
|
||||
var required_alignment: Atom.Alignment = .none;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
@ -1383,7 +1365,7 @@ fn updateLazySymbol(
|
||||
};
|
||||
|
||||
const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
|
||||
const res = codegen.generateLazySymbol(
|
||||
try codegen.generateLazySymbol(
|
||||
&macho_file.base,
|
||||
pt,
|
||||
src,
|
||||
@ -1392,15 +1374,8 @@ fn updateLazySymbol(
|
||||
&code_buffer,
|
||||
.none,
|
||||
.{ .atom_index = symbol_index },
|
||||
) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.LinkFailure,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| return diags.fail("failed to codegen symbol: {s}", .{@errorName(e)}),
|
||||
};
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}),
|
||||
};
|
||||
);
|
||||
const code = code_buffer.items;
|
||||
|
||||
const output_section_index = switch (lazy_sym.kind) {
|
||||
.code => macho_file.zig_text_sect_index.?,
|
||||
|
||||
@ -465,7 +465,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
// TODO we need the symbol index for symbol in the table of locals for the containing atom
|
||||
const res = try codegen.generateSymbol(
|
||||
try codegen.generateSymbol(
|
||||
&self.base,
|
||||
pt,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -473,10 +473,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
|
||||
&code_buffer,
|
||||
.{ .atom_index = @intCast(atom_idx) },
|
||||
);
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return zcu.failed_codegen.put(gpa, nav_index, em),
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
try self.data_nav_table.ensureUnusedCapacity(gpa, 1);
|
||||
const duped_code = try gpa.dupe(u8, code);
|
||||
self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } };
|
||||
@ -1081,7 +1078,7 @@ fn updateLazySymbolAtom(
|
||||
|
||||
// generate the code
|
||||
const src = Type.fromInterned(sym.ty).srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;
|
||||
const res = codegen.generateLazySymbol(
|
||||
codegen.generateLazySymbol(
|
||||
&self.base,
|
||||
pt,
|
||||
src,
|
||||
@ -1095,10 +1092,7 @@ fn updateLazySymbolAtom(
|
||||
error.CodegenFail => return error.LinkFailure,
|
||||
error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}),
|
||||
};
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return diags.fail("codegen failure: {s}", .{em.msg}),
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
// duped_code is freed when the atom is freed
|
||||
const duped_code = try gpa.dupe(u8, code);
|
||||
errdefer gpa.free(duped_code);
|
||||
@ -1408,11 +1402,8 @@ pub fn lowerUav(
|
||||
gop.value_ptr.* = index;
|
||||
// we need to free name latex
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
|
||||
const code = switch (res) {
|
||||
.ok => code_buffer.items,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
|
||||
const code = code_buffer.items;
|
||||
const atom_ptr = self.getAtomPtr(index);
|
||||
atom_ptr.* = .{
|
||||
.type = .d,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user