From c49957dbe82d7f0db555160b50306335bfa03165 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 14 Dec 2023 18:47:58 -0700 Subject: [PATCH] fix a round of compile errors caused by this branch --- src/Compilation.zig | 153 ++++++++++++++++++++++------------- src/Module.zig | 127 ++++++++++++++++------------- src/arch/aarch64/CodeGen.zig | 6 +- src/arch/aarch64/Emit.zig | 29 ++++--- src/arch/arm/CodeGen.zig | 8 +- src/arch/arm/Emit.zig | 30 ++++--- src/arch/riscv64/CodeGen.zig | 6 +- src/arch/riscv64/Emit.zig | 4 +- src/arch/sparc64/CodeGen.zig | 5 +- src/arch/sparc64/Emit.zig | 29 ++++--- src/arch/wasm/CodeGen.zig | 10 ++- src/arch/wasm/Emit.zig | 24 ++++-- src/arch/x86_64/CodeGen.zig | 42 +++++----- src/codegen.zig | 33 ++++---- src/codegen/llvm.zig | 4 +- src/libunwind.zig | 2 +- src/link.zig | 63 +++++++-------- src/link/C.zig | 12 ++- src/link/Coff.zig | 5 +- src/link/Coff/Atom.zig | 9 ++- src/link/Dwarf.zig | 2 +- src/link/Elf.zig | 52 ++++++------ src/link/Elf/Atom.zig | 14 +++- src/link/MachO.zig | 42 ++++------ src/link/MachO/Atom.zig | 12 ++- src/link/Plan9.zig | 1 - 26 files changed, 411 insertions(+), 313 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 35ee243617..693e46c07c 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -884,12 +884,32 @@ const CacheUse = union(CacheMode) { docs_sub_path: ?[]u8, lf_open_opts: link.File.OpenOptions, tmp_artifact_directory: ?Cache.Directory, + /// Prevents other processes from clobbering files in the output directory. + lock: ?Cache.Lock, + + fn releaseLock(whole: *Whole) void { + if (whole.lock) |*lock| { + lock.release(); + whole.lock = null; + } + } }; const Incremental = struct { /// Where build artifacts and incremental compilation metadata serialization go. artifact_directory: Compilation.Directory, }; + + fn deinit(cu: CacheUse) void { + switch (cu) { + .incremental => |incremental| { + incremental.artifact_directory.handle.close(); + }, + .whole => |whole| { + whole.releaseLock(); + }, + } + } }; pub const LinkObject = struct { @@ -916,7 +936,7 @@ pub const InitOptions = struct { /// Normally, `main_mod` and `root_mod` are the same. The exception is `zig /// test`, in which `root_mod` is the test runner, and `main_mod` is the /// user's source file which has the tests. - main_mod: ?*Package.Module, + main_mod: ?*Package.Module = null, /// This is provided so that the API user has a chance to tweak the /// per-module settings of the standard library. std_mod: *Package.Module, @@ -1615,6 +1635,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .implib_sub_path = try prepareWholeEmitSubPath(arena, options.emit_implib), .docs_sub_path = try prepareWholeEmitSubPath(arena, options.emit_docs), .tmp_artifact_directory = null, + .lock = null, }; comp.cache_use = .{ .whole = whole }; }, @@ -1822,13 +1843,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { pub fn destroy(self: *Compilation) void { if (self.bin_file) |lf| lf.destroy(); if (self.module) |zcu| zcu.deinit(); - switch (self.cache_use) { - .incremental => |incremental| { - incremental.artifact_directory.handle.close(); - }, - .whole => {}, - } - + self.cache_use.deinit(); self.work_queue.deinit(); self.anon_work_queue.deinit(); self.c_object_work_queue.deinit(); @@ -1922,11 +1937,17 @@ pub fn getTarget(self: Compilation) Target { return self.root_mod.resolved_target.result; } -pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.ChildProcess.Id) !void { - comp.bin_file.child_pid = pid; - try comp.makeBinFileWritable(); +/// Only legal to call when cache mode is incremental and a link file is present. +pub fn hotCodeSwap( + comp: *Compilation, + prog_node: *std.Progress.Node, + pid: std.ChildProcess.Id, +) !void { + const lf = comp.bin_file.?; + lf.child_pid = pid; + try lf.makeWritable(); try comp.update(prog_node); - try comp.makeBinFileExecutable(); + try lf.makeExecutable(); } fn cleanupAfterUpdate(comp: *Compilation) void { @@ -1941,7 +1962,7 @@ fn cleanupAfterUpdate(comp: *Compilation) void { lf.destroy(); comp.bin_file = null; } - if (whole.tmp_artifact_directory) |directory| { + if (whole.tmp_artifact_directory) |*directory| { directory.handle.close(); if (directory.path) |p| comp.gpa.free(p); whole.tmp_artifact_directory = null; @@ -1967,8 +1988,9 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void // C source files. switch (comp.cache_use) { .whole => |whole| { - // We are about to obtain this lock, so here we give other processes a chance first. assert(comp.bin_file == null); + // We are about to obtain this lock, so here we give other processes a chance first. + whole.releaseLock(); man = comp.cache_parent.obtain(); whole.cache_manifest = &man; @@ -1989,8 +2011,8 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void comp.wholeCacheModeSetBinFilePath(whole, &digest); - assert(comp.bin_file.lock == null); - comp.bin_file.lock = man.toOwnedLock(); + assert(whole.lock == null); + whole.lock = man.toOwnedLock(); return; } log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name}); @@ -2158,7 +2180,7 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void // Rename the temporary directory into place. // Close tmp dir and link.File to avoid open handle during rename. - if (whole.tmp_artifact_directory) |tmp_directory| { + if (whole.tmp_artifact_directory) |*tmp_directory| { tmp_directory.handle.close(); if (tmp_directory.path) |p| comp.gpa.free(p); whole.tmp_artifact_directory = null; @@ -2181,8 +2203,8 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void log.warn("failed to write cache manifest: {s}", .{@errorName(err)}); }; - assert(comp.bin_file.lock == null); - comp.bin_file.lock = man.toOwnedLock(); + assert(whole.lock == null); + whole.lock = man.toOwnedLock(); }, .incremental => {}, } @@ -2263,13 +2285,15 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi } fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void { - // This is needed before reading the error flags. - comp.bin_file.flush(comp, prog_node) catch |err| switch (err) { - error.FlushFailure => {}, // error reported through link_error_flags - error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr - else => |e| return e, - }; - comp.link_error_flags = comp.bin_file.errorFlags(); + if (comp.bin_file) |lf| { + // This is needed before reading the error flags. + lf.flush(comp, prog_node) catch |err| switch (err) { + error.FlushFailure => {}, // error reported through link_error_flags + error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr + else => |e| return e, + }; + comp.link_error_flags = lf.error_flags; + } if (comp.module) |module| { try link.File.C.flushEmitH(module); @@ -2445,9 +2469,9 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes .wasm => { const wasm = lf.cast(link.File.Wasm).?; man.hash.add(wasm.rdynamic); - man.hash.add(wasm.initial_memory); - man.hash.add(wasm.max_memory); - man.hash.add(wasm.global_base); + man.hash.addOptional(wasm.initial_memory); + man.hash.addOptional(wasm.max_memory); + man.hash.addOptional(wasm.global_base); }, .macho => { const macho = lf.cast(link.File.MachO).?; @@ -2626,12 +2650,14 @@ fn reportMultiModuleErrors(mod: *Module) !void { /// binary is concerned. This will remove the write flag, or close the file, /// or whatever is needed so that it can be executed. /// After this, one must call` makeFileWritable` before calling `update`. -pub fn makeBinFileExecutable(self: *Compilation) !void { - return self.bin_file.makeExecutable(); +pub fn makeBinFileExecutable(comp: *Compilation) !void { + const lf = comp.bin_file orelse return; + return lf.makeExecutable(); } -pub fn makeBinFileWritable(self: *Compilation) !void { - return self.bin_file.makeWritable(); +pub fn makeBinFileWritable(comp: *Compilation) !void { + const lf = comp.bin_file orelse return; + return lf.makeWritable(); } const Header = extern struct { @@ -2764,8 +2790,9 @@ pub fn totalErrorCount(self: *Compilation) u32 { } total += @intFromBool(self.link_error_flags.missing_libc); - // Misc linker errors - total += self.bin_file.miscErrors().len; + if (self.bin_file) |lf| { + total += lf.misc_errors.items.len; + } // Compile log errors only count if there are no other errors. if (total == 0) { @@ -2914,7 +2941,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { })); } - for (self.bin_file.miscErrors()) |link_err| { + if (self.bin_file) |lf| for (lf.misc_errors.items) |link_err| { try bundle.addRootErrorMessage(.{ .msg = try bundle.addString(link_err.msg), .notes_len = @intCast(link_err.notes.len), @@ -2925,7 +2952,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { .msg = try bundle.addString(note.msg), })); } - } + }; if (self.module) |module| { if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) { @@ -3246,12 +3273,12 @@ pub fn performAllTheWork( // TODO put all the modules in a flat array to make them easy to iterate. var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .{}; defer seen.deinit(comp.gpa); - try seen.put(comp.gpa, comp.root_mod); + try seen.put(comp.gpa, comp.root_mod, {}); var i: usize = 0; while (i < seen.count()) : (i += 1) { const mod = seen.keys()[i]; for (mod.deps.values()) |dep| - try seen.put(comp.gpa, dep); + try seen.put(comp.gpa, dep, {}); const file = mod.builtin_file orelse continue; @@ -3459,7 +3486,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v const gpa = comp.gpa; const module = comp.module.?; const decl = module.declPtr(decl_index); - comp.bin_file.updateDeclLineNumber(module, decl_index) catch |err| { + const lf = comp.bin_file.?; + lf.updateDeclLineNumber(module, decl_index) catch |err| { try module.failed_decls.ensureUnusedCapacity(gpa, 1); module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create( gpa, @@ -3782,7 +3810,7 @@ pub fn obtainCObjectCacheManifest( // that apply both to @cImport and compiling C objects. No linking stuff here! // Also nothing that applies only to compiling .zig code. man.hash.add(owner_mod.sanitize_c); - man.hash.addListOfBytes(owner_mod.clang_argv); + man.hash.addListOfBytes(owner_mod.cc_argv); man.hash.add(comp.config.link_libcpp); // When libc_installation is null it means that Zig generated this dir list @@ -6099,7 +6127,8 @@ fn buildOutputFromZig( const tracy_trace = trace(@src()); defer tracy_trace.end(); - var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); + const gpa = comp.gpa; + var arena_allocator = std.heap.ArenaAllocator.init(gpa); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); @@ -6110,6 +6139,7 @@ fn buildOutputFromZig( const config = try Config.resolve(.{ .output_mode = output_mode, + .link_mode = .Static, .resolved_target = comp.root_mod.resolved_target, .is_test = false, .have_zcu = true, @@ -6120,7 +6150,8 @@ fn buildOutputFromZig( .any_unwind_tables = unwind_tables, }); - const root_mod = Package.Module.create(.{ + const root_mod = try Package.Module.create(arena, .{ + .global_cache_directory = comp.global_cache_directory, .paths = .{ .root = .{ .root_dir = comp.zig_lib_directory }, .root_src_path = src_basename, @@ -6139,6 +6170,8 @@ fn buildOutputFromZig( }, .global = config, .cc_argv = &.{}, + .parent = null, + .builtin_mod = null, }); const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; const target = comp.getTarget(); @@ -6148,23 +6181,21 @@ fn buildOutputFromZig( .output_mode = output_mode, }); - const emit_bin = Compilation.EmitLoc{ - .directory = null, // Put it in the cache directory. - .basename = bin_basename, - }; - const sub_compilation = try Compilation.create(comp.gpa, .{ + const sub_compilation = try Compilation.create(gpa, .{ .global_cache_directory = comp.global_cache_directory, .local_cache_directory = comp.global_cache_directory, .zig_lib_directory = comp.zig_lib_directory, .self_exe_path = comp.self_exe_path, - .resolved = config, + .config = config, .root_mod = root_mod, .cache_mode = .whole, .root_name = root_name, .thread_pool = comp.thread_pool, .libc_installation = comp.libc_installation, - .emit_bin = emit_bin, - .link_mode = .Static, + .emit_bin = .{ + .directory = null, // Put it in the cache directory. + .basename = bin_basename, + }, .function_sections = true, .data_sections = true, .no_builtin = true, @@ -6186,8 +6217,8 @@ fn buildOutputFromZig( try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node); assert(out.* == null); - out.* = Compilation.CRTFile{ - .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(comp.gpa, &[_][]const u8{ + out.* = .{ + .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &.{ sub_compilation.bin_file.?.emit.sub_path, }), .lock = sub_compilation.bin_file.toOwnedLock(), @@ -6206,12 +6237,15 @@ pub fn build_crt_file( defer tracy_trace.end(); const gpa = comp.gpa; - const basename = try std.zig.binNameAlloc(gpa, .{ + var arena_allocator = std.heap.ArenaAllocator.init(gpa); + defer arena_allocator.deinit(); + const arena = arena_allocator.allocator(); + + const basename = try std.zig.binNameAlloc(arena, .{ .root_name = root_name, .target = comp.root_mod.resolved_target.result, .output_mode = output_mode, }); - errdefer gpa.free(basename); const config = try Config.resolve(.{ .output_mode = output_mode, @@ -6227,7 +6261,8 @@ pub fn build_crt_file( .Obj, .Exe => false, }, }); - const root_mod = Package.Module.create(.{ + const root_mod = try Package.Module.create(arena, .{ + .global_cache_directory = comp.global_cache_directory, .paths = .{ .root = .{ .root_dir = comp.zig_lib_directory }, .root_src_path = "", @@ -6249,6 +6284,8 @@ pub fn build_crt_file( }, .global = config, .cc_argv = &.{}, + .parent = null, + .builtin_mod = null, }); const sub_compilation = try Compilation.create(gpa, .{ @@ -6257,7 +6294,7 @@ pub fn build_crt_file( .zig_lib_directory = comp.zig_lib_directory, .self_exe_path = comp.self_exe_path, .cache_mode = .whole, - .resolved = config, + .config = config, .root_mod = root_mod, .root_name = root_name, .thread_pool = comp.thread_pool, @@ -6287,7 +6324,7 @@ pub fn build_crt_file( try comp.crt_files.ensureUnusedCapacity(gpa, 1); comp.crt_files.putAssumeCapacityNoClobber(basename, .{ - .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &[_][]const u8{ + .full_object_path = try sub_compilation.bin_file.?.emit.directory.join(gpa, &.{ sub_compilation.bin_file.?.emit.sub_path, }), .lock = sub_compilation.bin_file.toOwnedLock(), diff --git a/src/Module.zig b/src/Module.zig index 121f639f6b..0645b6f04f 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -619,7 +619,7 @@ pub const Decl = struct { // Sanitize the name for nvptx which is more restrictive. // TODO This should be handled by the backend, not the frontend. Have a // look at how the C backend does it for inspiration. - const cpu_arch = mod.root_mod.resolved_target.cpu.arch; + const cpu_arch = mod.root_mod.resolved_target.result.cpu.arch; if (cpu_arch.isNvptx()) { for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) { '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_', @@ -3313,7 +3313,8 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr if (no_bin_file and !dump_llvm_ir) return; - comp.bin_file.updateFunc(mod, func_index, air, liveness) catch |err| switch (err) { + const lf = comp.bin_file.?; + lf.updateFunc(mod, func_index, air, liveness) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => { decl.analysis = .codegen_failure; @@ -3488,25 +3489,29 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { new_decl.owns_tv = true; new_decl.analysis = .complete; - if (mod.comp.whole_cache_manifest) |whole_cache_manifest| { - const source = file.getSource(gpa) catch |err| { - try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)}); - return error.AnalysisFail; - }; + const comp = mod.comp; + switch (comp.cache_use) { + .whole => |whole| if (whole.cache_manifest) |man| { + const source = file.getSource(gpa) catch |err| { + try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)}); + return error.AnalysisFail; + }; - const resolved_path = std.fs.path.resolve(gpa, &.{ - file.mod.root.root_dir.path orelse ".", - file.mod.root.sub_path, - file.sub_file_path, - }) catch |err| { - try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)}); - return error.AnalysisFail; - }; - errdefer gpa.free(resolved_path); + const resolved_path = std.fs.path.resolve(gpa, &.{ + file.mod.root.root_dir.path orelse ".", + file.mod.root.sub_path, + file.sub_file_path, + }) catch |err| { + try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)}); + return error.AnalysisFail; + }; + errdefer gpa.free(resolved_path); - mod.comp.whole_cache_manifest_mutex.lock(); - defer mod.comp.whole_cache_manifest_mutex.unlock(); - try whole_cache_manifest.addFilePostContents(resolved_path, source.bytes, source.stat); + whole.cache_manifest_mutex.lock(); + defer whole.cache_manifest_mutex.unlock(); + try man.addFilePostContents(resolved_path, source.bytes, source.stat); + }, + .incremental => {}, } } @@ -4045,12 +4050,16 @@ fn newEmbedFile( const actual_read = try file.readAll(ptr); if (actual_read != size) return error.UnexpectedEndOfFile; - if (mod.comp.whole_cache_manifest) |whole_cache_manifest| { - const copied_resolved_path = try gpa.dupe(u8, resolved_path); - errdefer gpa.free(copied_resolved_path); - mod.comp.whole_cache_manifest_mutex.lock(); - defer mod.comp.whole_cache_manifest_mutex.unlock(); - try whole_cache_manifest.addFilePostContents(copied_resolved_path, ptr, stat); + const comp = mod.comp; + switch (comp.cache_use) { + .whole => |whole| if (whole.cache_manifest) |man| { + const copied_resolved_path = try gpa.dupe(u8, resolved_path); + errdefer gpa.free(copied_resolved_path); + whole.cache_manifest_mutex.lock(); + defer whole.cache_manifest_mutex.unlock(); + try man.addFilePostContents(copied_resolved_path, ptr, stat); + }, + .incremental => {}, } const array_ty = try ip.get(gpa, .{ .array_type = .{ @@ -4393,7 +4402,9 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void } }, } - try mod.comp.bin_file.deleteDeclExport(decl_index, exp.opts.name); + if (mod.comp.bin_file) |lf| { + try lf.deleteDeclExport(decl_index, exp.opts.name); + } if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| { failed_kv.value.destroy(mod.gpa); } @@ -5247,7 +5258,8 @@ fn processExportsInner( gop.value_ptr.* = new_export; } } - mod.comp.bin_file.updateExports(mod, exported, exports) catch |err| switch (err) { + const lf = mod.comp.bin_file orelse return; + lf.updateExports(mod, exported, exports) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, else => { const new_export = exports[0]; @@ -5403,36 +5415,39 @@ pub fn populateTestFunctions( pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void { const comp = mod.comp; - const no_bin_file = (comp.bin_file == null and - comp.emit_asm == null and - comp.emit_llvm_ir == null and - comp.emit_llvm_bc == null); + if (comp.bin_file) |lf| { + const decl = mod.declPtr(decl_index); + lf.updateDecl(mod, decl_index) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.AnalysisFail => { + decl.analysis = .codegen_failure; + return; + }, + else => { + const gpa = mod.gpa; + try mod.failed_decls.ensureUnusedCapacity(gpa, 1); + mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create( + gpa, + decl.srcLoc(mod), + "unable to codegen: {s}", + .{@errorName(err)}, + )); + decl.analysis = .codegen_failure_retryable; + return; + }, + }; + } else { + const dump_llvm_ir = builtin.mode == .Debug and + (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null); - const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null); - - if (no_bin_file and !dump_llvm_ir) return; - - const decl = mod.declPtr(decl_index); - - comp.bin_file.updateDecl(mod, decl_index) catch |err| switch (err) { - error.OutOfMemory => return error.OutOfMemory, - error.AnalysisFail => { - decl.analysis = .codegen_failure; - return; - }, - else => { - const gpa = mod.gpa; - try mod.failed_decls.ensureUnusedCapacity(gpa, 1); - mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create( - gpa, - decl.srcLoc(mod), - "unable to codegen: {s}", - .{@errorName(err)}, - )); - decl.analysis = .codegen_failure_retryable; - return; - }, - }; + if (comp.emit_asm != null or + comp.emit_llvm_ir != null or + comp.emit_llvm_bc != null or + dump_llvm_ir) + { + @panic("TODO handle emit_asm, emit_llvm_ir, and emit_llvm_bc along with -fno-emit-bin"); + } + } } fn reportRetryableFileError( diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 2fb740474b..341e4bef00 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -344,7 +344,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.ty; const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.target; + const target = &namespace.file_scope.mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { @@ -6343,14 +6343,14 @@ fn wantSafety(self: *Self) bool { fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args); return error.CodegenFail; } fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args); return error.CodegenFail; } diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index 9ba722f393..3f629fd46f 100644 --- a/src/arch/aarch64/Emit.zig +++ b/src/arch/aarch64/Emit.zig @@ -218,14 +218,16 @@ pub fn emitMir( } pub fn deinit(emit: *Emit) void { + const comp = emit.bin_file.comp; + const gpa = comp.gpa; var iter = emit.branch_forward_origins.valueIterator(); while (iter.next()) |origin_list| { - origin_list.deinit(emit.bin_file.allocator); + origin_list.deinit(gpa); } - emit.branch_types.deinit(emit.bin_file.allocator); - emit.branch_forward_origins.deinit(emit.bin_file.allocator); - emit.code_offset_mapping.deinit(emit.bin_file.allocator); + emit.branch_types.deinit(gpa); + emit.branch_forward_origins.deinit(gpa); + emit.code_offset_mapping.deinit(gpa); emit.* = undefined; } @@ -314,8 +316,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index { } fn lowerBranches(emit: *Emit) !void { + const comp = emit.bin_file.comp; + const gpa = comp.gpa; const mir_tags = emit.mir.instructions.items(.tag); - const allocator = emit.bin_file.allocator; // First pass: Note down all branches and their target // instructions, i.e. populate branch_types, @@ -329,7 +332,7 @@ fn lowerBranches(emit: *Emit) !void { const target_inst = emit.branchTarget(inst); // Remember this branch instruction - try emit.branch_types.put(allocator, inst, BranchType.default(tag)); + try emit.branch_types.put(gpa, inst, BranchType.default(tag)); // Forward branches require some extra stuff: We only // know their offset once we arrive at the target @@ -339,14 +342,14 @@ fn lowerBranches(emit: *Emit) !void { // etc. if (target_inst > inst) { // Remember the branch instruction index - try emit.code_offset_mapping.put(allocator, inst, 0); + try emit.code_offset_mapping.put(gpa, inst, 0); if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| { - try origin_list.append(allocator, inst); + try origin_list.append(gpa, inst); } else { var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}; - try origin_list.append(allocator, inst); - try emit.branch_forward_origins.put(allocator, target_inst, origin_list); + try origin_list.append(gpa, inst); + try emit.branch_forward_origins.put(gpa, target_inst, origin_list); } } @@ -356,7 +359,7 @@ fn lowerBranches(emit: *Emit) !void { // putNoClobber may not be used as the put operation // may clobber the entry when multiple branches branch // to the same target instruction - try emit.code_offset_mapping.put(allocator, target_inst, 0); + try emit.code_offset_mapping.put(gpa, target_inst, 0); } } @@ -429,7 +432,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(emit.err_msg == null); - emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args); + const comp = emit.bin_file.comp; + const gpa = comp.gpa; + emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args); return error.EmitFail; } diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 0df653ff35..c9d6a3aef4 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -351,7 +351,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.ty; const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.target; + const target = &namespace.file_scope.mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { @@ -6292,14 +6292,16 @@ fn wantSafety(self: *Self) bool { fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + const gpa = self.gpa; + self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); return error.CodegenFail; } fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + const gpa = self.gpa; + self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); return error.CodegenFail; } diff --git a/src/arch/arm/Emit.zig b/src/arch/arm/Emit.zig index 45c3392918..2ab3b60ee6 100644 --- a/src/arch/arm/Emit.zig +++ b/src/arch/arm/Emit.zig @@ -152,14 +152,17 @@ pub fn emitMir( } pub fn deinit(emit: *Emit) void { + const comp = emit.bin_file.comp; + const gpa = comp.gpa; + var iter = emit.branch_forward_origins.valueIterator(); while (iter.next()) |origin_list| { - origin_list.deinit(emit.bin_file.allocator); + origin_list.deinit(gpa); } - emit.branch_types.deinit(emit.bin_file.allocator); - emit.branch_forward_origins.deinit(emit.bin_file.allocator); - emit.code_offset_mapping.deinit(emit.bin_file.allocator); + emit.branch_types.deinit(gpa); + emit.branch_forward_origins.deinit(gpa); + emit.code_offset_mapping.deinit(gpa); emit.* = undefined; } @@ -231,8 +234,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index { } fn lowerBranches(emit: *Emit) !void { + const comp = emit.bin_file.comp; + const gpa = comp.gpa; const mir_tags = emit.mir.instructions.items(.tag); - const allocator = emit.bin_file.allocator; // First pass: Note down all branches and their target // instructions, i.e. populate branch_types, @@ -246,7 +250,7 @@ fn lowerBranches(emit: *Emit) !void { const target_inst = emit.branchTarget(inst); // Remember this branch instruction - try emit.branch_types.put(allocator, inst, BranchType.default(tag)); + try emit.branch_types.put(gpa, inst, BranchType.default(tag)); // Forward branches require some extra stuff: We only // know their offset once we arrive at the target @@ -256,14 +260,14 @@ fn lowerBranches(emit: *Emit) !void { // etc. if (target_inst > inst) { // Remember the branch instruction index - try emit.code_offset_mapping.put(allocator, inst, 0); + try emit.code_offset_mapping.put(gpa, inst, 0); if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| { - try origin_list.append(allocator, inst); + try origin_list.append(gpa, inst); } else { var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}; - try origin_list.append(allocator, inst); - try emit.branch_forward_origins.put(allocator, target_inst, origin_list); + try origin_list.append(gpa, inst); + try emit.branch_forward_origins.put(gpa, target_inst, origin_list); } } @@ -273,7 +277,7 @@ fn lowerBranches(emit: *Emit) !void { // putNoClobber may not be used as the put operation // may clobber the entry when multiple branches branch // to the same target instruction - try emit.code_offset_mapping.put(allocator, target_inst, 0); + try emit.code_offset_mapping.put(gpa, target_inst, 0); } } @@ -346,7 +350,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(emit.err_msg == null); - emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args); + const comp = emit.bin_file.comp; + const gpa = comp.gpa; + emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args); return error.EmitFail; } diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 30c6e38c8a..80daa8fd3a 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -232,7 +232,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.ty; const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.target; + const target = &namespace.file_scope.mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { @@ -2719,14 +2719,14 @@ fn wantSafety(self: *Self) bool { fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args); return error.CodegenFail; } fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args); return error.CodegenFail; } diff --git a/src/arch/riscv64/Emit.zig b/src/arch/riscv64/Emit.zig index 9d82cc38cc..f382f6f9eb 100644 --- a/src/arch/riscv64/Emit.zig +++ b/src/arch/riscv64/Emit.zig @@ -80,7 +80,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(emit.err_msg == null); - emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args); + const comp = emit.bin_file.comp; + const gpa = comp.gpa; + emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args); return error.EmitFail; } diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index bd0208c3c2..e58206ac16 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -275,7 +275,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.ty; const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.target; + const target = &namespace.file_scope.mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { @@ -3546,7 +3546,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + const gpa = self.gpa; + self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); return error.CodegenFail; } diff --git a/src/arch/sparc64/Emit.zig b/src/arch/sparc64/Emit.zig index 4701035bc9..b2f2e6f79d 100644 --- a/src/arch/sparc64/Emit.zig +++ b/src/arch/sparc64/Emit.zig @@ -152,14 +152,16 @@ pub fn emitMir( } pub fn deinit(emit: *Emit) void { + const comp = emit.bin_file.comp; + const gpa = comp.gpa; var iter = emit.branch_forward_origins.valueIterator(); while (iter.next()) |origin_list| { - origin_list.deinit(emit.bin_file.allocator); + origin_list.deinit(gpa); } - emit.branch_types.deinit(emit.bin_file.allocator); - emit.branch_forward_origins.deinit(emit.bin_file.allocator); - emit.code_offset_mapping.deinit(emit.bin_file.allocator); + emit.branch_types.deinit(gpa); + emit.branch_forward_origins.deinit(gpa); + emit.code_offset_mapping.deinit(gpa); emit.* = undefined; } @@ -511,7 +513,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void { fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(emit.err_msg == null); - emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args); + const comp = emit.bin_file.comp; + const gpa = comp.gpa; + emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args); return error.EmitFail; } @@ -537,8 +541,9 @@ fn isBranch(tag: Mir.Inst.Tag) bool { } fn lowerBranches(emit: *Emit) !void { + const comp = emit.bin_file.comp; + const gpa = comp.gpa; const mir_tags = emit.mir.instructions.items(.tag); - const allocator = emit.bin_file.allocator; // First pass: Note down all branches and their target // instructions, i.e. populate branch_types, @@ -552,7 +557,7 @@ fn lowerBranches(emit: *Emit) !void { const target_inst = emit.branchTarget(inst); // Remember this branch instruction - try emit.branch_types.put(allocator, inst, BranchType.default(tag)); + try emit.branch_types.put(gpa, inst, BranchType.default(tag)); // Forward branches require some extra stuff: We only // know their offset once we arrive at the target @@ -562,14 +567,14 @@ fn lowerBranches(emit: *Emit) !void { // etc. if (target_inst > inst) { // Remember the branch instruction index - try emit.code_offset_mapping.put(allocator, inst, 0); + try emit.code_offset_mapping.put(gpa, inst, 0); if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| { - try origin_list.append(allocator, inst); + try origin_list.append(gpa, inst); } else { var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{}; - try origin_list.append(allocator, inst); - try emit.branch_forward_origins.put(allocator, target_inst, origin_list); + try origin_list.append(gpa, inst); + try emit.branch_forward_origins.put(gpa, target_inst, origin_list); } } @@ -579,7 +584,7 @@ fn lowerBranches(emit: *Emit) !void { // putNoClobber may not be used as the put operation // may clobber the entry when multiple branches branch // to the same target instruction - try emit.code_offset_mapping.put(allocator, target_inst, 0); + try emit.code_offset_mapping.put(gpa, target_inst, 0); } } diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 2319330333..da33ae521d 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1210,13 +1210,15 @@ pub fn generate( debug_output: codegen.DebugInfoOutput, ) codegen.CodeGenError!codegen.Result { _ = src_loc; - const mod = bin_file.comp.module.?; + const comp = bin_file.comp; + const gpa = comp.gpa; + const mod = comp.module.?; const func = mod.funcInfo(func_index); const decl = mod.declPtr(func.owner_decl); const namespace = mod.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; var code_gen: CodeGen = .{ - .gpa = bin_file.allocator, + .gpa = gpa, .air = air, .liveness = liveness, .code = code, @@ -7731,7 +7733,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { // Only when the atomic feature is enabled, and we're not building // for a single-threaded build, can we emit the `fence` instruction. // In all other cases, we emit no instructions for a fence. - const func_namespace = zcu.namespacePtr(zcu.declPtr(func.decl).namespace); + const func_namespace = zcu.namespacePtr(func.decl.src_namespace); const single_threaded = func_namespace.file_scope.mod.single_threaded; if (func.useAtomicFeature() and !single_threaded) { try func.addAtomicTag(.atomic_fence); diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 990eb359e8..7e67a98285 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -254,8 +254,10 @@ fn offset(self: Emit) u32 { fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { @setCold(true); std.debug.assert(emit.error_msg == null); - const mod = emit.bin_file.base.comp.module.?; - emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.base.allocator, mod.declPtr(emit.decl_index).srcLoc(mod), format, args); + const comp = emit.bin_file.base.comp; + const zcu = comp.module.?; + const gpa = comp.gpa; + emit.error_msg = try Module.ErrorMsg.create(gpa, zcu.declPtr(emit.decl_index).srcLoc(zcu), format, args); return error.EmitFail; } @@ -299,6 +301,8 @@ fn emitLabel(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { } fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { + const comp = emit.bin_file.base.comp; + const gpa = comp.gpa; const label = emit.mir.instructions.items(.data)[inst].label; try emit.code.append(@intFromEnum(tag)); var buf: [5]u8 = undefined; @@ -308,7 +312,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { const atom_index = emit.bin_file.decls.get(emit.decl_index).?; const atom = emit.bin_file.getAtomPtr(atom_index); - try atom.relocs.append(emit.bin_file.base.allocator, .{ + try atom.relocs.append(gpa, .{ .index = label, .offset = global_offset, .relocation_type = .R_WASM_GLOBAL_INDEX_LEB, @@ -356,6 +360,8 @@ fn encodeMemArg(mem_arg: Mir.MemArg, writer: anytype) !void { } fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { + const comp = emit.bin_file.base.comp; + const gpa = comp.gpa; const label = emit.mir.instructions.items(.data)[inst].label; try emit.code.append(std.wasm.opcode(.call)); const call_offset = emit.offset(); @@ -366,7 +372,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { if (label != 0) { const atom_index = emit.bin_file.decls.get(emit.decl_index).?; const atom = emit.bin_file.getAtomPtr(atom_index); - try atom.relocs.append(emit.bin_file.base.allocator, .{ + try atom.relocs.append(gpa, .{ .offset = call_offset, .index = label, .relocation_type = .R_WASM_FUNCTION_INDEX_LEB, @@ -384,6 +390,8 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void { } fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { + const comp = emit.bin_file.base.comp; + const gpa = comp.gpa; const symbol_index = emit.mir.instructions.items(.data)[inst].label; try emit.code.append(std.wasm.opcode(.i32_const)); const index_offset = emit.offset(); @@ -394,7 +402,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { if (symbol_index != 0) { const atom_index = emit.bin_file.decls.get(emit.decl_index).?; const atom = emit.bin_file.getAtomPtr(atom_index); - try atom.relocs.append(emit.bin_file.base.allocator, .{ + try atom.relocs.append(gpa, .{ .offset = index_offset, .index = symbol_index, .relocation_type = .R_WASM_TABLE_INDEX_SLEB, @@ -406,7 +414,9 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { const extra_index = emit.mir.instructions.items(.data)[inst].payload; const mem = emit.mir.extraData(Mir.Memory, extra_index).data; const mem_offset = emit.offset() + 1; - const target = emit.bin_file.comp.root_mod.resolved_target.result; + const comp = emit.bin_file.base.comp; + const gpa = comp.gpa; + const target = comp.root_mod.resolved_target.result; const is_wasm32 = target.cpu.arch == .wasm32; if (is_wasm32) { try emit.code.append(std.wasm.opcode(.i32_const)); @@ -423,7 +433,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { if (mem.pointer != 0) { const atom_index = emit.bin_file.decls.get(emit.decl_index).?; const atom = emit.bin_file.getAtomPtr(atom_index); - try atom.relocs.append(emit.bin_file.base.allocator, .{ + try atom.relocs.append(gpa, .{ .offset = mem_offset, .index = mem.pointer, .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64, diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index b3c5df02d9..5056bc32fd 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -795,15 +795,16 @@ pub fn generate( code: *std.ArrayList(u8), debug_output: DebugInfoOutput, ) CodeGenError!Result { - const mod = bin_file.comp.module.?; + const comp = bin_file.comp; + const gpa = comp.gpa; + const mod = comp.module.?; 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; const namespace = mod.namespacePtr(fn_owner_decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; - const gpa = bin_file.allocator; var function = Self{ .gpa = gpa, .air = air, @@ -860,7 +861,7 @@ pub fn generate( error.CodegenFail => return Result{ .fail = function.err_msg.? }, error.OutOfRegisters => return Result{ .fail = try ErrorMsg.create( - bin_file.allocator, + gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}, @@ -904,22 +905,22 @@ pub fn generate( function.gen() catch |err| switch (err) { error.CodegenFail => return Result{ .fail = function.err_msg.? }, error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), + .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), }, else => |e| return e, }; var mir = Mir{ .instructions = function.mir_instructions.toOwnedSlice(), - .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), + .extra = try function.mir_extra.toOwnedSlice(gpa), .frame_locs = function.frame_locs.toOwnedSlice(), }; - defer mir.deinit(bin_file.allocator); + defer mir.deinit(gpa); var emit = Emit{ .lower = .{ .bin_file = bin_file, - .allocator = bin_file.allocator, + .allocator = gpa, .mir = mir, .cc = cc, .src_loc = src_loc, @@ -940,7 +941,7 @@ pub fn generate( }; return Result{ .fail = try ErrorMsg.create( - bin_file.allocator, + gpa, src_loc, "{s} This is a bug in the Zig compiler.", .{msg}, @@ -964,12 +965,13 @@ pub fn generateLazy( code: *std.ArrayList(u8), debug_output: DebugInfoOutput, ) CodeGenError!Result { - const gpa = bin_file.allocator; - const zcu = bin_file.comp.module.?; + const comp = bin_file.comp; + const gpa = comp.gpa; + const zcu = comp.module.?; const decl_index = lazy_sym.ty.getOwnerDecl(zcu); const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; var function = Self{ .gpa = gpa, .air = undefined, @@ -996,22 +998,22 @@ pub fn generateLazy( function.genLazy(lazy_sym) catch |err| switch (err) { error.CodegenFail => return Result{ .fail = function.err_msg.? }, error.OutOfRegisters => return Result{ - .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), + .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}), }, else => |e| return e, }; var mir = Mir{ .instructions = function.mir_instructions.toOwnedSlice(), - .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), + .extra = try function.mir_extra.toOwnedSlice(gpa), .frame_locs = function.frame_locs.toOwnedSlice(), }; - defer mir.deinit(bin_file.allocator); + defer mir.deinit(gpa); var emit = Emit{ .lower = .{ .bin_file = bin_file, - .allocator = bin_file.allocator, + .allocator = gpa, .mir = mir, .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), .src_loc = src_loc, @@ -1032,7 +1034,7 @@ pub fn generateLazy( }; return Result{ .fail = try ErrorMsg.create( - bin_file.allocator, + gpa, src_loc, "{s} This is a bug in the Zig compiler.", .{msg}, @@ -16416,14 +16418,16 @@ fn resolveCallingConventionValues( fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + const gpa = self.gpa; + self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); return error.CodegenFail; } fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); - self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args); + const gpa = self.gpa; + self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args); return error.CodegenFail; } diff --git a/src/codegen.zig b/src/codegen.zig index e579cb50f1..65af8236de 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -57,7 +57,7 @@ pub fn generateFunction( const func = zcu.funcInfo(func_index); const decl = zcu.declPtr(func.owner_decl); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; switch (target.cpu.arch) { .arm, .armeb, @@ -87,7 +87,7 @@ pub fn generateLazyFunction( const decl_index = lazy_sym.ty.getOwnerDecl(zcu); const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; switch (target.cpu.arch) { .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, src_loc, lazy_sym, code, debug_output), else => unreachable, @@ -117,12 +117,14 @@ pub fn generateLazySymbol( const tracy = trace(@src()); defer tracy.end(); - const zcu = bin_file.comp.module.?; + const comp = bin_file.comp; + const zcu = comp.module.?; const decl_index = lazy_sym.ty.getOwnerDecl(zcu); const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; const endian = target.cpu.arch.endian(); + const gpa = comp.gpa; log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ @tagName(lazy_sym.kind), @@ -160,7 +162,7 @@ pub fn generateLazySymbol( } return Result.ok; } else return .{ .fail = try ErrorMsg.create( - bin_file.allocator, + gpa, src_loc, "TODO implement generateLazySymbol for {s} {}", .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(zcu) }, @@ -827,7 +829,7 @@ fn lowerDeclRef( const zcu = lf.comp.module.?; const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; const ptr_width = target.ptrBitWidth(); const is_fn_body = decl.ty.zigTypeTag(zcu) == .Fn; @@ -921,7 +923,7 @@ fn genDeclRef( const ptr_decl = zcu.declPtr(ptr_decl_index); const namespace = zcu.namespacePtr(ptr_decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; const ptr_bits = target.ptrBitWidth(); const ptr_bytes: u64 = @divExact(ptr_bits, 8); @@ -944,6 +946,9 @@ fn genDeclRef( return GenResult.mcv(.{ .immediate = imm }); } + const comp = lf.comp; + const gpa = comp.gpa; + // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? if (tv.ty.castPtrToFn(zcu)) |fn_ty| { if (zcu.typeToFunc(fn_ty).?.is_generic) { @@ -958,8 +963,8 @@ fn genDeclRef( try zcu.markDeclAlive(decl); - const decl_namespace = zcu.namespacePtr(decl.namespace_index); - const single_threaded = decl_namespace.file_scope.zcu.single_threaded; + const decl_namespace = zcu.namespacePtr(decl.src_namespace); + const single_threaded = decl_namespace.file_scope.mod.single_threaded; const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded; const is_extern = decl.isExtern(zcu); @@ -985,8 +990,8 @@ fn genDeclRef( if (is_extern) { // TODO make this part of getGlobalSymbol const name = zcu.intern_pool.stringToSlice(decl.name); - const sym_name = try std.fmt.allocPrint(lf.allocator, "_{s}", .{name}); - defer lf.allocator.free(sym_name); + const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); + defer gpa.free(sym_name); const global_index = try macho_file.addUndefined(sym_name, .{ .add_got = true }); return GenResult.mcv(.{ .load_got = link.File.MachO.global_symbol_bit | global_index }); } @@ -1005,7 +1010,7 @@ fn genDeclRef( else null; const global_index = try coff_file.getGlobalSymbol(name, lib_name); - try coff_file.need_got_table.put(lf.allocator, global_index, {}); // needs GOT + try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index }); } const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index); @@ -1016,7 +1021,7 @@ fn genDeclRef( const atom = p9.getAtom(atom_index); return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) }); } else { - return GenResult.fail(lf.allocator, src_loc, "TODO genDeclRef for target {}", .{target}); + return GenResult.fail(gpa, src_loc, "TODO genDeclRef for target {}", .{target}); } } @@ -1073,7 +1078,7 @@ pub fn genTypedValue( const owner_decl = zcu.declPtr(owner_decl_index); const namespace = zcu.namespacePtr(owner_decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; const ptr_bits = target.ptrBitWidth(); if (!typed_value.ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 709b2bf6a9..6545f84f9d 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1785,7 +1785,7 @@ pub const Object = struct { if (wantDllExports(mod)) global_index.setDllStorageClass(.default, &self.builder); global_index.setUnnamedAddr(.unnamed_addr, &self.builder); if (decl.val.getVariable(mod)) |decl_var| { - const decl_namespace = mod.namespacePtr(decl.namespace_index); + const decl_namespace = mod.namespacePtr(decl.src_namespace); const single_threaded = decl_namespace.file_scope.mod.single_threaded; global_index.ptrConst(&self.builder).kind.variable.setThreadLocal( if (decl_var.is_threadlocal and !single_threaded) @@ -3173,7 +3173,7 @@ pub const Object = struct { variable_index.setLinkage(.external, &o.builder); variable_index.setUnnamedAddr(.default, &o.builder); if (decl.val.getVariable(mod)) |decl_var| { - const decl_namespace = mod.namespacePtr(decl.namespace_index); + const decl_namespace = mod.namespacePtr(decl.src_namespace); const single_threaded = decl_namespace.file_scope.mod.single_threaded; variable_index.setThreadLocal( if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default, diff --git a/src/libunwind.zig b/src/libunwind.zig index bc1c0d0343..baf24d8508 100644 --- a/src/libunwind.zig +++ b/src/libunwind.zig @@ -123,7 +123,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void { .local_cache_directory = comp.global_cache_directory, .global_cache_directory = comp.global_cache_directory, .zig_lib_directory = comp.zig_lib_directory, - .resolved = config, + .config = config, .root_mod = root_mod, .cache_mode = .whole, .root_name = root_name, diff --git a/src/link.zig b/src/link.zig index 91def2a134..ce12e922d7 100644 --- a/src/link.zig +++ b/src/link.zig @@ -69,10 +69,12 @@ pub const File = struct { allow_shlib_undefined: bool, stack_size: u64, + error_flags: ErrorFlags = .{}, + misc_errors: std.ArrayListUnmanaged(ErrorMsg) = .{}, + /// Prevents other processes from clobbering files in the output directory /// of this linking operation. lock: ?Cache.Lock = null, - child_pid: ?std.ChildProcess.Id = null, pub const OpenOptions = struct { @@ -210,6 +212,8 @@ pub const File = struct { } pub fn makeWritable(base: *File) !void { + const comp = base.comp; + const gpa = comp.gpa; switch (base.tag) { .coff, .elf, .macho, .plan9, .wasm => { if (build_options.only_c) unreachable; @@ -225,9 +229,10 @@ pub const File = struct { // it will return ETXTBSY. So instead, we copy the file, atomically rename it // over top of the exe path, and then proceed normally. This changes the inode, // avoiding the error. - const tmp_sub_path = try std.fmt.allocPrint(base.allocator, "{s}-{x}", .{ + const tmp_sub_path = try std.fmt.allocPrint(gpa, "{s}-{x}", .{ emit.sub_path, std.crypto.random.int(u32), }); + defer gpa.free(tmp_sub_path); try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); switch (builtin.os.tag) { @@ -242,9 +247,9 @@ pub const File = struct { } } } - const use_lld = build_options.have_llvm and base.comp.config.use_lld; - const output_mode = base.comp.config.output_mode; - const link_mode = base.comp.config.link_mode; + const use_lld = build_options.have_llvm and comp.config.use_lld; + const output_mode = comp.config.output_mode; + const link_mode = comp.config.link_mode; base.file = try emit.directory.handle.createFile(emit.sub_path, .{ .truncate = false, .read = true, @@ -256,9 +261,10 @@ pub const File = struct { } pub fn makeExecutable(base: *File) !void { - const output_mode = base.comp.config.output_mode; - const link_mode = base.comp.config.link_mode; - const use_lld = build_options.have_llvm and base.comp.config.use_lld; + const comp = base.comp; + const output_mode = comp.config.output_mode; + const link_mode = comp.config.link_mode; + const use_lld = build_options.have_llvm and comp.config.use_lld; switch (output_mode) { .Obj => return, @@ -464,8 +470,13 @@ pub const File = struct { } pub fn destroy(base: *File) void { + const gpa = base.comp.gpa; base.releaseLock(); if (base.file) |f| f.close(); + { + for (base.misc_errors.items) |*item| item.deinit(gpa); + base.misc_errors.deinit(gpa); + } switch (base.tag) { .coff => { if (build_options.only_c) unreachable; @@ -602,9 +613,9 @@ pub const File = struct { return; } - const use_lld = build_options.have_llvm and base.comp.config.use_lld; - const output_mode = base.comp.config.output_mode; - const link_mode = base.comp.config.link_mode; + const use_lld = build_options.have_llvm and comp.config.use_lld; + 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); } @@ -657,25 +668,6 @@ pub const File = struct { } } - pub fn errorFlags(base: *File) ErrorFlags { - switch (base.tag) { - .coff => return @fieldParentPtr(Coff, "base", base).error_flags, - .elf => return @fieldParentPtr(Elf, "base", base).error_flags, - .macho => return @fieldParentPtr(MachO, "base", base).error_flags, - .plan9 => return @fieldParentPtr(Plan9, "base", base).error_flags, - .c => return .{ .no_entry_point_found = false }, - .wasm, .spirv, .nvptx => return ErrorFlags{}, - } - } - - pub fn miscErrors(base: *File) []const ErrorMsg { - switch (base.tag) { - .elf => return @fieldParentPtr(Elf, "base", base).misc_errors.items, - .macho => return @fieldParentPtr(MachO, "base", base).misc_errors.items, - else => return &.{}, - } - } - pub const UpdateExportsError = error{ OutOfMemory, AnalysisFail, @@ -781,14 +773,15 @@ pub const File = struct { const tracy = trace(@src()); defer tracy.end(); - var arena_allocator = std.heap.ArenaAllocator.init(base.allocator); + 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}); const full_out_path_z = try arena.dupeZ(u8, full_out_path); - const opt_zcu = 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. @@ -801,7 +794,7 @@ pub const File = struct { log.debug("zcu_obj_path={s}", .{if (zcu_obj_path) |s| s else "(null)"}); - const compiler_rt_path: ?[]const u8 = if (base.comp.include_compiler_rt) + const compiler_rt_path: ?[]const u8 = if (comp.include_compiler_rt) comp.compiler_rt_obj.?.full_object_path else null; @@ -815,7 +808,7 @@ pub const File = struct { var man: Cache.Manifest = undefined; defer if (!base.disable_lld_caching) man.deinit(); - const objects = base.comp.objects; + const objects = comp.objects; var digest: [Cache.hex_digest_len]u8 = undefined; @@ -869,7 +862,7 @@ pub const File = struct { const win32_resource_table_len = if (build_options.only_core_functionality) 0 else comp.win32_resource_table.count(); const num_object_files = objects.len + comp.c_object_table.count() + win32_resource_table_len + 2; - var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); + var object_files = try std.ArrayList([*:0]const u8).initCapacity(gpa, num_object_files); defer object_files.deinit(); for (objects) |obj| { diff --git a/src/link/C.zig b/src/link/C.zig index ce44cc4c06..3592052cf8 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -84,7 +84,8 @@ pub fn getString(this: C, s: String) []const u8 { } pub fn addString(this: *C, s: []const u8) Allocator.Error!String { - const gpa = this.base.allocator; + const comp = this.base.comp; + const gpa = comp.gpa; try this.string_bytes.appendSlice(gpa, s); return .{ .start = @intCast(this.string_bytes.items.len - s.len), @@ -97,6 +98,15 @@ pub fn open( comp: *Compilation, emit: Compilation.Emit, options: link.File.OpenOptions, +) !*C { + return createEmpty(arena, comp, emit, options); +} + +pub fn createEmpty( + arena: Allocator, + comp: *Compilation, + emit: Compilation.Emit, + options: link.File.OpenOptions, ) !*C { const target = comp.root_mod.resolved_target.result; assert(target.ofmt == .c); diff --git a/src/link/Coff.zig b/src/link/Coff.zig index eba24f0d17..762591442b 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -8,7 +8,6 @@ llvm_object: ?*LlvmObject = null, base: link.File, image_base: u64, -error_flags: link.File.ErrorFlags = .{}, dll_export_fns: bool, subsystem: ?std.Target.SubSystem, tsaware: bool, @@ -1825,10 +1824,10 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod if (self.entry_addr == null and self.base.comp.config.output_mode == .Exe) { log.debug("flushing. no_entry_point_found = true\n", .{}); - self.error_flags.no_entry_point_found = true; + self.base.error_flags.no_entry_point_found = true; } else { log.debug("flushing. no_entry_point_found = false\n", .{}); - self.error_flags.no_entry_point_found = false; + self.base.error_flags.no_entry_point_found = false; try self.writeHeader(); } diff --git a/src/link/Coff/Atom.zig b/src/link/Coff/Atom.zig index 9e55575755..4aa97fa6ac 100644 --- a/src/link/Coff/Atom.zig +++ b/src/link/Coff/Atom.zig @@ -94,7 +94,8 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool { } pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !void { - const gpa = coff_file.base.allocator; + const comp = coff_file.base.comp; + const gpa = comp.gpa; log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index }); const gop = try coff_file.relocs.getOrPut(gpa, atom_index); if (!gop.found_existing) { @@ -104,7 +105,8 @@ pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !vo } pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void { - const gpa = coff_file.base.allocator; + const comp = coff_file.base.comp; + const gpa = comp.gpa; log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{ offset, coff_file.getAtom(atom_index).getSymbolIndex().?, @@ -117,7 +119,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void } pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void { - const gpa = coff_file.base.allocator; + const comp = coff_file.base.comp; + const gpa = comp.gpa; var removed_relocs = coff_file.relocs.fetchOrderedRemove(atom_index); if (removed_relocs) |*relocs| relocs.value.deinit(gpa); var removed_base_relocs = coff_file.base_relocs.fetchOrderedRemove(atom_index); diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 525ca90bc3..faaf5100a4 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1205,7 +1205,7 @@ pub fn commitDeclState( const decl = zcu.declPtr(decl_index); const ip = &zcu.intern_pool; const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.target; + const target = namespace.file_scope.mod.resolved_target.result; const target_endian = target.cpu.arch.endian(); var dbg_line_buffer = &decl_state.dbg_line; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 5f96e195ab..3e237fe494 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -196,9 +196,6 @@ resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{}, has_text_reloc: bool = false, num_ifunc_dynrelocs: usize = 0, -error_flags: link.File.ErrorFlags = link.File.ErrorFlags{}, -misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, - /// List of atoms that are owned directly by the linker. atoms: std.ArrayListUnmanaged(Atom) = .{}, @@ -477,7 +474,6 @@ pub fn deinit(self: *Elf) void { } self.last_atom_and_free_list_table.deinit(gpa); - self.misc_errors.deinit(gpa); self.comdat_groups.deinit(gpa); self.comdat_groups_owners.deinit(gpa); self.comdat_groups_table.deinit(gpa); @@ -1168,7 +1164,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node } // libc dep - self.error_flags.missing_libc = false; + self.base.error_flags.missing_libc = false; if (self.base.comp.config.link_libc) { if (self.base.comp.libc_installation) |lc| { const flags = target_util.libcFullLinkFlags(target); @@ -1219,7 +1215,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node }); try system_libs.append(.{ .path = path }); } else { - self.error_flags.missing_libc = true; + self.base.error_flags.missing_libc = true; } } @@ -1257,7 +1253,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node }; } - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; // Init all objects for (self.objects.items) |index| { @@ -1267,7 +1263,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node try self.file(index).?.shared_object.init(self); } - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; // Dedup shared objects { @@ -1389,14 +1385,14 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node if (self.entry_index == null and self.base.isExe()) { log.debug("flushing. no_entry_point_found = true", .{}); - self.error_flags.no_entry_point_found = true; + self.base.error_flags.no_entry_point_found = true; } else { log.debug("flushing. no_entry_point_found = false", .{}); - self.error_flags.no_entry_point_found = false; + self.base.error_flags.no_entry_point_found = false; try self.writeElfHeader(); } - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; } pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { @@ -1428,7 +1424,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const }; } - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; // First, we flush relocatable object file generated with our backends. if (self.zigObjectPtr()) |zig_object| { @@ -1540,7 +1536,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const try self.base.file.?.setEndPos(total_size); try self.base.file.?.pwriteAll(buffer.items, 0); - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; } pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void { @@ -1571,14 +1567,14 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) }; } - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; // Init all objects for (self.objects.items) |index| { try self.file(index).?.object.init(self); } - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; // Now, we are ready to resolve the symbols across all input files. // We will first resolve the files in the ZigObject, next in the parsed @@ -1612,7 +1608,7 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) try self.writeShdrTable(); try self.writeElfHeader(); - if (self.misc_errors.items.len > 0) return error.FlushFailure; + if (self.base.misc_errors.items.len > 0) return error.FlushFailure; } /// --verbose-link output @@ -2891,7 +2887,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v } // libc dep - self.error_flags.missing_libc = false; + self.base.error_flags.missing_libc = false; if (comp.config.link_libc) { if (self.base.comp.libc_installation != null) { const needs_grouping = link_mode == .Static; @@ -2912,7 +2908,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v .Dynamic => "libc.so", })); } else { - self.error_flags.missing_libc = true; + self.base.error_flags.missing_libc = true; } } } @@ -3135,7 +3131,7 @@ fn writePhdrTable(self: *Elf) !void { } fn writeElfHeader(self: *Elf) !void { - if (self.misc_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable + if (self.base.misc_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined; @@ -6067,8 +6063,9 @@ const ErrorWithNotes = struct { comptime format: []const u8, args: anytype, ) error{OutOfMemory}!void { - const gpa = elf_file.base.allocator; - const err_msg = &elf_file.misc_errors.items[err.index]; + const comp = elf_file.base.comp; + const gpa = comp.gpa; + const err_msg = &elf_file.base.misc_errors.items[err.index]; err_msg.msg = try std.fmt.allocPrint(gpa, format, args); } @@ -6078,8 +6075,9 @@ const ErrorWithNotes = struct { comptime format: []const u8, args: anytype, ) error{OutOfMemory}!void { - const gpa = elf_file.base.allocator; - const err_msg = &elf_file.misc_errors.items[err.index]; + const comp = elf_file.base.comp; + const gpa = comp.gpa; + const err_msg = &elf_file.base.misc_errors.items[err.index]; assert(err.note_slot < err_msg.notes.len); err_msg.notes[err.note_slot] = .{ .msg = try std.fmt.allocPrint(gpa, format, args) }; err.note_slot += 1; @@ -6088,14 +6086,14 @@ const ErrorWithNotes = struct { pub fn addErrorWithNotes(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); return self.addErrorWithNotesAssumeCapacity(note_count); } fn addErrorWithNotesAssumeCapacity(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes { const gpa = self.base.comp.gpa; - const index = self.misc_errors.items.len; - const err = self.misc_errors.addOneAssumeCapacity(); + const index = self.base.misc_errors.items.len; + const err = self.base.misc_errors.addOneAssumeCapacity(); err.* = .{ .msg = undefined, .notes = try gpa.alloc(link.File.ErrorMsg, note_count) }; return .{ .index = index }; } @@ -6130,7 +6128,7 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void { const gpa = self.base.comp.gpa; const max_notes = 4; - try self.misc_errors.ensureUnusedCapacity(gpa, undefs.count()); + try self.base.misc_errors.ensureUnusedCapacity(gpa, undefs.count()); var it = undefs.iterator(); while (it.next()) |entry| { diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index dc330fa54b..9f57dab283 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -227,7 +227,8 @@ pub fn grow(self: *Atom, elf_file: *Elf) !void { pub fn free(self: *Atom, elf_file: *Elf) void { log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) }); - const gpa = elf_file.base.allocator; + const comp = elf_file.base.comp; + const gpa = comp.gpa; const shndx = self.outputShndx().?; const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?; const free_list = &meta.free_list; @@ -352,7 +353,8 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void { } pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { - const gpa = elf_file.base.allocator; + const comp = elf_file.base.comp; + const gpa = comp.gpa; const file_ptr = self.file(elf_file).?; assert(file_ptr == .zig_object); const zig_object = file_ptr.zig_object; @@ -747,6 +749,8 @@ fn reportUndefined( rel: elf.Elf64_Rela, undefs: anytype, ) !void { + const comp = elf_file.base.comp; + const gpa = comp.gpa; const rel_esym = switch (self.file(elf_file).?) { .zig_object => |x| x.elfSym(rel.r_sym()).*, .object => |x| x.symtab.items[rel.r_sym()], @@ -761,7 +765,7 @@ fn reportUndefined( { const gop = try undefs.getOrPut(sym_index); if (!gop.found_existing) { - gop.value_ptr.* = std.ArrayList(Atom.Index).init(elf_file.base.allocator); + gop.value_ptr.* = std.ArrayList(Atom.Index).init(gpa); } try gop.value_ptr.append(self.atom_index); } @@ -957,6 +961,8 @@ fn resolveDynAbsReloc( elf_file: *Elf, writer: anytype, ) !void { + const comp = elf_file.base.comp; + const gpa = comp.gpa; const P = self.value + rel.r_offset; const A = rel.r_addend; const S = @as(i64, @intCast(target.address(.{}, elf_file))); @@ -967,7 +973,7 @@ fn resolveDynAbsReloc( .shared_object => unreachable, inline else => |x| x.num_dynrelocs, }; - try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, num_dynrelocs); + try elf_file.rela_dyn.ensureUnusedCapacity(gpa, num_dynrelocs); switch (action) { .@"error", diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 25d59f3de3..104c83b357 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -67,9 +67,6 @@ tlv_ptr_table: TableSection(SymbolWithLoc) = .{}, thunk_table: std.AutoHashMapUnmanaged(Atom.Index, thunks.Thunk.Index) = .{}, thunks: std.ArrayListUnmanaged(thunks.Thunk) = .{}, -error_flags: File.ErrorFlags = File.ErrorFlags{}, -misc_errors: std.ArrayListUnmanaged(File.ErrorMsg) = .{}, - segment_table_dirty: bool = false, got_table_count_dirty: bool = false, got_table_contents_dirty: bool = false, @@ -337,8 +334,8 @@ pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) li if (build_options.have_llvm) { return self.base.linkAsArchive(comp, prog_node); } else { - try self.misc_errors.ensureUnusedCapacity(gpa, 1); - self.misc_errors.appendAssumeCapacity(.{ + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); + self.base.misc_errors.appendAssumeCapacity(.{ .msg = try gpa.dupe(u8, "TODO: non-LLVM archiver for MachO object files"), }); return error.FlushFailure; @@ -492,7 +489,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try self.resolveSymbols(); if (self.getEntryPoint() == null) { - self.error_flags.no_entry_point_found = true; + self.base.error_flags.no_entry_point_found = true; } if (self.unresolved.count() > 0) { try self.reportUndefined(); @@ -2097,11 +2094,6 @@ pub fn deinit(self: *MachO) void { bindings.deinit(gpa); } self.bindings.deinit(gpa); - - for (self.misc_errors.items) |*err| { - err.deinit(gpa); - } - self.misc_errors.deinit(gpa); } fn freeAtom(self: *MachO, atom_index: Atom.Index) void { @@ -5341,13 +5333,13 @@ fn reportMissingLibraryError( args: anytype, ) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); const notes = try gpa.alloc(File.ErrorMsg, checked_paths.len); errdefer gpa.free(notes); for (checked_paths, notes) |path, *note| { note.* = .{ .msg = try std.fmt.allocPrint(gpa, "tried {s}", .{path}) }; } - self.misc_errors.appendAssumeCapacity(.{ + self.base.misc_errors.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, format, args), .notes = notes, }); @@ -5361,14 +5353,14 @@ fn reportDependencyError( args: anytype, ) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2); defer notes.deinit(); if (path) |p| { notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{p}) }); } notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "a dependency of {s}", .{parent}) }); - self.misc_errors.appendAssumeCapacity(.{ + self.base.misc_errors.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, format, args), .notes = try notes.toOwnedSlice(), }); @@ -5381,11 +5373,11 @@ pub fn reportParseError( args: anytype, ) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); var notes = try gpa.alloc(File.ErrorMsg, 1); errdefer gpa.free(notes); notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{path}) }; - self.misc_errors.appendAssumeCapacity(.{ + self.base.misc_errors.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, format, args), .notes = notes, }); @@ -5398,11 +5390,11 @@ pub fn reportUnresolvedBoundarySymbol( args: anytype, ) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); var notes = try gpa.alloc(File.ErrorMsg, 1); errdefer gpa.free(notes); notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while resolving {s}", .{sym_name}) }; - self.misc_errors.appendAssumeCapacity(.{ + self.base.misc_errors.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, format, args), .notes = notes, }); @@ -5411,7 +5403,7 @@ pub fn reportUnresolvedBoundarySymbol( pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; const count = self.unresolved.count(); - try self.misc_errors.ensureUnusedCapacity(gpa, count); + try self.base.misc_errors.ensureUnusedCapacity(gpa, count); for (self.unresolved.keys()) |global_index| { const global = self.globals.items[global_index]; @@ -5432,7 +5424,7 @@ pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void { }; err_msg.notes = try notes.toOwnedSlice(); - self.misc_errors.appendAssumeCapacity(err_msg); + self.base.misc_errors.appendAssumeCapacity(err_msg); } } @@ -5442,7 +5434,7 @@ fn reportSymbolCollision( other: SymbolWithLoc, ) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2); defer notes.deinit(); @@ -5465,12 +5457,12 @@ fn reportSymbolCollision( }) }; err_msg.notes = try notes.toOwnedSlice(); - self.misc_errors.appendAssumeCapacity(err_msg); + self.base.misc_errors.appendAssumeCapacity(err_msg); } fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{OutOfMemory}!void { const gpa = self.base.comp.gpa; - try self.misc_errors.ensureUnusedCapacity(gpa, 1); + try self.base.misc_errors.ensureUnusedCapacity(gpa, 1); const notes = try gpa.alloc(File.ErrorMsg, 1); errdefer gpa.free(notes); @@ -5488,7 +5480,7 @@ fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{Ou else unreachable; - self.misc_errors.appendAssumeCapacity(.{ + self.base.misc_errors.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "unhandled symbol type: '{s}' has type {s}", .{ self.getSymbolName(sym_with_loc), sym_type, diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 0263995359..d76a6de841 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -253,7 +253,8 @@ pub fn addRelocation(macho_file: *MachO, atom_index: Index, reloc: Relocation) ! } pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Relocation) !void { - const gpa = macho_file.base.allocator; + const comp = macho_file.base.comp; + const gpa = comp.gpa; const gop = try macho_file.relocs.getOrPut(gpa, atom_index); if (!gop.found_existing) { gop.value_ptr.* = .{}; @@ -269,7 +270,8 @@ pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Rel } pub fn addRebase(macho_file: *MachO, atom_index: Index, offset: u32) !void { - const gpa = macho_file.base.allocator; + const comp = macho_file.base.comp; + const gpa = comp.gpa; const atom = macho_file.getAtom(atom_index); log.debug(" (adding rebase at offset 0x{x} in %{?d})", .{ offset, atom.getSymbolIndex() }); const gop = try macho_file.rebases.getOrPut(gpa, atom_index); @@ -280,7 +282,8 @@ pub fn addRebase(macho_file: *MachO, atom_index: Index, offset: u32) !void { } pub fn addBinding(macho_file: *MachO, atom_index: Index, binding: Binding) !void { - const gpa = macho_file.base.allocator; + const comp = macho_file.base.comp; + const gpa = comp.gpa; const atom = macho_file.getAtom(atom_index); log.debug(" (adding binding to symbol {s} at offset 0x{x} in %{?d})", .{ macho_file.getSymbolName(binding.target), @@ -307,7 +310,8 @@ pub fn resolveRelocations( } pub fn freeRelocations(macho_file: *MachO, atom_index: Index) void { - const gpa = macho_file.base.allocator; + const comp = macho_file.base.comp; + const gpa = comp.gpa; var removed_relocs = macho_file.relocs.fetchOrderedRemove(atom_index); if (removed_relocs) |*relocs| relocs.value.deinit(gpa); var removed_rebases = macho_file.rebases.fetchOrderedRemove(atom_index); diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index c970e72e51..3fe6aee009 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -28,7 +28,6 @@ pub const base_tag = .plan9; base: link.File, sixtyfour_bit: bool, -error_flags: File.ErrorFlags = File.ErrorFlags{}, bases: Bases, /// A symbol's value is just casted down when compiling