diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-07-19 08:52:43 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-07-22 12:05:56 +0200 |
| commit | cba3389d906ff36f7913c7497d55ce1bf3164022 (patch) | |
| tree | 8da5db548c4b965080235a38432976c7e022abc0 /src/link.zig | |
| parent | 1fc42ed3e7ca0b74b54aaa827276d995d6c7c6cd (diff) | |
| download | zig-cba3389d906ff36f7913c7497d55ce1bf3164022.tar.gz zig-cba3389d906ff36f7913c7497d55ce1bf3164022.zip | |
macho: redo input file parsing in prep for multithreading
Diffstat (limited to 'src/link.zig')
| -rw-r--r-- | src/link.zig | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/link.zig b/src/link.zig index 9a754e4c6b..f9ed515d26 100644 --- a/src/link.zig +++ b/src/link.zig @@ -439,6 +439,58 @@ pub const File = struct { } } + pub const ErrorWithNotes = struct { + base: *const File, + + /// Allocated index in base.errors array. + index: usize, + + /// Next available note slot. + note_slot: usize = 0, + + pub fn addMsg( + err: ErrorWithNotes, + comptime format: []const u8, + args: anytype, + ) error{OutOfMemory}!void { + const gpa = err.base.comp.gpa; + const err_msg = &err.base.comp.link_errors.items[err.index]; + err_msg.msg = try std.fmt.allocPrint(gpa, format, args); + } + + pub fn addNote( + err: *ErrorWithNotes, + comptime format: []const u8, + args: anytype, + ) error{OutOfMemory}!void { + const gpa = err.base.comp.gpa; + const err_msg = &err.base.comp.link_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; + } + }; + + pub fn addErrorWithNotes(base: *const File, note_count: usize) error{OutOfMemory}!ErrorWithNotes { + base.comp.link_errors_mutex.lock(); + defer base.comp.link_errors_mutex.unlock(); + const gpa = base.comp.gpa; + try base.comp.link_errors.ensureUnusedCapacity(gpa, 1); + return base.addErrorWithNotesAssumeCapacity(note_count); + } + + pub fn addErrorWithNotesAssumeCapacity(base: *const File, note_count: usize) error{OutOfMemory}!ErrorWithNotes { + const gpa = base.comp.gpa; + const index = base.comp.link_errors.items.len; + const err = base.comp.link_errors.addOneAssumeCapacity(); + err.* = .{ .msg = undefined, .notes = try gpa.alloc(ErrorMsg, note_count) }; + return .{ .base = base, .index = index }; + } + + pub fn hasErrors(base: *const File) bool { + return base.comp.link_errors.items.len > 0 or base.comp.link_error_flags.isSet(); + } + pub fn releaseLock(self: *File) void { if (self.lock) |*lock| { lock.release(); @@ -874,9 +926,23 @@ pub const File = struct { } }; - pub const ErrorFlags = struct { + pub const ErrorFlags = packed struct { no_entry_point_found: bool = false, missing_libc: bool = false, + + const Int = blk: { + const bits = @typeInfo(@This()).Struct.fields.len; + break :blk @Type(.{ + .Int = .{ + .signedness = .unsigned, + .bits = bits, + }, + }); + }; + + fn isSet(ef: ErrorFlags) bool { + return @as(Int, @bitCast(ef)) > 0; + } }; pub const ErrorMsg = struct { |
