Commit d5c1e7f7b1
Changed files (12)
src/link/Coff/lld.zig
@@ -17,14 +17,12 @@ const Allocator = mem.Allocator;
const Coff = @import("../Coff.zig");
const Compilation = @import("../../Compilation.zig");
-pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = self.base.comp;
const gpa = comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
@@ -32,7 +30,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
// If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
- try self.flushModule(comp, prog_node);
+ try self.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
src/link/MachO/zld.zig
@@ -1,27 +1,24 @@
pub fn linkWithZld(
macho_file: *MachO,
- comp: *Compilation,
+ arena: Allocator,
prog_node: *std.Progress.Node,
) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = macho_file.base.comp.gpa;
- const target = macho_file.base.comp.root_mod.resolved_target.result;
+ const comp = macho_file.base.comp;
+ const gpa = comp.gpa;
+ const target = comp.root_mod.resolved_target.result;
const emit = macho_file.base.emit;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
-
const directory = emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{emit.sub_path});
- const opt_zcu = macho_file.base.comp.module;
+ const opt_zcu = comp.module;
// If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
- try macho_file.flushModule(comp, prog_node);
+ try macho_file.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, macho_file.base.zcu_object_sub_path.? });
@@ -35,8 +32,8 @@ pub fn linkWithZld(
sub_prog_node.context.refresh();
defer sub_prog_node.end();
- const output_mode = macho_file.base.comp.config.output_mode;
- const link_mode = macho_file.base.comp.config.link_mode;
+ const output_mode = comp.config.output_mode;
+ const link_mode = comp.config.link_mode;
const cpu_arch = target.cpu.arch;
const is_lib = output_mode == .Lib;
const is_dyn_lib = link_mode == .Dynamic and is_lib;
@@ -50,7 +47,7 @@ pub fn linkWithZld(
var digest: [Cache.hex_digest_len]u8 = undefined;
- const objects = macho_file.base.comp.objects;
+ const objects = comp.objects;
if (!macho_file.base.disable_lld_caching) {
man = comp.cache_parent.obtain();
@@ -76,7 +73,7 @@ pub fn linkWithZld(
man.hash.add(macho_file.headerpad_max_install_names);
man.hash.add(macho_file.base.gc_sections);
man.hash.add(macho_file.dead_strip_dylibs);
- man.hash.add(macho_file.base.comp.root_mod.strip);
+ man.hash.add(comp.root_mod.strip);
try MachO.hashAddFrameworks(&man, macho_file.frameworks);
man.hash.addListOfBytes(macho_file.base.rpath_list);
if (is_dyn_lib) {
@@ -406,7 +403,7 @@ pub fn linkWithZld(
try macho_file.createDyldPrivateAtom();
try macho_file.createTentativeDefAtoms();
- if (macho_file.base.comp.config.output_mode == .Exe) {
+ if (comp.config.output_mode == .Exe) {
const global = macho_file.getEntryPoint().?;
if (macho_file.getSymbol(global).undf()) {
// We do one additional check here in case the entry point was found in one of the dylibs.
src/link/C.zig
@@ -376,8 +376,8 @@ pub fn updateDeclLineNumber(self: *C, module: *Module, decl_index: InternPool.De
_ = decl_index;
}
-pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
- return self.flushModule(comp, prog_node);
+pub fn flush(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void {
+ return self.flushModule(arena, prog_node);
}
fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
@@ -393,7 +393,9 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
return defines;
}
-pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !void {
+pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void {
+ _ = arena; // Has the same lifetime as the call to Compilation.update.
+
const tracy = trace(@src());
defer tracy.end();
@@ -401,7 +403,8 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
sub_prog_node.activate();
defer sub_prog_node.end();
- const gpa = self.base.comp.gpa;
+ const comp = self.base.comp;
+ const gpa = comp.gpa;
const module = self.base.comp.module.?;
{
src/link/Coff.zig
@@ -1706,28 +1706,26 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {
gop.value_ptr.* = current;
}
-pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
- const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;
+pub fn flush(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ const comp = self.base.comp;
+ const use_lld = build_options.have_llvm and comp.config.use_lld;
if (use_lld) {
- return lld.linkWithLLD(self, comp, prog_node);
+ return lld.linkWithLLD(self, arena, prog_node);
}
- switch (self.base.comp.config.output_mode) {
- .Exe, .Obj => return self.flushModule(comp, prog_node),
+ switch (comp.config.output_mode) {
+ .Exe, .Obj => return self.flushModule(arena, prog_node),
.Lib => return error.TODOImplementWritingLibFiles,
}
}
-pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = self.base.comp;
const gpa = comp.gpa;
if (self.llvm_object) |llvm_object| {
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
-
try self.base.emitLlvmObject(arena, llvm_object, prog_node);
return;
}
src/link/Elf.zig
@@ -1026,22 +1026,20 @@ pub fn markDirty(self: *Elf, shdr_index: u16) void {
}
}
-pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flush(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;
if (use_lld) {
- return self.linkWithLLD(comp, prog_node);
+ return self.linkWithLLD(arena, prog_node);
}
- try self.flushModule(comp, prog_node);
+ try self.flushModule(arena, prog_node);
}
-pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = self.base.comp;
const gpa = comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
if (self.llvm_object) |llvm_object| {
try self.base.emitLlvmObject(arena, llvm_object, prog_node);
@@ -2349,22 +2347,20 @@ fn scanRelocs(self: *Elf) !void {
}
}
-fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = self.base.comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
+ const comp = self.base.comp;
+ const gpa = comp.gpa;
const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
// If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway.
- const module_obj_path: ?[]const u8 = if (self.base.comp.module != null) blk: {
- try self.flushModule(comp, prog_node);
+ const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
+ try self.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
@@ -2378,15 +2374,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
sub_prog_node.context.refresh();
defer sub_prog_node.end();
- const output_mode = self.base.comp.config.output_mode;
+ const output_mode = comp.config.output_mode;
const is_obj = output_mode == .Obj;
const is_lib = output_mode == .Lib;
- const link_mode = self.base.comp.config.link_mode;
+ const link_mode = comp.config.link_mode;
const is_dyn_lib = link_mode == .Dynamic and is_lib;
const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe;
const have_dynamic_linker = comp.config.link_libc and
link_mode == .Dynamic and is_exe_or_dyn_lib;
- const target = self.base.comp.root_mod.resolved_target.result;
+ const target = comp.root_mod.resolved_target.result;
const compiler_rt_path: ?[]const u8 = blk: {
if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
@@ -2459,8 +2455,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
man.hash.add(self.hash_style);
// strip does not need to go into the linker hash because it is part of the hash namespace
if (comp.config.link_libc) {
- man.hash.add(self.base.comp.libc_installation != null);
- if (self.base.comp.libc_installation) |libc_installation| {
+ man.hash.add(comp.libc_installation != null);
+ if (comp.libc_installation) |libc_installation| {
man.hash.addBytes(libc_installation.crt_dir.?);
}
if (have_dynamic_linker) {
@@ -2469,7 +2465,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
}
man.hash.addOptionalBytes(self.soname);
man.hash.addOptional(comp.version);
- try link.hashAddSystemLibs(&man, self.base.comp.system_libs);
+ try link.hashAddSystemLibs(&man, comp.system_libs);
man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
man.hash.add(self.base.allow_shlib_undefined);
man.hash.add(self.bind_global_refs_locally);
@@ -2743,7 +2739,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
if (self.each_lib_rpath) {
var test_path = std.ArrayList(u8).init(arena);
for (self.lib_dirs) |lib_dir_path| {
- for (self.base.comp.system_libs.keys()) |link_lib| {
+ for (comp.system_libs.keys()) |link_lib| {
if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))
continue;
if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) {
@@ -2771,7 +2767,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
}
if (comp.config.link_libc) {
- if (self.base.comp.libc_installation) |libc_installation| {
+ if (comp.libc_installation) |libc_installation| {
try argv.append("-L");
try argv.append(libc_installation.crt_dir.?);
}
@@ -2841,8 +2837,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
// Shared libraries.
if (is_exe_or_dyn_lib) {
- const system_libs = self.base.comp.system_libs.keys();
- const system_libs_values = self.base.comp.system_libs.values();
+ const system_libs = comp.system_libs.keys();
+ const system_libs_values = comp.system_libs.values();
// Worst-case, we need an --as-needed argument for every lib, as well
// as one before and one after.
@@ -2890,7 +2886,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
// libc dep
comp.link_error_flags.missing_libc = false;
if (comp.config.link_libc) {
- if (self.base.comp.libc_installation != null) {
+ if (comp.libc_installation != null) {
const needs_grouping = link_mode == .Static;
if (needs_grouping) try argv.append("--start-group");
try argv.appendSlice(target_util.libcFullLinkFlags(target));
@@ -2939,7 +2935,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
try argv.append("-Bsymbolic");
}
- if (self.base.comp.verbose_link) {
+ if (comp.verbose_link) {
// Skip over our own name so that the LLD linker name is the first argv item.
Compilation.dump_argv(argv.items[1..]);
}
src/link/MachO.zig
@@ -315,13 +315,14 @@ pub fn open(
return createEmpty(arena, comp, emit, options);
}
-pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
- const gpa = self.base.comp.gpa;
- const output_mode = self.base.comp.config.output_mode;
+pub fn flush(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ const comp = self.base.comp;
+ const gpa = comp.gpa;
+ const output_mode = comp.config.output_mode;
- if (output_mode == .Lib and self.base.comp.config.link_mode == .Static) {
+ if (output_mode == .Lib and comp.config.link_mode == .Static) {
if (build_options.have_llvm) {
- return self.base.linkAsArchive(comp, prog_node);
+ return self.base.linkAsArchive(arena, prog_node);
} else {
try comp.link_errors.ensureUnusedCapacity(gpa, 1);
comp.link_errors.appendAssumeCapacity(.{
@@ -332,19 +333,17 @@ pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) li
}
switch (self.mode) {
- .zld => return zld.linkWithZld(self, comp, prog_node),
- .incremental => return self.flushModule(comp, prog_node),
+ .zld => return zld.linkWithZld(self, arena, prog_node),
+ .incremental => return self.flushModule(arena, prog_node),
}
}
-pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = self.base.comp;
const gpa = comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
if (self.llvm_object) |llvm_object| {
try self.base.emitLlvmObject(arena, llvm_object, prog_node);
src/link/NvPtx.zig
@@ -106,18 +106,18 @@ pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void {
return self.llvm_object.freeDecl(decl_index);
}
-pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
- return self.flushModule(comp, prog_node);
+pub fn flush(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ return self.flushModule(arena, prog_node);
}
-pub fn flushModule(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
if (build_options.skip_non_native)
@panic("Attempted to compile for architecture that was disabled by build configuration");
// The code that was here before mutated the Compilation's file emission mechanism.
// That's not supposed to happen in flushModule, so I deleted the code.
+ _ = arena;
_ = self;
- _ = comp;
_ = prog_node;
@panic("TODO: rewrite the NvPtx.flushModule function");
}
src/link/Plan9.zig
@@ -608,8 +608,9 @@ fn allocateGotIndex(self: *Plan9) usize {
}
}
-pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
- const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;
+pub fn flush(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ const comp = self.base.comp;
+ const use_lld = build_options.have_llvm and comp.config.use_lld;
assert(!use_lld);
switch (link.File.effectiveOutputMode(use_lld, comp.config.output_mode)) {
@@ -618,7 +619,7 @@ pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) li
.Obj => return error.TODOImplementPlan9Objs,
.Lib => return error.TODOImplementWritingLibFiles,
}
- return self.flushModule(comp, prog_node);
+ return self.flushModule(arena, prog_node);
}
pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
@@ -666,11 +667,14 @@ fn atomCount(self: *Plan9) usize {
return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;
}
-pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!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");
}
+ _ = arena; // Has the same lifetime as the call to Compilation.update.
+
+ const comp = self.base.comp;
const gpa = comp.gpa;
const target = comp.root_mod.resolved_target.result;
src/link/SpirV.zig
@@ -173,15 +173,17 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void {
_ = decl_index;
}
-pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
- return self.flushModule(comp, prog_node);
+pub fn flush(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ return self.flushModule(arena, prog_node);
}
-pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
if (build_options.skip_non_native) {
@panic("Attempted to compile for architecture that was disabled by build configuration");
}
+ _ = arena; // Has the same lifetime as the call to Compilation.update.
+
const tracy = trace(@src());
defer tracy.end();
@@ -191,6 +193,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
const spv = &self.object.spv;
+ const comp = self.base.comp;
const gpa = comp.gpa;
const target = comp.getTarget();
src/link/Wasm.zig
@@ -3480,33 +3480,29 @@ fn resetState(wasm: *Wasm) void {
wasm.debug_pubtypes_index = null;
}
-pub fn flush(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ const comp = wasm.base.comp;
const use_lld = build_options.have_llvm and comp.config.use_lld;
const use_llvm = comp.config.use_llvm;
if (use_lld) {
- return wasm.linkWithLLD(comp, prog_node);
+ return wasm.linkWithLLD(arena, prog_node);
} else if (use_llvm) {
- return wasm.linkWithZld(comp, prog_node);
+ return wasm.linkWithZld(arena, prog_node);
} else {
- return wasm.flushModule(comp, prog_node);
+ return wasm.flushModule(arena, prog_node);
}
}
/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.
-fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = comp.gpa;
+ const comp = wasm.base.comp;
const shared_memory = comp.config.shared_memory;
const import_memory = comp.config.import_memory;
- // Used for all temporary memory allocated during flushin
- var arena_instance = std.heap.ArenaAllocator.init(gpa);
- defer arena_instance.deinit();
- const arena = arena_instance.allocator();
-
const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
const opt_zcu = comp.module;
@@ -3516,7 +3512,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
assert(use_llvm); // `linkWithZld` should never be called when the Wasm backend is used
- try wasm.flushModule(comp, prog_node);
+ try wasm.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
@@ -3708,15 +3704,11 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
}
}
-pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = comp.gpa;
- // Used for all temporary memory allocated during flushin
- var arena_instance = std.heap.ArenaAllocator.init(gpa);
- defer arena_instance.deinit();
- const arena = arena_instance.allocator();
+ const comp = wasm.base.comp;
if (wasm.llvm_object) |llvm_object| {
try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
@@ -4589,19 +4581,17 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {
}
}
-fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = wasm.base.comp;
const shared_memory = comp.config.shared_memory;
const export_memory = comp.config.export_memory;
const import_memory = comp.config.import_memory;
const target = comp.root_mod.resolved_target.result;
const gpa = comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
@@ -4609,7 +4599,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
// If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
- try wasm.flushModule(comp, prog_node);
+ try wasm.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
src/Compilation.zig
@@ -2311,7 +2311,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
fn flush(comp: *Compilation, arena: Allocator, prog_node: *std.Progress.Node) !void {
if (comp.bin_file) |lf| {
// This is needed before reading the error flags.
- lf.flush(comp, prog_node) catch |err| switch (err) {
+ lf.flush(arena, prog_node) catch |err| switch (err) {
error.FlushFailure => {}, // error reported through link_error_flags
error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
else => |e| return e,
src/link.zig
@@ -547,19 +547,22 @@ pub const File = struct {
/// Commit pending changes and write headers. Takes into account final output mode
/// and `use_lld`, not only `effectiveOutputMode`.
- pub fn flush(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
+ /// `arena` has the lifetime of the call to `Compilation.update`.
+ pub fn flush(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void {
if (build_options.only_c) {
assert(base.tag == .c);
- return @fieldParentPtr(C, "base", base).flush(comp, prog_node);
+ return @fieldParentPtr(C, "base", base).flush(arena, prog_node);
}
+ const comp = base.comp;
if (comp.clang_preprocessor_mode == .yes) {
+ const gpa = comp.gpa;
const emit = base.emit;
// TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case)
// Until then, we do `lld -r -o output.o input.o` even though the output is the same
// as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file
// to the final location. See also the corresponding TODO in Coff linking.
- const full_out_path = try emit.directory.join(comp.gpa, &[_][]const u8{emit.sub_path});
- defer comp.gpa.free(full_out_path);
+ const full_out_path = try emit.directory.join(gpa, &[_][]const u8{emit.sub_path});
+ defer gpa.free(full_out_path);
assert(comp.c_object_table.count() == 1);
const the_key = comp.c_object_table.keys()[0];
const cached_pp_file_path = the_key.status.success.object_path;
@@ -571,25 +574,25 @@ pub const File = struct {
const output_mode = comp.config.output_mode;
const link_mode = comp.config.link_mode;
if (use_lld and output_mode == .Lib and link_mode == .Static) {
- return base.linkAsArchive(comp, prog_node);
+ return base.linkAsArchive(arena, prog_node);
}
switch (base.tag) {
inline else => |tag| {
- return @fieldParentPtr(tag.Type(), "base", base).flush(comp, prog_node);
+ return @fieldParentPtr(tag.Type(), "base", base).flush(arena, prog_node);
},
}
}
/// Commit pending changes and write headers. Works based on `effectiveOutputMode`
/// rather than final output mode.
- pub fn flushModule(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
+ pub fn flushModule(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void {
switch (base.tag) {
.c => {
- return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node);
+ return @fieldParentPtr(C, "base", base).flushModule(arena, prog_node);
},
inline else => |tag| {
if (build_options.only_c) unreachable;
- return @fieldParentPtr(tag.Type(), "base", base).flushModule(comp, prog_node);
+ return @fieldParentPtr(tag.Type(), "base", base).flushModule(arena, prog_node);
},
}
}
@@ -707,14 +710,12 @@ pub const File = struct {
}
}
- pub fn linkAsArchive(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
+ pub fn linkAsArchive(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = base.comp;
const gpa = comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
const directory = base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
@@ -724,7 +725,7 @@ pub const File = struct {
// If there is no Zig code to compile, then we should skip flushing the output file
// because it will not be part of the linker line anyway.
const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
- try base.flushModule(comp, prog_node);
+ try base.flushModule(arena, prog_node);
const dirname = fs.path.dirname(full_out_path_z) orelse ".";
break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? });