mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
rework generic function calls
Abridged summary: * Move `Module.Fn` into `InternPool`. * Delete a lot of confusing and problematic `Sema` logic related to generic function calls. This commit removes `Module.Fn` and replaces it with two new `InternPool.Tag` values: * `func_decl` - corresponding to a function declared in the source code. This one contains line/column numbers, zir_body_inst, etc. * `func_instance` - one for each monomorphization of a generic function. Contains a reference to the `func_decl` from whence the instantiation came, along with the `comptime` parameter values (or types in the case of `anytype`) Since `InternPool` provides deduplication on these values, these fields are now deleted from `Module`: * `monomorphed_func_keys` * `monomorphed_funcs` * `align_stack_fns` Instead of these, Sema logic for generic function instantiation now unconditionally evaluates the function prototype expression for every generic callsite. This is technically required in order for type coercions to work. The previous code had some dubious, probably wrong hacks to make things work, such as `hashUncoerced`. I'm not 100% sure how we were able to eliminate that function and still pass all the behavior tests, but I'm pretty sure things were still broken without doing type coercion for every generic function call argument. After the function prototype is evaluated, it produces a deduplicated `func_instance` `InternPool.Index` which can then be used for the generic function call. Some other nice things made by this simplification are the removal of `comptime_args_fn_inst` and `preallocated_new_func` from `Sema`, and the messy logic associated with them. I have not yet been able to measure the perf of this against master branch. On one hand, it reduces memory usage and pointer chasing of the most heavily used `InternPool` Tag - function bodies - but on the other hand, it does evaluate function prototype expressions more than before. We will soon find out.
This commit is contained in:
parent
70c71935c7
commit
db33ee45b7
30 changed files with 1748 additions and 1973 deletions
|
|
@ -1003,7 +1003,7 @@ pub const Inst = struct {
|
|||
},
|
||||
ty_fn: struct {
|
||||
ty: Ref,
|
||||
func: Module.Fn.Index,
|
||||
func: InternPool.Index,
|
||||
},
|
||||
br: struct {
|
||||
block_inst: Index,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const wasi_libc = @import("wasi_libc.zig");
|
|||
const fatal = @import("main.zig").fatal;
|
||||
const clangMain = @import("main.zig").clangMain;
|
||||
const Module = @import("Module.zig");
|
||||
const InternPool = @import("InternPool.zig");
|
||||
const BuildId = std.Build.CompileStep.BuildId;
|
||||
const Cache = std.Build.Cache;
|
||||
const translate_c = @import("translate_c.zig");
|
||||
|
|
@ -227,7 +228,8 @@ const Job = union(enum) {
|
|||
/// Write the constant value for a Decl to the output file.
|
||||
codegen_decl: Module.Decl.Index,
|
||||
/// Write the machine code for a function to the output file.
|
||||
codegen_func: Module.Fn.Index,
|
||||
/// This will either be a non-generic `func_decl` or a `func_instance`.
|
||||
codegen_func: InternPool.Index,
|
||||
/// Render the .h file snippet for the Decl.
|
||||
emit_h_decl: Module.Decl.Index,
|
||||
/// The Decl needs to be analyzed and possibly export itself.
|
||||
|
|
@ -3216,8 +3218,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
|
|||
// Tests are always emitted in test binaries. The decl_refs are created by
|
||||
// Module.populateTestFunctions, but this will not queue body analysis, so do
|
||||
// that now.
|
||||
const func_index = module.intern_pool.indexToFunc(decl.val.ip_index).unwrap().?;
|
||||
try module.ensureFuncBodyAnalysisQueued(func_index);
|
||||
try module.ensureFuncBodyAnalysisQueued(decl.val.toIntern());
|
||||
}
|
||||
},
|
||||
.update_embed_file => |embed_file| {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
666
src/Module.zig
666
src/Module.zig
File diff suppressed because it is too large
Load diff
1699
src/Sema.zig
1699
src/Sema.zig
File diff suppressed because it is too large
Load diff
|
|
@ -205,7 +205,7 @@ pub fn print(
|
|||
mod.declPtr(extern_func.decl).name.fmt(ip),
|
||||
}),
|
||||
.func => |func| return writer.print("(function '{}')", .{
|
||||
mod.declPtr(mod.funcPtr(func.index).owner_decl).name.fmt(ip),
|
||||
mod.declPtr(func.owner_decl).name.fmt(ip),
|
||||
}),
|
||||
.int => |int| switch (int.storage) {
|
||||
inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
|
||||
|
|
|
|||
17
src/Zir.zig
17
src/Zir.zig
|
|
@ -90,13 +90,24 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en
|
|||
};
|
||||
}
|
||||
|
||||
/// Given an index into `string_bytes` returns the null-terminated string found there.
|
||||
/// TODO migrate to use this for type safety
|
||||
pub const NullTerminatedString = enum(u32) {
|
||||
_,
|
||||
};
|
||||
|
||||
/// TODO: migrate to nullTerminatedString2 for type safety
|
||||
pub fn nullTerminatedString(code: Zir, index: usize) [:0]const u8 {
|
||||
var end: usize = index;
|
||||
return nullTerminatedString2(code, @enumFromInt(index));
|
||||
}
|
||||
|
||||
/// Given an index into `string_bytes` returns the null-terminated string found there.
|
||||
pub fn nullTerminatedString2(code: Zir, index: NullTerminatedString) [:0]const u8 {
|
||||
const start = @intFromEnum(index);
|
||||
var end: u32 = start;
|
||||
while (code.string_bytes[end] != 0) {
|
||||
end += 1;
|
||||
}
|
||||
return code.string_bytes[index..end :0];
|
||||
return code.string_bytes[start..end :0];
|
||||
}
|
||||
|
||||
pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const Value = @import("../../value.zig").Value;
|
|||
const TypedValue = @import("../../TypedValue.zig");
|
||||
const link = @import("../../link.zig");
|
||||
const Module = @import("../../Module.zig");
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const Compilation = @import("../../Compilation.zig");
|
||||
const ErrorMsg = Module.ErrorMsg;
|
||||
const Target = std.Target;
|
||||
|
|
@ -49,7 +50,8 @@ liveness: Liveness,
|
|||
bin_file: *link.File,
|
||||
debug_output: DebugInfoOutput,
|
||||
target: *const std.Target,
|
||||
mod_fn: *const Module.Fn,
|
||||
func_index: InternPool.Index,
|
||||
owner_decl: Module.Decl.Index,
|
||||
err_msg: ?*ErrorMsg,
|
||||
args: []MCValue,
|
||||
ret_mcv: MCValue,
|
||||
|
|
@ -199,7 +201,7 @@ const DbgInfoReloc = struct {
|
|||
else => unreachable, // not a possible argument
|
||||
|
||||
};
|
||||
try dw.genArgDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, loc);
|
||||
try dw.genArgDbgInfo(reloc.name, reloc.ty, function.owner_decl, loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
|
@ -245,7 +247,7 @@ const DbgInfoReloc = struct {
|
|||
break :blk .nop;
|
||||
},
|
||||
};
|
||||
try dw.genVarDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, is_ptr, loc);
|
||||
try dw.genVarDbgInfo(reloc.name, reloc.ty, function.owner_decl, is_ptr, loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
|
@ -328,7 +330,7 @@ const Self = @This();
|
|||
pub fn generate(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
module_fn_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
@ -339,8 +341,8 @@ pub fn generate(
|
|||
}
|
||||
|
||||
const mod = bin_file.options.module.?;
|
||||
const module_fn = mod.funcPtr(module_fn_index);
|
||||
const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
|
||||
|
|
@ -359,7 +361,8 @@ pub fn generate(
|
|||
.debug_output = debug_output,
|
||||
.target = &bin_file.options.target,
|
||||
.bin_file = bin_file,
|
||||
.mod_fn = module_fn,
|
||||
.func_index = func_index,
|
||||
.owner_decl = func.owner_decl,
|
||||
.err_msg = null,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
|
||||
|
|
@ -368,8 +371,8 @@ pub fn generate(
|
|||
.branch_stack = &branch_stack,
|
||||
.src_loc = src_loc,
|
||||
.stack_align = undefined,
|
||||
.end_di_line = module_fn.rbrace_line,
|
||||
.end_di_column = module_fn.rbrace_column,
|
||||
.end_di_line = func.rbrace_line,
|
||||
.end_di_column = func.rbrace_column,
|
||||
};
|
||||
defer function.stack.deinit(bin_file.allocator);
|
||||
defer function.blocks.deinit(bin_file.allocator);
|
||||
|
|
@ -416,8 +419,8 @@ pub fn generate(
|
|||
.src_loc = src_loc,
|
||||
.code = code,
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_line = module_fn.lbrace_line,
|
||||
.prev_di_column = module_fn.lbrace_column,
|
||||
.prev_di_line = func.lbrace_line,
|
||||
.prev_di_column = func.lbrace_column,
|
||||
.stack_size = function.max_end_stack,
|
||||
.saved_regs_stack_space = function.saved_regs_stack_space,
|
||||
};
|
||||
|
|
@ -4011,12 +4014,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
|
|||
const atom_index = switch (self.bin_file.tag) {
|
||||
.macho => blk: {
|
||||
const macho_file = self.bin_file.cast(link.File.MachO).?;
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
.coff => blk: {
|
||||
const coff_file = self.bin_file.cast(link.File.Coff).?;
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
else => unreachable, // unsupported target format
|
||||
|
|
@ -4190,10 +4193,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
|||
while (self.args[arg_index] == .none) arg_index += 1;
|
||||
self.arg_index = arg_index + 1;
|
||||
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ty = self.typeOfIndex(inst);
|
||||
const tag = self.air.instructions.items(.tag)[inst];
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
|
||||
const name = mod.getParamName(self.func_index, src_index);
|
||||
|
||||
try self.dbg_info_relocs.append(self.gpa, .{
|
||||
.tag = tag,
|
||||
|
|
@ -4348,7 +4352,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
|||
const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
|
||||
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
_ = try self.addInst(.{
|
||||
.tag = .call_extern,
|
||||
|
|
@ -4617,9 +4621,9 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
|
|||
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const function = mod.funcPtr(ty_fn.func);
|
||||
const func = mod.funcInfo(ty_fn.func);
|
||||
// TODO emit debug info for function change
|
||||
_ = function;
|
||||
_ = func;
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
|
|
@ -5529,12 +5533,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
|
|||
const atom_index = switch (self.bin_file.tag) {
|
||||
.macho => blk: {
|
||||
const macho_file = self.bin_file.cast(link.File.MachO).?;
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
.coff => blk: {
|
||||
const coff_file = self.bin_file.cast(link.File.Coff).?;
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
else => unreachable, // unsupported target format
|
||||
|
|
@ -5650,12 +5654,12 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
|||
const atom_index = switch (self.bin_file.tag) {
|
||||
.macho => blk: {
|
||||
const macho_file = self.bin_file.cast(link.File.MachO).?;
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
.coff => blk: {
|
||||
const coff_file = self.bin_file.cast(link.File.Coff).?;
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
else => unreachable, // unsupported target format
|
||||
|
|
@ -5847,12 +5851,12 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
|
|||
const atom_index = switch (self.bin_file.tag) {
|
||||
.macho => blk: {
|
||||
const macho_file = self.bin_file.cast(link.File.MachO).?;
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
.coff => blk: {
|
||||
const coff_file = self.bin_file.cast(link.File.Coff).?;
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
|
||||
break :blk coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
},
|
||||
else => unreachable, // unsupported target format
|
||||
|
|
@ -6164,7 +6168,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
|
|||
self.bin_file,
|
||||
self.src_loc,
|
||||
arg_tv,
|
||||
self.mod_fn.owner_decl,
|
||||
self.owner_decl,
|
||||
)) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
.none => .none,
|
||||
|
|
@ -6198,6 +6202,7 @@ const CallMCValues = struct {
|
|||
/// Caller must call `CallMCValues.deinit`.
|
||||
fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(fn_ty).?;
|
||||
const cc = fn_info.cc;
|
||||
var result: CallMCValues = .{
|
||||
|
|
@ -6240,10 +6245,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
}
|
||||
}
|
||||
|
||||
for (fn_info.param_types, 0..) |ty, i| {
|
||||
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
|
||||
const param_size = @as(u32, @intCast(ty.toType().abiSize(mod)));
|
||||
if (param_size == 0) {
|
||||
result.args[i] = .{ .none = {} };
|
||||
result_arg.* = .{ .none = {} };
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -6256,7 +6261,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
|
||||
if (std.math.divCeil(u32, param_size, 8) catch unreachable <= 8 - ncrn) {
|
||||
if (param_size <= 8) {
|
||||
result.args[i] = .{ .register = self.registerAlias(c_abi_int_param_regs[ncrn], ty.toType()) };
|
||||
result_arg.* = .{ .register = self.registerAlias(c_abi_int_param_regs[ncrn], ty.toType()) };
|
||||
ncrn += 1;
|
||||
} else {
|
||||
return self.fail("TODO MCValues with multiple registers", .{});
|
||||
|
|
@ -6273,7 +6278,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
}
|
||||
}
|
||||
|
||||
result.args[i] = .{ .stack_argument_offset = nsaa };
|
||||
result_arg.* = .{ .stack_argument_offset = nsaa };
|
||||
nsaa += param_size;
|
||||
}
|
||||
}
|
||||
|
|
@ -6305,16 +6310,16 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
|
||||
var stack_offset: u32 = 0;
|
||||
|
||||
for (fn_info.param_types, 0..) |ty, i| {
|
||||
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
|
||||
if (ty.toType().abiSize(mod) > 0) {
|
||||
const param_size = @as(u32, @intCast(ty.toType().abiSize(mod)));
|
||||
const param_alignment = ty.toType().abiAlignment(mod);
|
||||
|
||||
stack_offset = std.mem.alignForward(u32, stack_offset, param_alignment);
|
||||
result.args[i] = .{ .stack_argument_offset = stack_offset };
|
||||
result_arg.* = .{ .stack_argument_offset = stack_offset };
|
||||
stack_offset += param_size;
|
||||
} else {
|
||||
result.args[i] = .{ .none = {} };
|
||||
result_arg.* = .{ .none = {} };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const Value = @import("../../value.zig").Value;
|
|||
const TypedValue = @import("../../TypedValue.zig");
|
||||
const link = @import("../../link.zig");
|
||||
const Module = @import("../../Module.zig");
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const Compilation = @import("../../Compilation.zig");
|
||||
const ErrorMsg = Module.ErrorMsg;
|
||||
const Target = std.Target;
|
||||
|
|
@ -50,7 +51,7 @@ liveness: Liveness,
|
|||
bin_file: *link.File,
|
||||
debug_output: DebugInfoOutput,
|
||||
target: *const std.Target,
|
||||
mod_fn: *const Module.Fn,
|
||||
func_index: InternPool.Index,
|
||||
err_msg: ?*ErrorMsg,
|
||||
args: []MCValue,
|
||||
ret_mcv: MCValue,
|
||||
|
|
@ -258,6 +259,7 @@ const DbgInfoReloc = struct {
|
|||
}
|
||||
|
||||
fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
|
||||
const mod = function.bin_file.options.module.?;
|
||||
switch (function.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
|
||||
|
|
@ -278,7 +280,7 @@ const DbgInfoReloc = struct {
|
|||
else => unreachable, // not a possible argument
|
||||
};
|
||||
|
||||
try dw.genArgDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, loc);
|
||||
try dw.genArgDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
|
@ -286,6 +288,7 @@ const DbgInfoReloc = struct {
|
|||
}
|
||||
|
||||
fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
|
||||
const mod = function.bin_file.options.module.?;
|
||||
const is_ptr = switch (reloc.tag) {
|
||||
.dbg_var_ptr => true,
|
||||
.dbg_var_val => false,
|
||||
|
|
@ -321,7 +324,7 @@ const DbgInfoReloc = struct {
|
|||
break :blk .nop;
|
||||
},
|
||||
};
|
||||
try dw.genVarDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, is_ptr, loc);
|
||||
try dw.genVarDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), is_ptr, loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
|
|
@ -334,7 +337,7 @@ const Self = @This();
|
|||
pub fn generate(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
module_fn_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
@ -345,8 +348,8 @@ pub fn generate(
|
|||
}
|
||||
|
||||
const mod = bin_file.options.module.?;
|
||||
const module_fn = mod.funcPtr(module_fn_index);
|
||||
const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
|
||||
|
|
@ -365,7 +368,7 @@ pub fn generate(
|
|||
.target = &bin_file.options.target,
|
||||
.bin_file = bin_file,
|
||||
.debug_output = debug_output,
|
||||
.mod_fn = module_fn,
|
||||
.func_index = func_index,
|
||||
.err_msg = null,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
|
||||
|
|
@ -374,8 +377,8 @@ pub fn generate(
|
|||
.branch_stack = &branch_stack,
|
||||
.src_loc = src_loc,
|
||||
.stack_align = undefined,
|
||||
.end_di_line = module_fn.rbrace_line,
|
||||
.end_di_column = module_fn.rbrace_column,
|
||||
.end_di_line = func.rbrace_line,
|
||||
.end_di_column = func.rbrace_column,
|
||||
};
|
||||
defer function.stack.deinit(bin_file.allocator);
|
||||
defer function.blocks.deinit(bin_file.allocator);
|
||||
|
|
@ -422,8 +425,8 @@ pub fn generate(
|
|||
.src_loc = src_loc,
|
||||
.code = code,
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_line = module_fn.lbrace_line,
|
||||
.prev_di_column = module_fn.lbrace_column,
|
||||
.prev_di_line = func.lbrace_line,
|
||||
.prev_di_column = func.lbrace_column,
|
||||
.stack_size = function.max_end_stack,
|
||||
.saved_regs_stack_space = function.saved_regs_stack_space,
|
||||
};
|
||||
|
|
@ -4163,10 +4166,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
|||
while (self.args[arg_index] == .none) arg_index += 1;
|
||||
self.arg_index = arg_index + 1;
|
||||
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ty = self.typeOfIndex(inst);
|
||||
const tag = self.air.instructions.items(.tag)[inst];
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
|
||||
const name = mod.getParamName(self.func_index, src_index);
|
||||
|
||||
try self.dbg_info_relocs.append(self.gpa, .{
|
||||
.tag = tag,
|
||||
|
|
@ -4569,9 +4573,9 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
|
|||
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const function = mod.funcPtr(ty_fn.func);
|
||||
const func = mod.funcInfo(ty_fn.func);
|
||||
// TODO emit debug info for function change
|
||||
_ = function;
|
||||
_ = func;
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
|
|
@ -6113,11 +6117,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
|
|||
}
|
||||
|
||||
fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const mcv: MCValue = switch (try codegen.genTypedValue(
|
||||
self.bin_file,
|
||||
self.src_loc,
|
||||
arg_tv,
|
||||
self.mod_fn.owner_decl,
|
||||
mod.funcOwnerDeclIndex(self.func_index),
|
||||
)) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
.none => .none,
|
||||
|
|
@ -6149,6 +6154,7 @@ const CallMCValues = struct {
|
|||
/// Caller must call `CallMCValues.deinit`.
|
||||
fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(fn_ty).?;
|
||||
const cc = fn_info.cc;
|
||||
var result: CallMCValues = .{
|
||||
|
|
@ -6194,14 +6200,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
}
|
||||
}
|
||||
|
||||
for (fn_info.param_types, 0..) |ty, i| {
|
||||
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
|
||||
if (ty.toType().abiAlignment(mod) == 8)
|
||||
ncrn = std.mem.alignForward(usize, ncrn, 2);
|
||||
|
||||
const param_size = @as(u32, @intCast(ty.toType().abiSize(mod)));
|
||||
if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {
|
||||
if (param_size <= 4) {
|
||||
result.args[i] = .{ .register = c_abi_int_param_regs[ncrn] };
|
||||
result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] };
|
||||
ncrn += 1;
|
||||
} else {
|
||||
return self.fail("TODO MCValues with multiple registers", .{});
|
||||
|
|
@ -6213,7 +6219,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
if (ty.toType().abiAlignment(mod) == 8)
|
||||
nsaa = std.mem.alignForward(u32, nsaa, 8);
|
||||
|
||||
result.args[i] = .{ .stack_argument_offset = nsaa };
|
||||
result_arg.* = .{ .stack_argument_offset = nsaa };
|
||||
nsaa += param_size;
|
||||
}
|
||||
}
|
||||
|
|
@ -6244,16 +6250,16 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
|
||||
var stack_offset: u32 = 0;
|
||||
|
||||
for (fn_info.param_types, 0..) |ty, i| {
|
||||
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
|
||||
if (ty.toType().abiSize(mod) > 0) {
|
||||
const param_size = @as(u32, @intCast(ty.toType().abiSize(mod)));
|
||||
const param_alignment = ty.toType().abiAlignment(mod);
|
||||
|
||||
stack_offset = std.mem.alignForward(u32, stack_offset, param_alignment);
|
||||
result.args[i] = .{ .stack_argument_offset = stack_offset };
|
||||
result_arg.* = .{ .stack_argument_offset = stack_offset };
|
||||
stack_offset += param_size;
|
||||
} else {
|
||||
result.args[i] = .{ .none = {} };
|
||||
result_arg.* = .{ .none = {} };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const Value = @import("../../value.zig").Value;
|
|||
const TypedValue = @import("../../TypedValue.zig");
|
||||
const link = @import("../../link.zig");
|
||||
const Module = @import("../../Module.zig");
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const Compilation = @import("../../Compilation.zig");
|
||||
const ErrorMsg = Module.ErrorMsg;
|
||||
const Target = std.Target;
|
||||
|
|
@ -43,7 +44,7 @@ air: Air,
|
|||
liveness: Liveness,
|
||||
bin_file: *link.File,
|
||||
target: *const std.Target,
|
||||
mod_fn: *const Module.Fn,
|
||||
func_index: InternPool.Index,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
err_msg: ?*ErrorMsg,
|
||||
|
|
@ -217,7 +218,7 @@ const Self = @This();
|
|||
pub fn generate(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
module_fn_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
@ -228,8 +229,8 @@ pub fn generate(
|
|||
}
|
||||
|
||||
const mod = bin_file.options.module.?;
|
||||
const module_fn = mod.funcPtr(module_fn_index);
|
||||
const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
|
||||
|
|
@ -247,7 +248,7 @@ pub fn generate(
|
|||
.liveness = liveness,
|
||||
.target = &bin_file.options.target,
|
||||
.bin_file = bin_file,
|
||||
.mod_fn = module_fn,
|
||||
.func_index = func_index,
|
||||
.code = code,
|
||||
.debug_output = debug_output,
|
||||
.err_msg = null,
|
||||
|
|
@ -258,8 +259,8 @@ pub fn generate(
|
|||
.branch_stack = &branch_stack,
|
||||
.src_loc = src_loc,
|
||||
.stack_align = undefined,
|
||||
.end_di_line = module_fn.rbrace_line,
|
||||
.end_di_column = module_fn.rbrace_column,
|
||||
.end_di_line = func.rbrace_line,
|
||||
.end_di_column = func.rbrace_column,
|
||||
};
|
||||
defer function.stack.deinit(bin_file.allocator);
|
||||
defer function.blocks.deinit(bin_file.allocator);
|
||||
|
|
@ -301,8 +302,8 @@ pub fn generate(
|
|||
.src_loc = src_loc,
|
||||
.code = code,
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_line = module_fn.lbrace_line,
|
||||
.prev_di_column = module_fn.lbrace_column,
|
||||
.prev_di_line = func.lbrace_line,
|
||||
.prev_di_column = func.lbrace_column,
|
||||
};
|
||||
defer emit.deinit();
|
||||
|
||||
|
|
@ -1627,13 +1628,15 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
|
|||
}
|
||||
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const arg = self.air.instructions.items(.data)[inst].arg;
|
||||
const ty = self.air.getRefType(arg.ty);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
|
||||
const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
|
||||
const name = mod.getParamName(self.func_index, arg.src_index);
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
.register => |reg| try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, .{
|
||||
.register => |reg| try dw.genArgDbgInfo(name, ty, owner_decl, .{
|
||||
.register = reg.dwarfLocOp(),
|
||||
}),
|
||||
.stack_offset => {},
|
||||
|
|
@ -1742,24 +1745,28 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
|||
}
|
||||
|
||||
if (try self.air.value(callee, mod)) |func_value| {
|
||||
if (mod.funcPtrUnwrap(mod.intern_pool.indexToFunc(func_value.ip_index))) |func| {
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
_ = try atom.getOrCreateOffsetTableEntry(elf_file);
|
||||
const got_addr = @as(u32, @intCast(atom.getOffsetTableAddress(elf_file)));
|
||||
try self.genSetReg(Type.usize, .ra, .{ .memory = got_addr });
|
||||
_ = try self.addInst(.{
|
||||
.tag = .jalr,
|
||||
.data = .{ .i_type = .{
|
||||
.rd = .ra,
|
||||
.rs1 = .ra,
|
||||
.imm12 = 0,
|
||||
} },
|
||||
});
|
||||
} else if (mod.intern_pool.indexToKey(func_value.ip_index) == .extern_func) {
|
||||
return self.fail("TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail("TODO implement calling bitcasted functions", .{});
|
||||
switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
|
||||
.func => |func| {
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
_ = try atom.getOrCreateOffsetTableEntry(elf_file);
|
||||
const got_addr = @as(u32, @intCast(atom.getOffsetTableAddress(elf_file)));
|
||||
try self.genSetReg(Type.usize, .ra, .{ .memory = got_addr });
|
||||
_ = try self.addInst(.{
|
||||
.tag = .jalr,
|
||||
.data = .{ .i_type = .{
|
||||
.rd = .ra,
|
||||
.rs1 = .ra,
|
||||
.imm12 = 0,
|
||||
} },
|
||||
});
|
||||
},
|
||||
.extern_func => {
|
||||
return self.fail("TODO implement calling extern functions", .{});
|
||||
},
|
||||
else => {
|
||||
return self.fail("TODO implement calling bitcasted functions", .{});
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return self.fail("TODO implement calling runtime-known function pointer", .{});
|
||||
|
|
@ -1876,9 +1883,9 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
|
|||
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const function = mod.funcPtr(ty_fn.func);
|
||||
const func = mod.funcInfo(ty_fn.func);
|
||||
// TODO emit debug info for function change
|
||||
_ = function;
|
||||
_ = func;
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
|
|
@ -2569,11 +2576,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
|
|||
}
|
||||
|
||||
fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const mcv: MCValue = switch (try codegen.genTypedValue(
|
||||
self.bin_file,
|
||||
self.src_loc,
|
||||
typed_value,
|
||||
self.mod_fn.owner_decl,
|
||||
mod.funcOwnerDeclIndex(self.func_index),
|
||||
)) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
.none => .none,
|
||||
|
|
@ -2605,6 +2613,7 @@ const CallMCValues = struct {
|
|||
/// Caller must call `CallMCValues.deinit`.
|
||||
fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(fn_ty).?;
|
||||
const cc = fn_info.cc;
|
||||
var result: CallMCValues = .{
|
||||
|
|
@ -2636,14 +2645,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
var next_stack_offset: u32 = 0;
|
||||
const argument_registers = [_]Register{ .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7 };
|
||||
|
||||
for (fn_info.param_types, 0..) |ty, i| {
|
||||
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
|
||||
const param_size = @as(u32, @intCast(ty.toType().abiSize(mod)));
|
||||
if (param_size <= 8) {
|
||||
if (next_register < argument_registers.len) {
|
||||
result.args[i] = .{ .register = argument_registers[next_register] };
|
||||
result_arg.* = .{ .register = argument_registers[next_register] };
|
||||
next_register += 1;
|
||||
} else {
|
||||
result.args[i] = .{ .stack_offset = next_stack_offset };
|
||||
result_arg.* = .{ .stack_offset = next_stack_offset };
|
||||
next_register += next_stack_offset;
|
||||
}
|
||||
} else if (param_size <= 16) {
|
||||
|
|
@ -2652,11 +2661,11 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
|||
} else if (next_register < argument_registers.len) {
|
||||
return self.fail("TODO MCValues split register + stack", .{});
|
||||
} else {
|
||||
result.args[i] = .{ .stack_offset = next_stack_offset };
|
||||
result_arg.* = .{ .stack_offset = next_stack_offset };
|
||||
next_register += next_stack_offset;
|
||||
}
|
||||
} else {
|
||||
result.args[i] = .{ .stack_offset = next_stack_offset };
|
||||
result_arg.* = .{ .stack_offset = next_stack_offset };
|
||||
next_register += next_stack_offset;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const Allocator = mem.Allocator;
|
|||
const builtin = @import("builtin");
|
||||
const link = @import("../../link.zig");
|
||||
const Module = @import("../../Module.zig");
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const TypedValue = @import("../../TypedValue.zig");
|
||||
const ErrorMsg = Module.ErrorMsg;
|
||||
const codegen = @import("../../codegen.zig");
|
||||
|
|
@ -52,7 +53,7 @@ air: Air,
|
|||
liveness: Liveness,
|
||||
bin_file: *link.File,
|
||||
target: *const std.Target,
|
||||
mod_fn: *const Module.Fn,
|
||||
func_index: InternPool.Index,
|
||||
code: *std.ArrayList(u8),
|
||||
debug_output: DebugInfoOutput,
|
||||
err_msg: ?*ErrorMsg,
|
||||
|
|
@ -260,7 +261,7 @@ const BigTomb = struct {
|
|||
pub fn generate(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
module_fn_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
@ -271,8 +272,8 @@ pub fn generate(
|
|||
}
|
||||
|
||||
const mod = bin_file.options.module.?;
|
||||
const module_fn = mod.funcPtr(module_fn_index);
|
||||
const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
|
||||
|
|
@ -289,8 +290,8 @@ pub fn generate(
|
|||
.air = air,
|
||||
.liveness = liveness,
|
||||
.target = &bin_file.options.target,
|
||||
.func_index = func_index,
|
||||
.bin_file = bin_file,
|
||||
.mod_fn = module_fn,
|
||||
.code = code,
|
||||
.debug_output = debug_output,
|
||||
.err_msg = null,
|
||||
|
|
@ -301,8 +302,8 @@ pub fn generate(
|
|||
.branch_stack = &branch_stack,
|
||||
.src_loc = src_loc,
|
||||
.stack_align = undefined,
|
||||
.end_di_line = module_fn.rbrace_line,
|
||||
.end_di_column = module_fn.rbrace_column,
|
||||
.end_di_line = func.rbrace_line,
|
||||
.end_di_column = func.rbrace_column,
|
||||
};
|
||||
defer function.stack.deinit(bin_file.allocator);
|
||||
defer function.blocks.deinit(bin_file.allocator);
|
||||
|
|
@ -344,8 +345,8 @@ pub fn generate(
|
|||
.src_loc = src_loc,
|
||||
.code = code,
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_line = module_fn.lbrace_line,
|
||||
.prev_di_column = module_fn.lbrace_column,
|
||||
.prev_di_line = func.lbrace_line,
|
||||
.prev_di_column = func.lbrace_column,
|
||||
};
|
||||
defer emit.deinit();
|
||||
|
||||
|
|
@ -1345,37 +1346,41 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
|||
// on linking.
|
||||
if (try self.air.value(callee, mod)) |func_value| {
|
||||
if (self.bin_file.tag == link.File.Elf.base_tag) {
|
||||
if (mod.funcPtrUnwrap(mod.intern_pool.indexToFunc(func_value.ip_index))) |func| {
|
||||
const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
_ = try atom.getOrCreateOffsetTableEntry(elf_file);
|
||||
break :blk @as(u32, @intCast(atom.getOffsetTableAddress(elf_file)));
|
||||
} else unreachable;
|
||||
switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
|
||||
.func => |func| {
|
||||
const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
|
||||
const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
const atom = elf_file.getAtom(atom_index);
|
||||
_ = try atom.getOrCreateOffsetTableEntry(elf_file);
|
||||
break :blk @as(u32, @intCast(atom.getOffsetTableAddress(elf_file)));
|
||||
} else unreachable;
|
||||
|
||||
try self.genSetReg(Type.usize, .o7, .{ .memory = got_addr });
|
||||
try self.genSetReg(Type.usize, .o7, .{ .memory = got_addr });
|
||||
|
||||
_ = try self.addInst(.{
|
||||
.tag = .jmpl,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = false,
|
||||
.rd = .o7,
|
||||
.rs1 = .o7,
|
||||
.rs2_or_imm = .{ .rs2 = .g0 },
|
||||
_ = try self.addInst(.{
|
||||
.tag = .jmpl,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = false,
|
||||
.rd = .o7,
|
||||
.rs1 = .o7,
|
||||
.rs2_or_imm = .{ .rs2 = .g0 },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// TODO Find a way to fill this delay slot
|
||||
_ = try self.addInst(.{
|
||||
.tag = .nop,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
} else if (mod.intern_pool.indexToKey(func_value.ip_index) == .extern_func) {
|
||||
return self.fail("TODO implement calling extern functions", .{});
|
||||
} else {
|
||||
return self.fail("TODO implement calling bitcasted functions", .{});
|
||||
// TODO Find a way to fill this delay slot
|
||||
_ = try self.addInst(.{
|
||||
.tag = .nop,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
},
|
||||
.extern_func => {
|
||||
return self.fail("TODO implement calling extern functions", .{});
|
||||
},
|
||||
else => {
|
||||
return self.fail("TODO implement calling bitcasted functions", .{});
|
||||
},
|
||||
}
|
||||
} else @panic("TODO SPARCv9 currently does not support non-ELF binaries");
|
||||
} else {
|
||||
|
|
@ -1660,9 +1665,9 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
|
|||
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const function = mod.funcPtr(ty_fn.func);
|
||||
const func = mod.funcInfo(ty_fn.func);
|
||||
// TODO emit debug info for function change
|
||||
_ = function;
|
||||
_ = func;
|
||||
return self.finishAir(inst, .dead, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
|
|
@ -3595,13 +3600,15 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
|
|||
}
|
||||
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const arg = self.air.instructions.items(.data)[inst].arg;
|
||||
const ty = self.air.getRefType(arg.ty);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
|
||||
const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
|
||||
const name = mod.getParamName(self.func_index, arg.src_index);
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
.register => |reg| try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, .{
|
||||
.register => |reg| try dw.genArgDbgInfo(name, ty, owner_decl, .{
|
||||
.register = reg.dwarfLocOp(),
|
||||
}),
|
||||
else => {},
|
||||
|
|
@ -4127,11 +4134,12 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re
|
|||
}
|
||||
|
||||
fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const mcv: MCValue = switch (try codegen.genTypedValue(
|
||||
self.bin_file,
|
||||
self.src_loc,
|
||||
typed_value,
|
||||
self.mod_fn.owner_decl,
|
||||
mod.funcOwnerDeclIndex(self.func_index),
|
||||
)) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
.none => .none,
|
||||
|
|
@ -4452,6 +4460,7 @@ fn realStackOffset(off: u32) u32 {
|
|||
/// Caller must call `CallMCValues.deinit`.
|
||||
fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(fn_ty).?;
|
||||
const cc = fn_info.cc;
|
||||
var result: CallMCValues = .{
|
||||
|
|
@ -4486,14 +4495,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
|
|||
.callee => abi.c_abi_int_param_regs_callee_view,
|
||||
};
|
||||
|
||||
for (fn_info.param_types, 0..) |ty, i| {
|
||||
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
|
||||
const param_size = @as(u32, @intCast(ty.toType().abiSize(mod)));
|
||||
if (param_size <= 8) {
|
||||
if (next_register < argument_registers.len) {
|
||||
result.args[i] = .{ .register = argument_registers[next_register] };
|
||||
result_arg.* = .{ .register = argument_registers[next_register] };
|
||||
next_register += 1;
|
||||
} else {
|
||||
result.args[i] = .{ .stack_offset = next_stack_offset };
|
||||
result_arg.* = .{ .stack_offset = next_stack_offset };
|
||||
next_register += next_stack_offset;
|
||||
}
|
||||
} else if (param_size <= 16) {
|
||||
|
|
@ -4502,11 +4511,11 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
|
|||
} else if (next_register < argument_registers.len) {
|
||||
return self.fail("TODO MCValues split register + stack", .{});
|
||||
} else {
|
||||
result.args[i] = .{ .stack_offset = next_stack_offset };
|
||||
result_arg.* = .{ .stack_offset = next_stack_offset };
|
||||
next_register += next_stack_offset;
|
||||
}
|
||||
} else {
|
||||
result.args[i] = .{ .stack_offset = next_stack_offset };
|
||||
result_arg.* = .{ .stack_offset = next_stack_offset };
|
||||
next_register += next_stack_offset;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ air: Air,
|
|||
liveness: Liveness,
|
||||
gpa: mem.Allocator,
|
||||
debug_output: codegen.DebugInfoOutput,
|
||||
mod_fn: *const Module.Fn,
|
||||
func_index: InternPool.Index,
|
||||
/// Contains a list of current branches.
|
||||
/// When we return from a branch, the branch will be popped from this list,
|
||||
/// which means branches can only contain references from within its own branch,
|
||||
|
|
@ -1202,7 +1202,7 @@ fn genFunctype(
|
|||
pub fn generate(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
func_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
@ -1210,7 +1210,7 @@ pub fn generate(
|
|||
) codegen.CodeGenError!codegen.Result {
|
||||
_ = src_loc;
|
||||
const mod = bin_file.options.module.?;
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
var code_gen: CodeGen = .{
|
||||
.gpa = bin_file.allocator,
|
||||
.air = air,
|
||||
|
|
@ -1223,7 +1223,7 @@ pub fn generate(
|
|||
.target = bin_file.options.target,
|
||||
.bin_file = bin_file.cast(link.File.Wasm).?,
|
||||
.debug_output = debug_output,
|
||||
.mod_fn = func,
|
||||
.func_index = func_index,
|
||||
};
|
||||
defer code_gen.deinit();
|
||||
|
||||
|
|
@ -1237,8 +1237,9 @@ pub fn generate(
|
|||
|
||||
fn genFunc(func: *CodeGen) InnerError!void {
|
||||
const mod = func.bin_file.base.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(func.decl.ty).?;
|
||||
var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type.toType(), mod);
|
||||
var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), fn_info.return_type.toType(), mod);
|
||||
defer func_type.deinit(func.gpa);
|
||||
_ = try func.bin_file.storeDeclType(func.decl_index, func_type);
|
||||
|
||||
|
|
@ -1347,6 +1348,7 @@ const CallWValues = struct {
|
|||
|
||||
fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {
|
||||
const mod = func.bin_file.base.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(fn_ty).?;
|
||||
const cc = fn_info.cc;
|
||||
var result: CallWValues = .{
|
||||
|
|
@ -1369,7 +1371,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
|
|||
|
||||
switch (cc) {
|
||||
.Unspecified => {
|
||||
for (fn_info.param_types) |ty| {
|
||||
for (fn_info.param_types.get(ip)) |ty| {
|
||||
if (!ty.toType().hasRuntimeBitsIgnoreComptime(mod)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1379,7 +1381,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
|
|||
}
|
||||
},
|
||||
.C => {
|
||||
for (fn_info.param_types) |ty| {
|
||||
for (fn_info.param_types.get(ip)) |ty| {
|
||||
const ty_classes = abi.classifyType(ty.toType(), mod);
|
||||
for (ty_classes) |class| {
|
||||
if (class == .none) continue;
|
||||
|
|
@ -2185,6 +2187,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
|
|||
const ty = func.typeOf(pl_op.operand);
|
||||
|
||||
const mod = func.bin_file.base.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_ty = switch (ty.zigTypeTag(mod)) {
|
||||
.Fn => ty,
|
||||
.Pointer => ty.childType(mod),
|
||||
|
|
@ -2203,7 +2206,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
|
|||
} else if (func_val.getExternFunc(mod)) |extern_func| {
|
||||
const ext_decl = mod.declPtr(extern_func.decl);
|
||||
const ext_info = mod.typeToFunc(ext_decl.ty).?;
|
||||
var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type.toType(), mod);
|
||||
var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), ext_info.return_type.toType(), mod);
|
||||
defer func_type.deinit(func.gpa);
|
||||
const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl);
|
||||
const atom = func.bin_file.getAtomPtr(atom_index);
|
||||
|
|
@ -2253,7 +2256,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
|
|||
const operand = try func.resolveInst(pl_op.operand);
|
||||
try func.emitWValue(operand);
|
||||
|
||||
var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type.toType(), mod);
|
||||
var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), fn_info.return_type.toType(), mod);
|
||||
defer fn_type.deinit(func.gpa);
|
||||
|
||||
const fn_type_index = try func.bin_file.putOrGetFuncType(fn_type);
|
||||
|
|
@ -2564,8 +2567,8 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
switch (func.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
const src_index = func.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, src_index);
|
||||
try dwarf.genArgDbgInfo(name, arg_ty, func.mod_fn.owner_decl, .{
|
||||
const name = mod.getParamName(func.func_index, src_index);
|
||||
try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
|
||||
.wasm_local = arg.local.value,
|
||||
});
|
||||
},
|
||||
|
|
@ -6198,6 +6201,7 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||
fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
|
||||
if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
|
||||
|
||||
const mod = func.bin_file.base.options.module.?;
|
||||
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
|
||||
const ty = func.typeOf(pl_op.operand);
|
||||
const operand = try func.resolveInst(pl_op.operand);
|
||||
|
|
@ -6214,7 +6218,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
|
|||
break :blk .nop;
|
||||
},
|
||||
};
|
||||
try func.debug_output.dwarf.genVarDbgInfo(name, ty, func.mod_fn.owner_decl, is_ptr, loc);
|
||||
try func.debug_output.dwarf.genVarDbgInfo(name, ty, mod.funcOwnerDeclIndex(func.func_index), is_ptr, loc);
|
||||
|
||||
func.finishAir(inst, .none, &.{});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,20 +110,21 @@ const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
|
|||
const RegisterOffset = struct { reg: Register, off: i32 = 0 };
|
||||
|
||||
const Owner = union(enum) {
|
||||
mod_fn: *const Module.Fn,
|
||||
func_index: InternPool.Index,
|
||||
lazy_sym: link.File.LazySymbol,
|
||||
|
||||
fn getDecl(owner: Owner, mod: *Module) Module.Decl.Index {
|
||||
return switch (owner) {
|
||||
.mod_fn => |mod_fn| mod_fn.owner_decl,
|
||||
.func_index => |func_index| mod.funcOwnerDeclIndex(func_index),
|
||||
.lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(mod),
|
||||
};
|
||||
}
|
||||
|
||||
fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {
|
||||
switch (owner) {
|
||||
.mod_fn => |mod_fn| {
|
||||
const decl_index = mod_fn.owner_decl;
|
||||
.func_index => |func_index| {
|
||||
const mod = ctx.bin_file.options.module.?;
|
||||
const decl_index = mod.funcOwnerDeclIndex(func_index);
|
||||
if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
|
||||
return macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
|
|
@ -638,7 +639,7 @@ const Self = @This();
|
|||
pub fn generate(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
module_fn_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
@ -649,8 +650,8 @@ pub fn generate(
|
|||
}
|
||||
|
||||
const mod = bin_file.options.module.?;
|
||||
const module_fn = mod.funcPtr(module_fn_index);
|
||||
const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const fn_owner_decl = mod.declPtr(func.owner_decl);
|
||||
assert(fn_owner_decl.has_tv);
|
||||
const fn_type = fn_owner_decl.ty;
|
||||
|
||||
|
|
@ -662,15 +663,15 @@ pub fn generate(
|
|||
.target = &bin_file.options.target,
|
||||
.bin_file = bin_file,
|
||||
.debug_output = debug_output,
|
||||
.owner = .{ .mod_fn = module_fn },
|
||||
.owner = .{ .func_index = func_index },
|
||||
.err_msg = null,
|
||||
.args = undefined, // populated after `resolveCallingConventionValues`
|
||||
.ret_mcv = undefined, // populated after `resolveCallingConventionValues`
|
||||
.fn_type = fn_type,
|
||||
.arg_index = 0,
|
||||
.src_loc = src_loc,
|
||||
.end_di_line = module_fn.rbrace_line,
|
||||
.end_di_column = module_fn.rbrace_column,
|
||||
.end_di_line = func.rbrace_line,
|
||||
.end_di_column = func.rbrace_column,
|
||||
};
|
||||
defer {
|
||||
function.frame_allocs.deinit(gpa);
|
||||
|
|
@ -687,17 +688,16 @@ pub fn generate(
|
|||
if (builtin.mode == .Debug) function.mir_to_air_map.deinit(gpa);
|
||||
}
|
||||
|
||||
wip_mir_log.debug("{}:", .{function.fmtDecl(module_fn.owner_decl)});
|
||||
wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)});
|
||||
|
||||
const ip = &mod.intern_pool;
|
||||
|
||||
try function.frame_allocs.resize(gpa, FrameIndex.named_count);
|
||||
function.frame_allocs.set(
|
||||
@intFromEnum(FrameIndex.stack_frame),
|
||||
FrameAlloc.init(.{
|
||||
.size = 0,
|
||||
.alignment = if (mod.align_stack_fns.get(module_fn_index)) |set_align_stack|
|
||||
@intCast(set_align_stack.alignment.toByteUnitsOptional().?)
|
||||
else
|
||||
1,
|
||||
.alignment = @intCast(func.analysis(ip).stack_alignment.toByteUnitsOptional() orelse 1),
|
||||
}),
|
||||
);
|
||||
function.frame_allocs.set(
|
||||
|
|
@ -761,8 +761,8 @@ pub fn generate(
|
|||
.debug_output = debug_output,
|
||||
.code = code,
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_line = module_fn.lbrace_line,
|
||||
.prev_di_column = module_fn.lbrace_column,
|
||||
.prev_di_line = func.lbrace_line,
|
||||
.prev_di_column = func.lbrace_column,
|
||||
};
|
||||
defer emit.deinit();
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
|
|
@ -7942,7 +7942,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
|||
|
||||
const ty = self.typeOfIndex(inst);
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = self.owner.mod_fn.getParamName(mod, src_index);
|
||||
const name = mod.getParamName(self.owner.func_index, src_index);
|
||||
try self.genArgDbgInfo(ty, name, dst_mcv);
|
||||
|
||||
break :result dst_mcv;
|
||||
|
|
@ -8139,7 +8139,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
|
|||
if (try self.air.value(callee, mod)) |func_value| {
|
||||
const func_key = mod.intern_pool.indexToKey(func_value.ip_index);
|
||||
if (switch (func_key) {
|
||||
.func => |func| mod.funcPtr(func.index).owner_decl,
|
||||
.func => |func| func.owner_decl,
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
.decl => |decl| decl,
|
||||
else => null,
|
||||
|
|
@ -8582,9 +8582,9 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
|
|||
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const function = mod.funcPtr(ty_fn.func);
|
||||
const func = mod.funcInfo(ty_fn.func);
|
||||
// TODO emit debug info for function change
|
||||
_ = function;
|
||||
_ = func;
|
||||
return self.finishAir(inst, .unreach, .{ .none, .none, .none });
|
||||
}
|
||||
|
||||
|
|
@ -11719,11 +11719,12 @@ fn resolveCallingConventionValues(
|
|||
stack_frame_base: FrameIndex,
|
||||
) !CallMCValues {
|
||||
const mod = self.bin_file.options.module.?;
|
||||
const ip = &mod.intern_pool;
|
||||
const cc = fn_info.cc;
|
||||
const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len);
|
||||
defer self.gpa.free(param_types);
|
||||
|
||||
for (param_types[0..fn_info.param_types.len], fn_info.param_types) |*dest, src| {
|
||||
for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src| {
|
||||
dest.* = src.toType();
|
||||
}
|
||||
// TODO: promote var arg types
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ pub const DebugInfoOutput = union(enum) {
|
|||
pub fn generateFunction(
|
||||
bin_file: *link.File,
|
||||
src_loc: Module.SrcLoc,
|
||||
func_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
code: *std.ArrayList(u8),
|
||||
|
|
|
|||
|
|
@ -257,7 +257,8 @@ pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
|
|||
return .{ .data = ident };
|
||||
}
|
||||
|
||||
/// This data is available when outputting .c code for a `Module.Fn.Index`.
|
||||
/// This data is available when outputting .c code for a `InternPool.Index`
|
||||
/// that corresponds to `func`.
|
||||
/// It is not available when generating .h file.
|
||||
pub const Function = struct {
|
||||
air: Air,
|
||||
|
|
@ -268,7 +269,7 @@ pub const Function = struct {
|
|||
next_block_index: usize = 0,
|
||||
object: Object,
|
||||
lazy_fns: LazyFnMap,
|
||||
func_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
/// All the locals, to be emitted at the top of the function.
|
||||
locals: std.ArrayListUnmanaged(Local) = .{},
|
||||
/// Which locals are available for reuse, based on Type.
|
||||
|
|
@ -1487,6 +1488,7 @@ pub const DeclGen = struct {
|
|||
) !void {
|
||||
const store = &dg.ctypes.set;
|
||||
const mod = dg.module;
|
||||
const ip = &mod.intern_pool;
|
||||
|
||||
const fn_decl = mod.declPtr(fn_decl_index);
|
||||
const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind);
|
||||
|
|
@ -1499,7 +1501,7 @@ pub const DeclGen = struct {
|
|||
else => unreachable,
|
||||
}
|
||||
}
|
||||
if (fn_decl.val.getFunction(mod)) |func| if (func.is_cold) try w.writeAll("zig_cold ");
|
||||
if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) try w.writeAll("zig_cold ");
|
||||
if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
|
||||
|
||||
const trailing = try renderTypePrefix(
|
||||
|
|
@ -1744,7 +1746,7 @@ pub const DeclGen = struct {
|
|||
return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
|
||||
.variable => |variable| mod.decl_exports.contains(variable.decl),
|
||||
.extern_func => true,
|
||||
.func => |func| mod.decl_exports.contains(mod.funcPtr(func.index).owner_decl),
|
||||
.func => |func| mod.decl_exports.contains(func.owner_decl),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
|
@ -4161,7 +4163,7 @@ fn airCall(
|
|||
const callee_val = (try f.air.value(pl_op.operand, mod)) orelse break :known;
|
||||
break :fn_decl switch (mod.intern_pool.indexToKey(callee_val.ip_index)) {
|
||||
.extern_func => |extern_func| extern_func.decl,
|
||||
.func => |func| mod.funcPtr(func.index).owner_decl,
|
||||
.func => |func| func.owner_decl,
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
.decl => |decl| decl,
|
||||
else => break :known,
|
||||
|
|
@ -4238,9 +4240,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||
const ty_fn = f.air.instructions.items(.data)[inst].ty_fn;
|
||||
const mod = f.object.dg.module;
|
||||
const writer = f.object.writer();
|
||||
const function = mod.funcPtr(ty_fn.func);
|
||||
const owner_decl = mod.funcOwnerDeclPtr(ty_fn.func);
|
||||
try writer.print("/* dbg func:{s} */\n", .{
|
||||
mod.intern_pool.stringToSlice(mod.declPtr(function.owner_decl).name),
|
||||
mod.intern_pool.stringToSlice(owner_decl.name),
|
||||
});
|
||||
return .none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1722,6 +1722,7 @@ pub const CType = extern union {
|
|||
|
||||
.Fn => {
|
||||
const info = mod.typeToFunc(ty).?;
|
||||
const ip = &mod.intern_pool;
|
||||
if (!info.is_generic) {
|
||||
if (lookup.isMutable()) {
|
||||
const param_kind: Kind = switch (kind) {
|
||||
|
|
@ -1730,7 +1731,7 @@ pub const CType = extern union {
|
|||
.payload => unreachable,
|
||||
};
|
||||
_ = try lookup.typeToIndex(info.return_type.toType(), param_kind);
|
||||
for (info.param_types) |param_type| {
|
||||
for (info.param_types.get(ip)) |param_type| {
|
||||
if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
_ = try lookup.typeToIndex(param_type.toType(), param_kind);
|
||||
}
|
||||
|
|
@ -2014,6 +2015,7 @@ pub const CType = extern union {
|
|||
.function,
|
||||
.varargs_function,
|
||||
=> {
|
||||
const ip = &mod.intern_pool;
|
||||
const info = mod.typeToFunc(ty).?;
|
||||
assert(!info.is_generic);
|
||||
const param_kind: Kind = switch (kind) {
|
||||
|
|
@ -2023,14 +2025,14 @@ pub const CType = extern union {
|
|||
};
|
||||
|
||||
var c_params_len: usize = 0;
|
||||
for (info.param_types) |param_type| {
|
||||
for (info.param_types.get(ip)) |param_type| {
|
||||
if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
c_params_len += 1;
|
||||
}
|
||||
|
||||
const params_pl = try arena.alloc(Index, c_params_len);
|
||||
var c_param_i: usize = 0;
|
||||
for (info.param_types) |param_type| {
|
||||
for (info.param_types.get(ip)) |param_type| {
|
||||
if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
params_pl[c_param_i] = store.set.typeToIndex(param_type.toType(), mod, param_kind).?;
|
||||
c_param_i += 1;
|
||||
|
|
@ -2147,6 +2149,7 @@ pub const CType = extern union {
|
|||
=> {
|
||||
if (ty.zigTypeTag(mod) != .Fn) return false;
|
||||
|
||||
const ip = &mod.intern_pool;
|
||||
const info = mod.typeToFunc(ty).?;
|
||||
assert(!info.is_generic);
|
||||
const data = cty.cast(Payload.Function).?.data;
|
||||
|
|
@ -2160,7 +2163,7 @@ pub const CType = extern union {
|
|||
return false;
|
||||
|
||||
var c_param_i: usize = 0;
|
||||
for (info.param_types) |param_type| {
|
||||
for (info.param_types.get(ip)) |param_type| {
|
||||
if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
|
||||
if (c_param_i >= data.param_types.len) return false;
|
||||
|
|
@ -2202,6 +2205,7 @@ pub const CType = extern union {
|
|||
autoHash(hasher, t);
|
||||
|
||||
const mod = self.lookup.getModule();
|
||||
const ip = &mod.intern_pool;
|
||||
switch (t) {
|
||||
.fwd_anon_struct,
|
||||
.fwd_anon_union,
|
||||
|
|
@ -2270,7 +2274,7 @@ pub const CType = extern union {
|
|||
};
|
||||
|
||||
self.updateHasherRecurse(hasher, info.return_type.toType(), param_kind);
|
||||
for (info.param_types) |param_type| {
|
||||
for (info.param_types.get(ip)) |param_type| {
|
||||
if (!param_type.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
self.updateHasherRecurse(hasher, param_type.toType(), param_kind);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -867,14 +867,15 @@ pub const Object = struct {
|
|||
pub fn updateFunc(
|
||||
o: *Object,
|
||||
mod: *Module,
|
||||
func_index: Module.Fn.Index,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
) !void {
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const target = mod.getTarget();
|
||||
const ip = &mod.intern_pool;
|
||||
|
||||
var dg: DeclGen = .{
|
||||
.object = o,
|
||||
|
|
@ -885,26 +886,25 @@ pub const Object = struct {
|
|||
|
||||
const llvm_func = try o.resolveLlvmFunction(decl_index);
|
||||
|
||||
if (mod.align_stack_fns.get(func_index)) |align_info| {
|
||||
o.addFnAttrInt(llvm_func, "alignstack", align_info.alignment.toByteUnitsOptional().?);
|
||||
o.addFnAttr(llvm_func, "noinline");
|
||||
} else {
|
||||
Object.removeFnAttr(llvm_func, "alignstack");
|
||||
if (!func.is_noinline) Object.removeFnAttr(llvm_func, "noinline");
|
||||
}
|
||||
|
||||
if (func.is_cold) {
|
||||
o.addFnAttr(llvm_func, "cold");
|
||||
} else {
|
||||
Object.removeFnAttr(llvm_func, "cold");
|
||||
}
|
||||
|
||||
if (func.is_noinline) {
|
||||
if (func.analysis(ip).is_noinline) {
|
||||
o.addFnAttr(llvm_func, "noinline");
|
||||
} else {
|
||||
Object.removeFnAttr(llvm_func, "noinline");
|
||||
}
|
||||
|
||||
if (func.analysis(ip).stack_alignment.toByteUnitsOptional()) |alignment| {
|
||||
o.addFnAttrInt(llvm_func, "alignstack", alignment);
|
||||
o.addFnAttr(llvm_func, "noinline");
|
||||
} else {
|
||||
Object.removeFnAttr(llvm_func, "alignstack");
|
||||
}
|
||||
|
||||
if (func.analysis(ip).is_cold) {
|
||||
o.addFnAttr(llvm_func, "cold");
|
||||
} else {
|
||||
Object.removeFnAttr(llvm_func, "cold");
|
||||
}
|
||||
|
||||
// TODO: disable this if safety is off for the function scope
|
||||
const ssp_buf_size = mod.comp.bin_file.options.stack_protector;
|
||||
if (ssp_buf_size != 0) {
|
||||
|
|
@ -921,7 +921,7 @@ pub const Object = struct {
|
|||
o.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
|
||||
}
|
||||
|
||||
if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|
|
||||
if (ip.stringToSliceUnwrap(decl.@"linksection")) |section|
|
||||
llvm_func.setSection(section);
|
||||
|
||||
// Remove all the basic blocks of a function in order to start over, generating
|
||||
|
|
@ -968,7 +968,7 @@ pub const Object = struct {
|
|||
.byval => {
|
||||
assert(!it.byval_attr);
|
||||
const param_index = it.zig_index - 1;
|
||||
const param_ty = fn_info.param_types[param_index].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[param_index].toType();
|
||||
const param = llvm_func.getParam(llvm_arg_i);
|
||||
try args.ensureUnusedCapacity(1);
|
||||
|
||||
|
|
@ -987,7 +987,7 @@ pub const Object = struct {
|
|||
llvm_arg_i += 1;
|
||||
},
|
||||
.byref => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const param_llvm_ty = try o.lowerType(param_ty);
|
||||
const param = llvm_func.getParam(llvm_arg_i);
|
||||
const alignment = param_ty.abiAlignment(mod);
|
||||
|
|
@ -1006,7 +1006,7 @@ pub const Object = struct {
|
|||
}
|
||||
},
|
||||
.byref_mut => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const param_llvm_ty = try o.lowerType(param_ty);
|
||||
const param = llvm_func.getParam(llvm_arg_i);
|
||||
const alignment = param_ty.abiAlignment(mod);
|
||||
|
|
@ -1026,7 +1026,7 @@ pub const Object = struct {
|
|||
},
|
||||
.abi_sized_int => {
|
||||
assert(!it.byval_attr);
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const param = llvm_func.getParam(llvm_arg_i);
|
||||
llvm_arg_i += 1;
|
||||
|
||||
|
|
@ -1053,7 +1053,7 @@ pub const Object = struct {
|
|||
},
|
||||
.slice => {
|
||||
assert(!it.byval_attr);
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const ptr_info = param_ty.ptrInfo(mod);
|
||||
|
||||
if (math.cast(u5, it.zig_index - 1)) |i| {
|
||||
|
|
@ -1083,7 +1083,7 @@ pub const Object = struct {
|
|||
.multiple_llvm_types => {
|
||||
assert(!it.byval_attr);
|
||||
const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const param_llvm_ty = try o.lowerType(param_ty);
|
||||
const param_alignment = param_ty.abiAlignment(mod);
|
||||
const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
|
||||
|
|
@ -1114,7 +1114,7 @@ pub const Object = struct {
|
|||
args.appendAssumeCapacity(casted);
|
||||
},
|
||||
.float_array => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const param_llvm_ty = try o.lowerType(param_ty);
|
||||
const param = llvm_func.getParam(llvm_arg_i);
|
||||
llvm_arg_i += 1;
|
||||
|
|
@ -1132,7 +1132,7 @@ pub const Object = struct {
|
|||
}
|
||||
},
|
||||
.i32_array, .i64_array => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const param_llvm_ty = try o.lowerType(param_ty);
|
||||
const param = llvm_func.getParam(llvm_arg_i);
|
||||
llvm_arg_i += 1;
|
||||
|
|
@ -1168,7 +1168,7 @@ pub const Object = struct {
|
|||
const decl_di_ty = try o.lowerDebugType(decl.ty, .full);
|
||||
const subprogram = dib.createFunction(
|
||||
di_file.?.toScope(),
|
||||
mod.intern_pool.stringToSlice(decl.name),
|
||||
ip.stringToSlice(decl.name),
|
||||
llvm_func.getValueName(),
|
||||
di_file.?,
|
||||
line_number,
|
||||
|
|
@ -1460,6 +1460,7 @@ pub const Object = struct {
|
|||
const target = o.target;
|
||||
const dib = o.di_builder.?;
|
||||
const mod = o.module;
|
||||
const ip = &mod.intern_pool;
|
||||
switch (ty.zigTypeTag(mod)) {
|
||||
.Void, .NoReturn => {
|
||||
const di_type = dib.createBasicType("void", 0, DW.ATE.signed);
|
||||
|
|
@ -1492,7 +1493,6 @@ pub const Object = struct {
|
|||
return enum_di_ty;
|
||||
}
|
||||
|
||||
const ip = &mod.intern_pool;
|
||||
const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
|
||||
|
||||
const enumerators = try gpa.alloc(*llvm.DIEnumerator, enum_type.names.len);
|
||||
|
|
@ -1518,7 +1518,7 @@ pub const Object = struct {
|
|||
if (@sizeOf(usize) == @sizeOf(u64)) {
|
||||
enumerators[i] = dib.createEnumerator2(
|
||||
field_name_z,
|
||||
@as(c_uint, @intCast(bigint.limbs.len)),
|
||||
@intCast(bigint.limbs.len),
|
||||
bigint.limbs.ptr,
|
||||
int_info.bits,
|
||||
int_info.signedness == .unsigned,
|
||||
|
|
@ -2320,8 +2320,8 @@ pub const Object = struct {
|
|||
try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
|
||||
}
|
||||
|
||||
for (0..mod.typeToFunc(ty).?.param_types.len) |i| {
|
||||
const param_ty = mod.typeToFunc(ty).?.param_types[i].toType();
|
||||
for (0..fn_info.param_types.len) |i| {
|
||||
const param_ty = fn_info.param_types.get(ip)[i].toType();
|
||||
if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
|
||||
|
||||
if (isByRef(param_ty, mod)) {
|
||||
|
|
@ -2475,9 +2475,10 @@ pub const Object = struct {
|
|||
const fn_type = try o.lowerType(zig_fn_type);
|
||||
|
||||
const fqn = try decl.getFullyQualifiedName(mod);
|
||||
const ip = &mod.intern_pool;
|
||||
|
||||
const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
|
||||
const llvm_fn = o.llvm_module.addFunctionInAddressSpace(mod.intern_pool.stringToSlice(fqn), fn_type, llvm_addrspace);
|
||||
const llvm_fn = o.llvm_module.addFunctionInAddressSpace(ip.stringToSlice(fqn), fn_type, llvm_addrspace);
|
||||
gop.value_ptr.* = llvm_fn;
|
||||
|
||||
const is_extern = decl.isExtern(mod);
|
||||
|
|
@ -2486,8 +2487,8 @@ pub const Object = struct {
|
|||
llvm_fn.setUnnamedAddr(.True);
|
||||
} else {
|
||||
if (target.isWasm()) {
|
||||
o.addFnAttrString(llvm_fn, "wasm-import-name", mod.intern_pool.stringToSlice(decl.name));
|
||||
if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
|
||||
o.addFnAttrString(llvm_fn, "wasm-import-name", ip.stringToSlice(decl.name));
|
||||
if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
|
||||
if (!std.mem.eql(u8, lib_name, "c")) {
|
||||
o.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
|
||||
}
|
||||
|
|
@ -2546,13 +2547,13 @@ pub const Object = struct {
|
|||
while (it.next()) |lowering| switch (lowering) {
|
||||
.byval => {
|
||||
const param_index = it.zig_index - 1;
|
||||
const param_ty = fn_info.param_types[param_index].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[param_index].toType();
|
||||
if (!isByRef(param_ty, mod)) {
|
||||
o.addByValParamAttrs(llvm_fn, param_ty, param_index, fn_info, it.llvm_index - 1);
|
||||
}
|
||||
},
|
||||
.byref => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1];
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1];
|
||||
const param_llvm_ty = try o.lowerType(param_ty.toType());
|
||||
const alignment = param_ty.toType().abiAlignment(mod);
|
||||
o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
|
||||
|
|
@ -3031,6 +3032,7 @@ pub const Object = struct {
|
|||
|
||||
fn lowerTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type {
|
||||
const mod = o.module;
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(fn_ty).?;
|
||||
const llvm_ret_ty = try lowerFnRetTy(o, fn_info);
|
||||
|
||||
|
|
@ -3052,19 +3054,19 @@ pub const Object = struct {
|
|||
while (it.next()) |lowering| switch (lowering) {
|
||||
.no_bits => continue,
|
||||
.byval => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
try llvm_params.append(try o.lowerType(param_ty));
|
||||
},
|
||||
.byref, .byref_mut => {
|
||||
try llvm_params.append(o.context.pointerType(0));
|
||||
},
|
||||
.abi_sized_int => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));
|
||||
try llvm_params.append(o.context.intType(abi_size * 8));
|
||||
},
|
||||
.slice => {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)
|
||||
param_ty.optionalChild(mod).slicePtrFieldType(mod)
|
||||
else
|
||||
|
|
@ -3083,7 +3085,7 @@ pub const Object = struct {
|
|||
try llvm_params.append(o.context.intType(16));
|
||||
},
|
||||
.float_array => |count| {
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?);
|
||||
const field_count = @as(c_uint, @intCast(count));
|
||||
const arr_ty = float_ty.arrayType(field_count);
|
||||
|
|
@ -3137,8 +3139,7 @@ pub const Object = struct {
|
|||
return llvm_type.getUndef();
|
||||
}
|
||||
|
||||
const val_key = mod.intern_pool.indexToKey(tv.val.toIntern());
|
||||
switch (val_key) {
|
||||
switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
|
||||
.int_type,
|
||||
.ptr_type,
|
||||
.array_type,
|
||||
|
|
@ -3175,12 +3176,14 @@ pub const Object = struct {
|
|||
.enum_literal,
|
||||
.empty_enum_value,
|
||||
=> unreachable, // non-runtime values
|
||||
.extern_func, .func => {
|
||||
const fn_decl_index = switch (val_key) {
|
||||
.extern_func => |extern_func| extern_func.decl,
|
||||
.func => |func| mod.funcPtr(func.index).owner_decl,
|
||||
else => unreachable,
|
||||
};
|
||||
.extern_func => |extern_func| {
|
||||
const fn_decl_index = extern_func.decl;
|
||||
const fn_decl = mod.declPtr(fn_decl_index);
|
||||
try mod.markDeclAlive(fn_decl);
|
||||
return o.resolveLlvmFunction(fn_decl_index);
|
||||
},
|
||||
.func => |func| {
|
||||
const fn_decl_index = func.owner_decl;
|
||||
const fn_decl = mod.declPtr(fn_decl_index);
|
||||
try mod.markDeclAlive(fn_decl);
|
||||
return o.resolveLlvmFunction(fn_decl_index);
|
||||
|
|
@ -4598,6 +4601,7 @@ pub const FuncGen = struct {
|
|||
const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
|
||||
const o = self.dg.object;
|
||||
const mod = o.module;
|
||||
const ip = &mod.intern_pool;
|
||||
const callee_ty = self.typeOf(pl_op.operand);
|
||||
const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) {
|
||||
.Fn => callee_ty,
|
||||
|
|
@ -4801,14 +4805,14 @@ pub const FuncGen = struct {
|
|||
while (it.next()) |lowering| switch (lowering) {
|
||||
.byval => {
|
||||
const param_index = it.zig_index - 1;
|
||||
const param_ty = fn_info.param_types[param_index].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[param_index].toType();
|
||||
if (!isByRef(param_ty, mod)) {
|
||||
o.addByValParamAttrs(call, param_ty, param_index, fn_info, it.llvm_index - 1);
|
||||
}
|
||||
},
|
||||
.byref => {
|
||||
const param_index = it.zig_index - 1;
|
||||
const param_ty = fn_info.param_types[param_index].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[param_index].toType();
|
||||
const param_llvm_ty = try o.lowerType(param_ty);
|
||||
const alignment = param_ty.abiAlignment(mod);
|
||||
o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
|
||||
|
|
@ -4828,7 +4832,7 @@ pub const FuncGen = struct {
|
|||
|
||||
.slice => {
|
||||
assert(!it.byval_attr);
|
||||
const param_ty = fn_info.param_types[it.zig_index - 1].toType();
|
||||
const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
|
||||
const ptr_info = param_ty.ptrInfo(mod);
|
||||
const llvm_arg_i = it.llvm_index - 2;
|
||||
|
||||
|
|
@ -4930,7 +4934,7 @@ pub const FuncGen = struct {
|
|||
fg.context.pointerType(0).constNull(),
|
||||
null_opt_addr_global,
|
||||
};
|
||||
const panic_func = mod.funcPtrUnwrap(mod.panic_func_index).?;
|
||||
const panic_func = mod.funcInfo(mod.panic_func_index);
|
||||
const panic_decl = mod.declPtr(panic_func.owner_decl);
|
||||
const fn_info = mod.typeToFunc(panic_decl.ty).?;
|
||||
const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl);
|
||||
|
|
@ -6030,7 +6034,7 @@ pub const FuncGen = struct {
|
|||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
|
||||
const mod = o.module;
|
||||
const func = mod.funcPtr(ty_fn.func);
|
||||
const func = mod.funcInfo(ty_fn.func);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
|
|
@ -6039,7 +6043,7 @@ pub const FuncGen = struct {
|
|||
const cur_debug_location = self.builder.getCurrentDebugLocation2();
|
||||
|
||||
try self.dbg_inlined.append(self.gpa, .{
|
||||
.loc = @as(*llvm.DILocation, @ptrCast(cur_debug_location)),
|
||||
.loc = @ptrCast(cur_debug_location),
|
||||
.scope = self.di_scope.?,
|
||||
.base_line = self.base_line,
|
||||
});
|
||||
|
|
@ -6090,8 +6094,7 @@ pub const FuncGen = struct {
|
|||
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
|
||||
|
||||
const mod = o.module;
|
||||
const func = mod.funcPtr(ty_fn.func);
|
||||
const decl = mod.declPtr(func.owner_decl);
|
||||
const decl = mod.funcOwnerDeclPtr(ty_fn.func);
|
||||
const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
|
||||
self.di_file = di_file;
|
||||
const old = self.dbg_inlined.pop();
|
||||
|
|
@ -8137,12 +8140,13 @@ pub const FuncGen = struct {
|
|||
}
|
||||
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const func = self.dg.decl.getOwnedFunction(mod).?;
|
||||
const func_index = self.dg.decl.getOwnedFunctionIndex();
|
||||
const func = mod.funcInfo(func_index);
|
||||
const lbrace_line = mod.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
|
||||
const lbrace_col = func.lbrace_column + 1;
|
||||
const di_local_var = dib.createParameterVariable(
|
||||
self.di_scope.?,
|
||||
func.getParamName(mod, src_index).ptr, // TODO test 0 bit args
|
||||
mod.getParamName(func_index, src_index).ptr, // TODO test 0 bit args
|
||||
self.di_file.?,
|
||||
lbrace_line,
|
||||
try o.lowerDebugType(inst_ty, .full),
|
||||
|
|
@ -10888,13 +10892,17 @@ const ParamTypeIterator = struct {
|
|||
|
||||
pub fn next(it: *ParamTypeIterator) ?Lowering {
|
||||
if (it.zig_index >= it.fn_info.param_types.len) return null;
|
||||
const ty = it.fn_info.param_types[it.zig_index];
|
||||
const mod = it.object.module;
|
||||
const ip = &mod.intern_pool;
|
||||
const ty = it.fn_info.param_types.get(ip)[it.zig_index];
|
||||
it.byval_attr = false;
|
||||
return nextInner(it, ty.toType());
|
||||
}
|
||||
|
||||
/// `airCall` uses this instead of `next` so that it can take into account variadic functions.
|
||||
pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) ?Lowering {
|
||||
const mod = it.object.module;
|
||||
const ip = &mod.intern_pool;
|
||||
if (it.zig_index >= it.fn_info.param_types.len) {
|
||||
if (it.zig_index >= args.len) {
|
||||
return null;
|
||||
|
|
@ -10902,7 +10910,7 @@ const ParamTypeIterator = struct {
|
|||
return nextInner(it, fg.typeOf(args[it.zig_index]));
|
||||
}
|
||||
} else {
|
||||
return nextInner(it, it.fn_info.param_types[it.zig_index].toType());
|
||||
return nextInner(it, it.fn_info.param_types.get(ip)[it.zig_index].toType());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ pub const DeclGen = struct {
|
|||
if (ty.zigTypeTag(mod) == .Fn) {
|
||||
const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) {
|
||||
.extern_func => |extern_func| extern_func.decl,
|
||||
.func => |func| mod.funcPtr(func.index).owner_decl,
|
||||
.func => |func| func.owner_decl,
|
||||
else => unreachable,
|
||||
};
|
||||
const spv_decl_index = try self.resolveDecl(fn_decl_index);
|
||||
|
|
@ -255,13 +255,14 @@ pub const DeclGen = struct {
|
|||
/// Fetch or allocate a result id for decl index. This function also marks the decl as alive.
|
||||
/// Note: Function does not actually generate the decl.
|
||||
fn resolveDecl(self: *DeclGen, decl_index: Module.Decl.Index) !SpvModule.Decl.Index {
|
||||
const decl = self.module.declPtr(decl_index);
|
||||
try self.module.markDeclAlive(decl);
|
||||
const mod = self.module;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
try mod.markDeclAlive(decl);
|
||||
|
||||
const entry = try self.decl_link.getOrPut(decl_index);
|
||||
if (!entry.found_existing) {
|
||||
// TODO: Extern fn?
|
||||
const kind: SpvModule.DeclKind = if (decl.val.getFunctionIndex(self.module) != .none)
|
||||
const kind: SpvModule.DeclKind = if (decl.val.isFuncBody(mod))
|
||||
.func
|
||||
else
|
||||
.global;
|
||||
|
|
@ -1268,6 +1269,7 @@ pub const DeclGen = struct {
|
|||
},
|
||||
.Fn => switch (repr) {
|
||||
.direct => {
|
||||
const ip = &mod.intern_pool;
|
||||
const fn_info = mod.typeToFunc(ty).?;
|
||||
// TODO: Put this somewhere in Sema.zig
|
||||
if (fn_info.is_var_args)
|
||||
|
|
@ -1275,8 +1277,8 @@ pub const DeclGen = struct {
|
|||
|
||||
const param_ty_refs = try self.gpa.alloc(CacheRef, fn_info.param_types.len);
|
||||
defer self.gpa.free(param_ty_refs);
|
||||
for (param_ty_refs, 0..) |*param_type, i| {
|
||||
param_type.* = try self.resolveType(fn_info.param_types[i].toType(), .direct);
|
||||
for (param_ty_refs, fn_info.param_types.get(ip)) |*param_type, fn_param_type| {
|
||||
param_type.* = try self.resolveType(fn_param_type.toType(), .direct);
|
||||
}
|
||||
const return_ty_ref = try self.resolveType(fn_info.return_type.toType(), .direct);
|
||||
|
||||
|
|
@ -1576,6 +1578,7 @@ pub const DeclGen = struct {
|
|||
|
||||
fn genDecl(self: *DeclGen) !void {
|
||||
const mod = self.module;
|
||||
const ip = &mod.intern_pool;
|
||||
const decl = mod.declPtr(self.decl_index);
|
||||
const spv_decl_index = try self.resolveDecl(self.decl_index);
|
||||
|
||||
|
|
@ -1594,7 +1597,8 @@ pub const DeclGen = struct {
|
|||
const fn_info = mod.typeToFunc(decl.ty).?;
|
||||
|
||||
try self.args.ensureUnusedCapacity(self.gpa, fn_info.param_types.len);
|
||||
for (fn_info.param_types) |param_type| {
|
||||
for (0..fn_info.param_types.len) |i| {
|
||||
const param_type = fn_info.param_types.get(ip)[i];
|
||||
const param_type_id = try self.resolveTypeId(param_type.toType());
|
||||
const arg_result_id = self.spv.allocId();
|
||||
try self.func.prologue.emit(self.spv.gpa, .OpFunctionParameter, .{
|
||||
|
|
@ -1621,7 +1625,7 @@ pub const DeclGen = struct {
|
|||
try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
|
||||
try self.spv.addFunction(spv_decl_index, self.func);
|
||||
|
||||
const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(self.module));
|
||||
const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));
|
||||
|
||||
try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{
|
||||
.target = decl_id,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ const Compilation = @import("Compilation.zig");
|
|||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||
const Liveness = @import("Liveness.zig");
|
||||
const Module = @import("Module.zig");
|
||||
const InternPool = @import("InternPool.zig");
|
||||
const Package = @import("Package.zig");
|
||||
const Type = @import("type.zig").Type;
|
||||
const TypedValue = @import("TypedValue.zig");
|
||||
|
|
@ -562,7 +563,7 @@ pub const File = struct {
|
|||
}
|
||||
|
||||
/// May be called before or after updateDeclExports for any given Decl.
|
||||
pub fn updateFunc(base: *File, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) UpdateDeclError!void {
|
||||
pub fn updateFunc(base: *File, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) UpdateDeclError!void {
|
||||
if (build_options.only_c) {
|
||||
assert(base.tag == .c);
|
||||
return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness);
|
||||
|
|
|
|||
|
|
@ -88,13 +88,13 @@ pub fn freeDecl(self: *C, decl_index: Module.Decl.Index) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *C, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *C, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
const func = module.funcPtr(func_index);
|
||||
const func = module.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const gop = try self.decl_table.getOrPut(gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
|
|
|
|||
|
|
@ -1032,7 +1032,7 @@ fn freeAtom(self: *Coff, atom_index: Atom.Index) void {
|
|||
self.getAtomPtr(atom_index).sym_index = 0;
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *Coff, mod: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
|
@ -1044,7 +1044,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: Module.Fn.Index, air: A
|
|||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
|
|
@ -1424,7 +1424,7 @@ pub fn updateDeclExports(
|
|||
// detect the default subsystem.
|
||||
for (exports) |exp| {
|
||||
const exported_decl = mod.declPtr(exp.exported_decl);
|
||||
if (exported_decl.getOwnedFunctionIndex(mod) == .none) continue;
|
||||
if (exported_decl.getOwnedFunctionIndex() == .none) continue;
|
||||
const winapi_cc = switch (self.base.options.target.cpu.arch) {
|
||||
.x86 => std.builtin.CallingConvention.Stdcall,
|
||||
else => std.builtin.CallingConvention.C,
|
||||
|
|
|
|||
|
|
@ -2575,7 +2575,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
|
|||
return local_sym;
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *Elf, mod: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *Elf, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !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");
|
||||
}
|
||||
|
|
@ -2586,7 +2586,7 @@ pub fn updateFunc(self: *Elf, mod: *Module, func_index: Module.Fn.Index, air: Ai
|
|||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
|
|
|
|||
|
|
@ -1845,7 +1845,7 @@ fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
|
|||
self.markRelocsDirtyByTarget(target);
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *MachO, mod: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .macho) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
|
@ -1855,7 +1855,7 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: Module.Fn.Index, air:
|
|||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const assert = std.debug.assert;
|
|||
const log = std.log.scoped(.link);
|
||||
|
||||
const Module = @import("../Module.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const link = @import("../link.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
|
|
@ -68,7 +69,7 @@ pub fn deinit(self: *NvPtx) void {
|
|||
self.base.allocator.free(self.ptx_file_name);
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *NvPtx, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *NvPtx, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
if (!build_options.have_llvm) return;
|
||||
try self.llvm_object.updateFunc(module, func_index, air, liveness);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
const Plan9 = @This();
|
||||
const link = @import("../link.zig");
|
||||
const Module = @import("../Module.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const aout = @import("Plan9/aout.zig");
|
||||
const codegen = @import("../codegen.zig");
|
||||
|
|
@ -344,12 +345,12 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi
|
|||
}
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *Plan9, mod: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .plan9) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
self.freeUnnamedConsts(decl_index);
|
||||
|
|
@ -908,7 +909,7 @@ pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void {
|
|||
// in the deleteUnusedDecl function.
|
||||
const mod = self.base.options.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const is_fn = decl.val.getFunctionIndex(mod) != .none;
|
||||
const is_fn = decl.val.isFuncBody(mod);
|
||||
if (is_fn) {
|
||||
var symidx_and_submap = self.fn_decl_table.get(decl.getFileScope(mod)).?;
|
||||
var submap = symidx_and_submap.functions;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ const assert = std.debug.assert;
|
|||
const log = std.log.scoped(.link);
|
||||
|
||||
const Module = @import("../Module.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const link = @import("../link.zig");
|
||||
const codegen = @import("../codegen/spirv.zig");
|
||||
|
|
@ -103,12 +104,12 @@ pub fn deinit(self: *SpirV) void {
|
|||
self.decl_link.deinit();
|
||||
}
|
||||
|
||||
pub fn updateFunc(self: *SpirV, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(self: *SpirV, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native) {
|
||||
@panic("Attempted to compile for architecture that was disabled by build configuration");
|
||||
}
|
||||
|
||||
const func = module.funcPtr(func_index);
|
||||
const func = module.funcInfo(func_index);
|
||||
|
||||
var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &self.spv, &self.decl_link);
|
||||
defer decl_gen.deinit();
|
||||
|
|
@ -138,7 +139,7 @@ pub fn updateDeclExports(
|
|||
exports: []const *Module.Export,
|
||||
) !void {
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (decl.val.getFunctionIndex(mod) != .none and decl.ty.fnCallingConvention(mod) == .Kernel) {
|
||||
if (decl.val.isFuncBody(mod) and decl.ty.fnCallingConvention(mod) == .Kernel) {
|
||||
// TODO: Unify with resolveDecl in spirv.zig.
|
||||
const entry = try self.decl_link.getOrPut(decl_index);
|
||||
if (!entry.found_existing) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const log = std.log.scoped(.link);
|
|||
pub const Atom = @import("Wasm/Atom.zig");
|
||||
const Dwarf = @import("Dwarf.zig");
|
||||
const Module = @import("../Module.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const CodeGen = @import("../arch/wasm/CodeGen.zig");
|
||||
const codegen = @import("../codegen.zig");
|
||||
|
|
@ -1338,7 +1339,7 @@ pub fn allocateSymbol(wasm: *Wasm) !u32 {
|
|||
return index;
|
||||
}
|
||||
|
||||
pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) !void {
|
||||
pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
|
||||
if (build_options.skip_non_native and builtin.object_format != .wasm) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
|
@ -1349,7 +1350,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: Module.Fn.Index, air: A
|
|||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const func = mod.funcPtr(func_index);
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ const Writer = struct {
|
|||
fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const ty_fn = w.air.instructions.items(.data)[inst].ty_fn;
|
||||
const func_index = ty_fn.func;
|
||||
const owner_decl = w.module.declPtr(w.module.funcPtr(func_index).owner_decl);
|
||||
const owner_decl = w.module.funcOwnerDeclPtr(func_index);
|
||||
try s.print("{}", .{owner_decl.name.fmt(&w.module.intern_pool)});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ pub const Type = struct {
|
|||
const func = ies.func;
|
||||
|
||||
try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
|
||||
const owner_decl = mod.declPtr(mod.funcPtr(func).owner_decl);
|
||||
const owner_decl = mod.funcOwnerDeclPtr(func);
|
||||
try owner_decl.renderFullyQualifiedName(mod, writer);
|
||||
try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
|
||||
},
|
||||
|
|
@ -367,7 +367,8 @@ pub const Type = struct {
|
|||
try writer.writeAll("noinline ");
|
||||
}
|
||||
try writer.writeAll("fn(");
|
||||
for (fn_info.param_types, 0..) |param_ty, i| {
|
||||
const param_types = fn_info.param_types.get(&mod.intern_pool);
|
||||
for (param_types, 0..) |param_ty, i| {
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
if (std.math.cast(u5, i)) |index| {
|
||||
if (fn_info.paramIsComptime(index)) {
|
||||
|
|
@ -384,7 +385,7 @@ pub const Type = struct {
|
|||
}
|
||||
}
|
||||
if (fn_info.is_var_args) {
|
||||
if (fn_info.param_types.len != 0) {
|
||||
if (param_types.len != 0) {
|
||||
try writer.writeAll(", ");
|
||||
}
|
||||
try writer.writeAll("...");
|
||||
|
|
|
|||
|
|
@ -473,12 +473,15 @@ pub const Value = struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn getFunction(val: Value, mod: *Module) ?*Module.Fn {
|
||||
return mod.funcPtrUnwrap(val.getFunctionIndex(mod));
|
||||
pub fn isFuncBody(val: Value, mod: *Module) bool {
|
||||
return mod.intern_pool.isFuncBody(val.toIntern());
|
||||
}
|
||||
|
||||
pub fn getFunctionIndex(val: Value, mod: *Module) Module.Fn.OptionalIndex {
|
||||
return if (val.ip_index != .none) mod.intern_pool.indexToFunc(val.toIntern()) else .none;
|
||||
pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func {
|
||||
return switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.func => |x| x,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getExternFunc(val: Value, mod: *Module) ?InternPool.Key.ExternFunc {
|
||||
|
|
@ -1462,7 +1465,7 @@ pub const Value = struct {
|
|||
return switch (mod.intern_pool.indexToKey(val.toIntern())) {
|
||||
.variable => |variable| variable.decl,
|
||||
.extern_func => |extern_func| extern_func.decl,
|
||||
.func => |func| mod.funcPtr(func.index).owner_decl,
|
||||
.func => |func| func.owner_decl,
|
||||
.ptr => |ptr| switch (ptr.addr) {
|
||||
.decl => |decl| decl,
|
||||
.mut_decl => |mut_decl| mut_decl.decl,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue