authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-15 18:54:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:26-07:00
logf3d0fc7a66fa40e86036e7c626231e7de265cd64
treeaac6243b4e4e5de1f3f941a7bf6e88d9e46ac01b
parenta21e7ab64f66c83c57b2d87b71c19d50d94ed543

backends: port to new `std.io.BufferedWriter` API


129 files changed, 5611 insertions(+), 6719 deletions(-)

lib/compiler/aro/aro/Compilation.zig+1-1
......@@ -546,7 +546,7 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi
546546 }
547547
548548 try buf.appendSlice("#define __STDC__ 1\n");
549 try buf.writer().print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)});
549 try buf.print("#define __STDC_HOSTED__ {d}\n", .{@intFromBool(comp.target.os.tag != .freestanding)});
550550
551551 // standard macros
552552 try buf.appendSlice(
lib/compiler/build_runner.zig+5-2
......@@ -695,7 +695,10 @@ fn runStepNames(
695695
696696 if (run.summary != .none) {
697697 var bw = std.debug.lockStdErr2(&stdio_buffer);
698 defer std.debug.unlockStdErr();
698 defer {
699 bw.flush() catch {};
700 std.debug.unlockStdErr();
701 }
699702
700703 const total_count = success_count + failure_count + pending_count + skipped_count;
701704 ttyconf.setColor(&bw, .cyan) catch {};
......@@ -710,7 +713,7 @@ fn runStepNames(
710713 if (test_fail_count > 0) bw.print("; {d} failed", .{test_fail_count}) catch {};
711714 if (test_leak_count > 0) bw.print("; {d} leaked", .{test_leak_count}) catch {};
712715
713 bw.writeAll("\n") catch {};
716 bw.writeByte('\n') catch {};
714717
715718 // Print a fancy tree with build results.
716719 var step_stack_copy = try step_stack.clone(gpa);
lib/std/Build/Cache/Path.zig+2-2
......@@ -133,11 +133,11 @@ pub fn makePath(p: Path, sub_path: []const u8) !void {
133133}
134134
135135pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8 {
136 return std.fmt.allocPrint(allocator, "{}", .{p});
136 return std.fmt.allocPrint(allocator, "{f}", .{p});
137137}
138138
139139pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 {
140 return std.fmt.allocPrintZ(allocator, "{}", .{p});
140 return std.fmt.allocPrintZ(allocator, "{f}", .{p});
141141}
142142
143143pub fn format(
lib/std/Build/Step.zig+4-4
......@@ -469,7 +469,7 @@ pub fn evalZigProcess(
469469 // This is intentionally printed for failure on the first build but not for
470470 // subsequent rebuilds.
471471 if (s.result_error_bundle.errorMessageCount() > 0) {
472 return s.fail("the following command failed with {d} compilation errors:\n{s}", .{
472 return s.fail("the following command failed with {d} compilation errors:\n{s}\n", .{
473473 s.result_error_bundle.errorMessageCount(),
474474 try allocPrintCmd(arena, null, argv),
475475 });
......@@ -689,7 +689,7 @@ pub inline fn handleChildProcUnsupported(
689689) error{ OutOfMemory, MakeFailed }!void {
690690 if (!std.process.can_spawn) {
691691 return s.fail(
692 "unable to execute the following command: host cannot spawn child processes\n{s}",
692 "unable to execute the following command: host cannot spawn child processes\n{s}\n",
693693 .{try allocPrintCmd(s.owner.allocator, opt_cwd, argv)},
694694 );
695695 }
......@@ -706,14 +706,14 @@ pub fn handleChildProcessTerm(
706706 .Exited => |code| {
707707 if (code != 0) {
708708 return s.fail(
709 "the following command exited with error code {d}:\n{s}",
709 "the following command exited with error code {d}:\n{s}\n",
710710 .{ code, try allocPrintCmd(arena, opt_cwd, argv) },
711711 );
712712 }
713713 },
714714 .Signal, .Stopped, .Unknown => {
715715 return s.fail(
716 "the following command terminated unexpectedly:\n{s}",
716 "the following command terminated unexpectedly:\n{s}\n",
717717 .{try allocPrintCmd(arena, opt_cwd, argv)},
718718 );
719719 },
lib/std/Build/Step/CheckObject.zig+4-4
......@@ -1523,11 +1523,11 @@ const MachODumper = struct {
15231523 ) !void {
15241524 const size = try br.takeLeb128(u64);
15251525 if (size > 0) {
1526 const flags = try br.takeLeb128(u64);
1526 const flags = try br.takeLeb128(u8);
15271527 switch (flags) {
15281528 macho.EXPORT_SYMBOL_FLAGS_REEXPORT => {
15291529 const ord = try br.takeLeb128(u64);
1530 const name = try br.takeDelimiterConclusive(0);
1530 const name = try br.takeSentinel(0);
15311531 try exports.append(.{
15321532 .name = if (name.len > 0) name else prefix,
15331533 .tag = .reexport,
......@@ -1568,8 +1568,8 @@ const MachODumper = struct {
15681568
15691569 const nedges = try br.takeByte();
15701570 for (0..nedges) |_| {
1571 const label = try br.takeDelimiterConclusive(0);
1572 const off = try br.takeLeb128(u64);
1571 const label = try br.takeSentinel(0);
1572 const off = try br.takeLeb128(usize);
15731573 const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label });
15741574 const seek = br.seek;
15751575 br.seek = off;
lib/std/Target.zig+7-12
......@@ -301,28 +301,23 @@ pub const Os = struct {
301301
302302 /// This function is defined to serialize a Zig source code representation of this
303303 /// type, that, when parsed, will deserialize into the same data.
304 pub fn format(
305 ver: WindowsVersion,
306 comptime fmt_str: []const u8,
307 _: std.fmt.FormatOptions,
308 writer: *std.io.BufferedWriter,
309 ) anyerror!void {
304 pub fn format(ver: WindowsVersion, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
310305 const maybe_name = std.enums.tagName(WindowsVersion, ver);
311306 if (comptime std.mem.eql(u8, fmt_str, "s")) {
312307 if (maybe_name) |name|
313 try writer.print(".{s}", .{name})
308 try bw.print(".{s}", .{name})
314309 else
315 try writer.print(".{d}", .{@intFromEnum(ver)});
310 try bw.print(".{d}", .{@intFromEnum(ver)});
316311 } else if (comptime std.mem.eql(u8, fmt_str, "c")) {
317312 if (maybe_name) |name|
318 try writer.print(".{s}", .{name})
313 try bw.print(".{s}", .{name})
319314 else
320 try writer.print("@enumFromInt(0x{X:0>8})", .{@intFromEnum(ver)});
315 try bw.print("@enumFromInt(0x{X:0>8})", .{@intFromEnum(ver)});
321316 } else if (fmt_str.len == 0) {
322317 if (maybe_name) |name|
323 try writer.print("WindowsVersion.{s}", .{name})
318 try bw.print("WindowsVersion.{s}", .{name})
324319 else
325 try writer.print("WindowsVersion(0x{X:0>8})", .{@intFromEnum(ver)});
320 try bw.print("WindowsVersion(0x{X:0>8})", .{@intFromEnum(ver)});
326321 } else std.fmt.invalidFmtError(fmt_str, ver);
327322 }
328323 };
lib/std/Uri.zig+13-13
......@@ -236,44 +236,44 @@ pub const WriteToStreamOptions = struct {
236236 port: bool = true,
237237};
238238
239pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, writer: *std.io.BufferedWriter) anyerror!void {
239pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.BufferedWriter) anyerror!void {
240240 if (options.scheme) {
241 try writer.print("{s}:", .{uri.scheme});
241 try bw.print("{s}:", .{uri.scheme});
242242 if (options.authority and uri.host != null) {
243 try writer.writeAll("//");
243 try bw.writeAll("//");
244244 }
245245 }
246246 if (options.authority) {
247247 if (options.authentication and uri.host != null) {
248248 if (uri.user) |user| {
249 try writer.print("{fuser}", .{user});
249 try bw.print("{fuser}", .{user});
250250 if (uri.password) |password| {
251 try writer.print(":{fpassword}", .{password});
251 try bw.print(":{fpassword}", .{password});
252252 }
253 try writer.writeByte('@');
253 try bw.writeByte('@');
254254 }
255255 }
256256 if (uri.host) |host| {
257 try writer.print("{fhost}", .{host});
257 try bw.print("{fhost}", .{host});
258258 if (options.port) {
259 if (uri.port) |port| try writer.print(":{d}", .{port});
259 if (uri.port) |port| try bw.print(":{d}", .{port});
260260 }
261261 }
262262 }
263263 if (options.path) {
264 try writer.print("{fpath}", .{
264 try bw.print("{fpath}", .{
265265 if (uri.path.isEmpty()) Uri.Component{ .percent_encoded = "/" } else uri.path,
266266 });
267267 if (options.query) {
268 if (uri.query) |query| try writer.print("?{fquery}", .{query});
268 if (uri.query) |query| try bw.print("?{fquery}", .{query});
269269 }
270270 if (options.fragment) {
271 if (uri.fragment) |fragment| try writer.print("#{ffragment}", .{fragment});
271 if (uri.fragment) |fragment| try bw.print("#{ffragment}", .{fragment});
272272 }
273273 }
274274}
275275
276pub fn format(uri: Uri, comptime fmt: []const u8, _: std.fmt.Options, writer: *std.io.BufferedWriter) anyerror!void {
276pub fn format(uri: Uri, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
277277 const scheme = comptime std.mem.indexOfScalar(u8, fmt, ';') != null or fmt.len == 0;
278278 const authentication = comptime std.mem.indexOfScalar(u8, fmt, '@') != null or fmt.len == 0;
279279 const authority = comptime std.mem.indexOfScalar(u8, fmt, '+') != null or fmt.len == 0;
......@@ -288,7 +288,7 @@ pub fn format(uri: Uri, comptime fmt: []const u8, _: std.fmt.Options, writer: *s
288288 .path = path,
289289 .query = query,
290290 .fragment = fragment,
291 }, writer);
291 }, bw);
292292}
293293
294294/// Parses the URI or returns an error.
lib/std/fmt.zig+1-5
......@@ -531,11 +531,7 @@ pub fn Formatter(comptime formatFn: anytype) type {
531531 const Data = @typeInfo(@TypeOf(formatFn)).@"fn".params[0].type.?;
532532 return struct {
533533 data: Data,
534 pub fn format(
535 self: @This(),
536 writer: *std.io.BufferedWriter,
537 comptime fmt: []const u8,
538 ) anyerror!void {
534 pub fn format(self: @This(), writer: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
539535 try formatFn(self.data, writer, fmt);
540536 }
541537 };
lib/std/io/BufferedReader.zig+79-51
......@@ -201,8 +201,8 @@ pub fn toss(br: *BufferedReader, n: usize) void {
201201
202202/// Equivalent to `peek` + `toss`.
203203pub fn take(br: *BufferedReader, n: usize) anyerror![]u8 {
204 const result = try peek(br, n);
205 toss(br, n);
204 const result = try br.peek(n);
205 br.toss(n);
206206 return result;
207207}
208208
......@@ -218,7 +218,7 @@ pub fn take(br: *BufferedReader, n: usize) anyerror![]u8 {
218218/// See also:
219219/// * `take`
220220pub fn takeArray(br: *BufferedReader, comptime n: usize) anyerror!*[n]u8 {
221 return (try take(br, n))[0..n];
221 return (try br.take(n))[0..n];
222222}
223223
224224/// Skips the next `n` bytes from the stream, advancing the seek position.
......@@ -232,7 +232,7 @@ pub fn takeArray(br: *BufferedReader, comptime n: usize) anyerror!*[n]u8 {
232232/// * `discardUntilEnd`
233233/// * `discardUpTo`
234234pub fn discard(br: *BufferedReader, n: usize) anyerror!void {
235 if ((try discardUpTo(br, n)) != n) return error.EndOfStream;
235 if ((try br.discardUpTo(n)) != n) return error.EndOfStream;
236236}
237237
238238/// Skips the next `n` bytes from the stream, advancing the seek position.
......@@ -325,6 +325,34 @@ pub fn partialRead(br: *BufferedReader, buffer: []u8) anyerror!usize {
325325 @panic("TODO");
326326}
327327
328/// Returns a slice of the next bytes of buffered data from the stream until
329/// `sentinel` is found, advancing the seek position.
330///
331/// Returned slice has a sentinel.
332///
333/// If the stream ends before the sentinel is found, `error.EndOfStream` is
334/// returned.
335///
336/// If the sentinel is not found within a number of bytes matching the
337/// capacity of the `BufferedReader`, `error.StreamTooLong` is returned.
338///
339/// Invalidates previously returned values from `peek`.
340///
341/// See also:
342/// * `peekSentinel`
343/// * `takeDelimiterExclusive`
344/// * `takeDelimiterInclusive`
345pub fn takeSentinel(br: *BufferedReader, comptime sentinel: u8) anyerror![:sentinel]u8 {
346 const result = try br.peekSentinel(sentinel);
347 br.toss(result.len + 1);
348 return result;
349}
350
351pub fn peekSentinel(br: *BufferedReader, comptime sentinel: u8) anyerror![:sentinel]u8 {
352 const result = try br.takeDelimiterInclusive(sentinel);
353 return result[0 .. result.len - 1 :sentinel];
354}
355
328356/// Returns a slice of the next bytes of buffered data from the stream until
329357/// `delimiter` is found, advancing the seek position.
330358///
......@@ -339,36 +367,17 @@ pub fn partialRead(br: *BufferedReader, buffer: []u8) anyerror!usize {
339367/// Invalidates previously returned values from `peek`.
340368///
341369/// See also:
342/// * `takeDelimiterConclusive`
370/// * `takeSentinel`
371/// * `takeDelimiterExclusive`
343372/// * `peekDelimiterInclusive`
344373pub fn takeDelimiterInclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 {
345 const result = try peekDelimiterInclusive(br, delimiter);
346 toss(result.len);
374 const result = try br.peekDelimiterInclusive(delimiter);
375 br.toss(result.len);
347376 return result;
348377}
349378
350379pub fn peekDelimiterInclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 {
351 const storage = &br.storage;
352 const buffer = storage.buffer[0..storage.end];
353 const seek = br.seek;
354 if (std.mem.indexOfScalarPos(u8, buffer, seek, delimiter)) |end| {
355 @branchHint(.likely);
356 return buffer[seek .. end + 1];
357 }
358 const remainder = buffer[seek..];
359 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
360 var i = remainder.len;
361 storage.end = i;
362 br.seek = 0;
363 while (i < storage.buffer.len) {
364 const status = try br.unbuffered_reader.read(storage, .none);
365 if (std.mem.indexOfScalarPos(u8, storage.buffer[0..storage.end], i, delimiter)) |end| {
366 return storage.buffer[0 .. end + 1];
367 }
368 if (status.end) return error.EndOfStream;
369 i = storage.end;
370 }
371 return error.StreamTooLong;
380 return (try br.peekDelimiterInclusiveUnlessEnd(delimiter)) orelse error.EndOfStream;
372381}
373382
374383/// Returns a slice of the next bytes of buffered data from the stream until
......@@ -384,21 +393,32 @@ pub fn peekDelimiterInclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8
384393/// Invalidates previously returned values from `peek`.
385394///
386395/// See also:
396/// * `takeSentinel`
387397/// * `takeDelimiterInclusive`
388/// * `peekDelimiterConclusive`
389pub fn takeDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 {
390 const result = try peekDelimiterConclusive(br, delimiter);
398/// * `peekDelimiterExclusive`
399pub fn takeDelimiterExclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 {
400 const result_unless_end = try br.peekDelimiterInclusiveUnlessEnd(delimiter);
401 const result = result_unless_end orelse {
402 br.toss(br.storage.end);
403 return br.storage.buffer[0..br.storage.end];
404 };
391405 br.toss(result.len);
392 return result;
406 return result[0 .. result.len - 1];
407}
408
409pub fn peekDelimiterExclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 {
410 const result_unless_end = try br.peekDelimiterInclusiveUnlessEnd(delimiter);
411 const result = result_unless_end orelse return br.storage.buffer[0..br.storage.end];
412 return result[0 .. result.len - 1];
393413}
394414
395pub fn peekDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 {
415fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) anyerror!?[]u8 {
396416 const storage = &br.storage;
397417 const buffer = storage.buffer[0..storage.end];
398418 const seek = br.seek;
399419 if (std.mem.indexOfScalarPos(u8, buffer, seek, delimiter)) |end| {
400420 @branchHint(.likely);
401 return buffer[seek..end];
421 return buffer[seek .. end + 1];
402422 }
403423 const remainder = buffer[seek..];
404424 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
......@@ -407,10 +427,8 @@ pub fn peekDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8
407427 br.seek = 0;
408428 while (i < storage.buffer.len) {
409429 const status = try br.unbuffered_reader.read(storage, .unlimited);
410 if (std.mem.indexOfScalarPos(u8, storage.buffer[0..storage.end], i, delimiter)) |end| {
411 return storage.buffer[0 .. end + 1];
412 }
413 if (status.end) return storage.buffer[0..storage.end];
430 if (std.mem.indexOfScalarPos(u8, storage.buffer[0..storage.end], i, delimiter)) |end| return storage.buffer[0 .. end + 1];
431 if (status.end) return null;
414432 i = storage.end;
415433 }
416434 return error.StreamTooLong;
......@@ -436,7 +454,7 @@ pub fn streamReadDelimiter(br: *BufferedReader, bw: *std.io.BufferedWriter, deli
436454///
437455/// Returns number of bytes streamed as well as whether the input reached the end.
438456/// The end is not signaled to the writer.
439pub fn streamReadDelimiterConclusive(
457pub fn streamReadDelimiterExclusive(
440458 br: *BufferedReader,
441459 bw: *std.io.BufferedWriter,
442460 delimiter: u8,
......@@ -468,7 +486,7 @@ pub fn streamReadDelimiterLimited(
468486/// including the delimiter.
469487///
470488/// If end of stream is found, this function succeeds.
471pub fn discardDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror!void {
489pub fn discardDelimiterExclusive(br: *BufferedReader, delimiter: u8) anyerror!void {
472490 _ = br;
473491 _ = delimiter;
474492 @panic("TODO");
......@@ -517,7 +535,7 @@ pub fn takeByte(br: *BufferedReader) anyerror!u8 {
517535 const seek = br.seek;
518536 if (seek >= buffer.len) {
519537 @branchHint(.unlikely);
520 try fill(br, 1);
538 try br.fill(1);
521539 }
522540 br.seek = seek + 1;
523541 return buffer[seek];
......@@ -531,20 +549,20 @@ pub fn takeByteSigned(br: *BufferedReader) anyerror!i8 {
531549/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
532550pub inline fn takeInt(br: *BufferedReader, comptime T: type, endian: std.builtin.Endian) anyerror!T {
533551 const n = @divExact(@typeInfo(T).int.bits, 8);
534 return std.mem.readInt(T, try takeArray(br, n), endian);
552 return std.mem.readInt(T, try br.takeArray(n), endian);
535553}
536554
537555/// Asserts the buffer was initialized with a capacity at least `n`.
538556pub fn takeVarInt(br: *BufferedReader, comptime Int: type, endian: std.builtin.Endian, n: usize) anyerror!Int {
539557 assert(n <= @sizeOf(Int));
540 return std.mem.readVarInt(Int, try take(br, n), endian);
558 return std.mem.readVarInt(Int, try br.take(n), endian);
541559}
542560
543561/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
544562pub fn takeStruct(br: *BufferedReader, comptime T: type) anyerror!*align(1) T {
545563 // Only extern and packed structs have defined in-memory layout.
546564 comptime assert(@typeInfo(T).@"struct".layout != .auto);
547 return @ptrCast(try takeArray(br, @sizeOf(T)));
565 return @ptrCast(try br.takeArray(@sizeOf(T)));
548566}
549567
550568/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
......@@ -561,7 +579,7 @@ pub fn takeStructEndian(br: *BufferedReader, comptime T: type, endian: std.built
561579/// Asserts the buffer was initialized with a capacity at least `@sizeOf(Enum)`.
562580pub fn takeEnum(br: *BufferedReader, comptime Enum: type, endian: std.builtin.Endian) anyerror!Enum {
563581 const Tag = @typeInfo(Enum).@"enum".tag_type;
564 const int = try takeInt(br, Tag, endian);
582 const int = try br.takeInt(Tag, endian);
565583 return std.meta.intToEnum(Enum, int);
566584}
567585
......@@ -588,10 +606,12 @@ fn takeMultipleOf7Leb128(br: *BufferedReader, comptime Result: type) anyerror!Re
588606 const buffer: []const packed struct(u8) { bits: u7, more: bool } = @ptrCast(try br.peekAll(1));
589607 for (buffer, 1..) |byte, len| {
590608 if (remaining_bits > 0) {
591 result = @shlExact(@as(UnsignedResult, byte.bits), result_info.bits - 7) | if (result_info.bits > 7) @shrExact(result, 7) else 0;
609 result = @shlExact(@as(UnsignedResult, byte.bits), result_info.bits - 7) |
610 if (result_info.bits > 7) @shrExact(result, 7) else 0;
592611 remaining_bits -= 7;
593612 } else if (fits) fits = switch (result_info.signedness) {
594 .signed => @as(i7, @bitCast(byte.bits)) == @as(i7, @truncate(@as(Result, @bitCast(result)) >> (result_info.bits - 1))),
613 .signed => @as(i7, @bitCast(byte.bits)) ==
614 @as(i7, @truncate(@as(Result, @bitCast(result)) >> (result_info.bits - 1))),
595615 .unsigned => byte.bits == 0,
596616 };
597617 if (byte.more) continue;
......@@ -652,6 +672,14 @@ test read {
652672 return error.Unimplemented;
653673}
654674
675test takeSentinel {
676 return error.Unimplemented;
677}
678
679test peekSentinel {
680 return error.Unimplemented;
681}
682
655683test takeDelimiterInclusive {
656684 return error.Unimplemented;
657685}
......@@ -660,11 +688,11 @@ test peekDelimiterInclusive {
660688 return error.Unimplemented;
661689}
662690
663test takeDelimiterConclusive {
691test takeDelimiterExclusive {
664692 return error.Unimplemented;
665693}
666694
667test peekDelimiterConclusive {
695test peekDelimiterExclusive {
668696 return error.Unimplemented;
669697}
670698
......@@ -672,7 +700,7 @@ test streamReadDelimiter {
672700 return error.Unimplemented;
673701}
674702
675test streamReadDelimiterConclusive {
703test streamReadDelimiterExclusive {
676704 return error.Unimplemented;
677705}
678706
......@@ -680,7 +708,7 @@ test streamReadDelimiterLimited {
680708 return error.Unimplemented;
681709}
682710
683test discardDelimiterConclusive {
711test discardDelimiterExclusive {
684712 return error.Unimplemented;
685713}
686714
lib/std/io/BufferedWriter.zig+127-110
......@@ -92,7 +92,7 @@ pub fn writableSlice(bw: *BufferedWriter, minimum_length: usize) anyerror![]u8 {
9292 return cap_slice;
9393 }
9494 const buffer = bw.buffer[0..bw.end];
95 const n = try bw.unbuffered_writer.write(buffer);
95 const n = try bw.unbuffered_writer.writev(&.{buffer});
9696 if (n == buffer.len) {
9797 @branchHint(.likely);
9898 bw.end = 0;
......@@ -306,7 +306,7 @@ pub fn write(bw: *BufferedWriter, bytes: []const u8) anyerror!usize {
306306/// transferred.
307307pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) anyerror!void {
308308 var index: usize = 0;
309 while (index < bytes.len) index += try write(bw, bytes[index..]);
309 while (index < bytes.len) index += try bw.write(bytes[index..]);
310310}
311311
312312pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!void {
......@@ -354,7 +354,7 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void {
354354/// many times as necessary.
355355pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) anyerror!void {
356356 var remaining: usize = n;
357 while (remaining > 0) remaining -= try splatByte(bw, byte, remaining);
357 while (remaining > 0) remaining -= try bw.splatByte(byte, remaining);
358358}
359359
360360/// Writes the same byte many times, allowing short writes.
......@@ -368,11 +368,11 @@ pub fn splatByte(bw: *BufferedWriter, byte: u8, n: usize) anyerror!usize {
368368/// many times as necessary.
369369pub fn splatBytesAll(bw: *BufferedWriter, bytes: []const u8, splat: usize) anyerror!void {
370370 var remaining_bytes: usize = bytes.len * splat;
371 remaining_bytes -= try splatBytes(bw, bytes, splat);
371 remaining_bytes -= try bw.splatBytes(bytes, splat);
372372 while (remaining_bytes > 0) {
373373 const leftover = remaining_bytes % bytes.len;
374374 const buffers: [2][]const u8 = .{ bytes[bytes.len - leftover ..], bytes };
375 remaining_bytes -= try splatBytes(bw, &buffers, splat);
375 remaining_bytes -= try bw.splatBytes(&buffers, splat);
376376 }
377377}
378378
......@@ -519,7 +519,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp
519519 const headers_and_trailers = options.headers_and_trailers;
520520 const headers = headers_and_trailers[0..options.headers_len];
521521 switch (options.limit) {
522 .nothing => return writevAll(bw, headers_and_trailers),
522 .nothing => return bw.writevAll(headers_and_trailers),
523523 .unlimited => {
524524 // When reading the whole file, we cannot include the trailers in the
525525 // call that reads from the file handle, because we have no way to
......@@ -528,7 +528,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp
528528 var i: usize = 0;
529529 var offset = options.offset;
530530 while (true) {
531 var n = try writeFile(bw, file, offset, .unlimited, headers[i..], headers.len - i);
531 var n = try bw.writeFile(file, offset, .unlimited, headers[i..], headers.len - i);
532532 while (i < headers.len and n >= headers[i].len) {
533533 n -= headers[i].len;
534534 i += 1;
......@@ -546,7 +546,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp
546546 var i: usize = 0;
547547 var offset = options.offset;
548548 while (true) {
549 var n = try writeFile(bw, file, offset, .limited(len), headers_and_trailers[i..], headers.len - i);
549 var n = try bw.writeFile(file, offset, .limited(len), headers_and_trailers[i..], headers.len - i);
550550 while (i < headers.len and n >= headers[i].len) {
551551 n -= headers[i].len;
552552 i += 1;
......@@ -564,7 +564,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp
564564 if (i >= headers_and_trailers.len) return;
565565 }
566566 headers_and_trailers[i] = headers_and_trailers[i][n..];
567 return writevAll(bw, headers_and_trailers[i..]);
567 return bw.writevAll(headers_and_trailers[i..]);
568568 }
569569 offset = offset.advance(n);
570570 len -= n;
......@@ -605,7 +605,7 @@ pub fn alignBuffer(
605605}
606606
607607pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std.fmt.Options) anyerror!void {
608 return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill);
608 return bw.alignBuffer(buffer, options.width orelse buffer.len, options.alignment, options.fill);
609609}
610610
611611pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void {
......@@ -614,15 +614,15 @@ pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void {
614614 .pointer => |info| {
615615 try bw.writeAll(@typeName(info.child) ++ "@");
616616 if (info.size == .slice)
617 try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{})
617 try bw.printIntOptions(@intFromPtr(value.ptr), 16, .lower, .{})
618618 else
619 try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{});
619 try bw.printIntOptions(@intFromPtr(value), 16, .lower, .{});
620620 return;
621621 },
622622 .optional => |info| {
623623 if (@typeInfo(info.child) == .pointer) {
624624 try bw.writeAll(@typeName(info.child) ++ "@");
625 try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{});
625 try bw.printIntOptions(@intFromPtr(value), 16, .lower, .{});
626626 return;
627627 }
628628 },
......@@ -648,7 +648,7 @@ pub fn printValue(
648648 } else fmt;
649649
650650 if (comptime std.mem.eql(u8, actual_fmt, "*")) {
651 return printAddress(bw, value);
651 return bw.printAddress(value);
652652 }
653653
654654 if (std.meta.hasMethod(T, "format")) {
......@@ -661,24 +661,24 @@ pub fn printValue(
661661 }
662662
663663 switch (@typeInfo(T)) {
664 .float, .comptime_float => return printFloat(bw, actual_fmt, options, value),
665 .int, .comptime_int => return printInt(bw, actual_fmt, options, value),
664 .float, .comptime_float => return bw.printFloat(actual_fmt, options, value),
665 .int, .comptime_int => return bw.printInt(actual_fmt, options, value),
666666 .bool => {
667667 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
668 return alignBufferOptions(bw, if (value) "true" else "false", options);
668 return bw.alignBufferOptions(if (value) "true" else "false", options);
669669 },
670670 .void => {
671671 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
672 return alignBufferOptions(bw, "void", options);
672 return bw.alignBufferOptions("void", options);
673673 },
674674 .optional => {
675675 if (actual_fmt.len == 0 or actual_fmt[0] != '?')
676676 @compileError("cannot print optional without a specifier (i.e. {?} or {any})");
677677 const remaining_fmt = comptime stripOptionalOrErrorUnionSpec(actual_fmt);
678678 if (value) |payload| {
679 return printValue(bw, remaining_fmt, options, payload, max_depth);
679 return bw.printValue(remaining_fmt, options, payload, max_depth);
680680 } else {
681 return alignBufferOptions(bw, "null", options);
681 return bw.alignBufferOptions("null", options);
682682 }
683683 },
684684 .error_union => {
......@@ -686,9 +686,9 @@ pub fn printValue(
686686 @compileError("cannot format error union without a specifier (i.e. {!} or {any})");
687687 const remaining_fmt = comptime stripOptionalOrErrorUnionSpec(actual_fmt);
688688 if (value) |payload| {
689 return printValue(bw, remaining_fmt, options, payload, max_depth);
689 return bw.printValue(remaining_fmt, options, payload, max_depth);
690690 } else |err| {
691 return printValue(bw, "", options, err, max_depth);
691 return bw.printValue("", options, err, max_depth);
692692 }
693693 },
694694 .error_set => {
......@@ -721,14 +721,14 @@ pub fn printValue(
721721 }
722722
723723 try bw.writeByte('(');
724 try printValue(bw, actual_fmt, options, @intFromEnum(value), max_depth);
724 try bw.printValue(actual_fmt, options, @intFromEnum(value), max_depth);
725725 try bw.writeByte(')');
726726 },
727727 .@"union" => |info| {
728728 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
729729 try bw.writeAll(@typeName(T));
730730 if (max_depth == 0) {
731 bw.writeAll("{ ... }");
731 try bw.writeAll("{ ... }");
732732 return;
733733 }
734734 if (info.tag_type) |UnionTagType| {
......@@ -737,13 +737,13 @@ pub fn printValue(
737737 try bw.writeAll(" = ");
738738 inline for (info.fields) |u_field| {
739739 if (value == @field(UnionTagType, u_field.name)) {
740 try printValue(bw, ANY, options, @field(value, u_field.name), max_depth - 1);
740 try bw.printValue(ANY, options, @field(value, u_field.name), max_depth - 1);
741741 }
742742 }
743743 try bw.writeAll(" }");
744744 } else {
745745 try bw.writeByte('@');
746 try bw.printIntOptions(@intFromPtr(&value), 16, .lower);
746 try bw.printIntOptions(@intFromPtr(&value), 16, .lower, options);
747747 }
748748 },
749749 .@"struct" => |info| {
......@@ -761,7 +761,7 @@ pub fn printValue(
761761 } else {
762762 try bw.writeAll(", ");
763763 }
764 try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1);
764 try bw.printValue(ANY, options, @field(value, f.name), max_depth - 1);
765765 }
766766 try bw.writeAll(" }");
767767 return;
......@@ -780,19 +780,19 @@ pub fn printValue(
780780 }
781781 try bw.writeAll(f.name);
782782 try bw.writeAll(" = ");
783 try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1);
783 try bw.printValue(ANY, options, @field(value, f.name), max_depth - 1);
784784 }
785785 try bw.writeAll(" }");
786786 },
787787 .pointer => |ptr_info| switch (ptr_info.size) {
788788 .one => switch (@typeInfo(ptr_info.child)) {
789789 .array, .@"enum", .@"union", .@"struct" => {
790 return printValue(bw, actual_fmt, options, value.*, max_depth);
790 return bw.printValue(actual_fmt, options, value.*, max_depth);
791791 },
792792 else => {
793793 var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" };
794 try writevAll(bw, &buffers);
795 try printIntOptions(bw, @intFromPtr(value), 16, .lower, options);
794 try bw.writevAll(&buffers);
795 try bw.printIntOptions(@intFromPtr(value), 16, .lower, options);
796796 return;
797797 },
798798 },
......@@ -800,10 +800,10 @@ pub fn printValue(
800800 if (actual_fmt.len == 0)
801801 @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");
802802 if (ptr_info.sentinel() != null) {
803 return printValue(bw, actual_fmt, options, std.mem.span(value), max_depth);
803 return bw.printValue(actual_fmt, options, std.mem.span(value), max_depth);
804804 }
805805 if (actual_fmt[0] == 's' and ptr_info.child == u8) {
806 return alignBufferOptions(bw, std.mem.span(value), options);
806 return bw.alignBufferOptions(std.mem.span(value), options);
807807 }
808808 invalidFmtError(fmt, value);
809809 },
......@@ -815,19 +815,19 @@ pub fn printValue(
815815 }
816816 if (ptr_info.child == u8) switch (actual_fmt.len) {
817817 1 => switch (actual_fmt[0]) {
818 's' => return alignBufferOptions(bw, value, options),
819 'x' => return printHex(bw, value, .lower),
820 'X' => return printHex(bw, value, .upper),
818 's' => return bw.alignBufferOptions(value, options),
819 'x' => return bw.printHex(value, .lower),
820 'X' => return bw.printHex(value, .upper),
821821 else => {},
822822 },
823823 3 => if (actual_fmt[0] == 'b' and actual_fmt[1] == '6' and actual_fmt[2] == '4') {
824 return printBase64(bw, value);
824 return bw.printBase64(value);
825825 },
826826 else => {},
827827 };
828828 try bw.writeAll("{ ");
829829 for (value, 0..) |elem, i| {
830 try printValue(bw, actual_fmt, options, elem, max_depth - 1);
830 try bw.printValue(actual_fmt, options, elem, max_depth - 1);
831831 if (i != value.len - 1) {
832832 try bw.writeAll(", ");
833833 }
......@@ -843,16 +843,16 @@ pub fn printValue(
843843 }
844844 if (info.child == u8) {
845845 if (actual_fmt[0] == 's') {
846 return alignBufferOptions(bw, &value, options);
846 return bw.alignBufferOptions(&value, options);
847847 } else if (actual_fmt[0] == 'x') {
848 return printHex(bw, &value, .lower);
848 return bw.printHex(&value, .lower);
849849 } else if (actual_fmt[0] == 'X') {
850 return printHex(bw, &value, .upper);
850 return bw.printHex(&value, .upper);
851851 }
852852 }
853853 try bw.writeAll("{ ");
854854 for (value, 0..) |elem, i| {
855 try printValue(bw, actual_fmt, options, elem, max_depth - 1);
855 try bw.printValue(actual_fmt, options, elem, max_depth - 1);
856856 if (i < value.len - 1) {
857857 try bw.writeAll(", ");
858858 }
......@@ -866,7 +866,7 @@ pub fn printValue(
866866 try bw.writeAll("{ ");
867867 var i: usize = 0;
868868 while (i < info.len) : (i += 1) {
869 try printValue(bw, actual_fmt, options, value[i], max_depth - 1);
869 try bw.printValue(actual_fmt, options, value[i], max_depth - 1);
870870 if (i < info.len - 1) {
871871 try bw.writeAll(", ");
872872 }
......@@ -876,16 +876,16 @@ pub fn printValue(
876876 .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),
877877 .type => {
878878 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
879 return alignBufferOptions(bw, @typeName(value), options);
879 return bw.alignBufferOptions(@typeName(value), options);
880880 },
881881 .enum_literal => {
882882 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
883883 const buffer = [_]u8{'.'} ++ @tagName(value);
884 return alignBufferOptions(bw, buffer, options);
884 return bw.alignBufferOptions(buffer, options);
885885 },
886886 .null => {
887887 if (actual_fmt.len != 0) invalidFmtError(fmt, value);
888 return alignBufferOptions(bw, "null", options);
888 return bw.alignBufferOptions("null", options);
889889 },
890890 else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"),
891891 }
......@@ -903,34 +903,34 @@ pub fn printInt(
903903 } else value;
904904
905905 switch (fmt.len) {
906 0 => return printIntOptions(bw, int_value, 10, .lower, options),
906 0 => return bw.printIntOptions(int_value, 10, .lower, options),
907907 1 => switch (fmt[0]) {
908 'd' => return printIntOptions(bw, int_value, 10, .lower, options),
908 'd' => return bw.printIntOptions(int_value, 10, .lower, options),
909909 'c' => {
910910 if (@typeInfo(@TypeOf(int_value)).int.bits <= 8) {
911 return printAsciiChar(bw, @as(u8, int_value), options);
911 return bw.printAsciiChar(@as(u8, int_value), options);
912912 } else {
913913 @compileError("cannot print integer that is larger than 8 bits as an ASCII character");
914914 }
915915 },
916916 'u' => {
917917 if (@typeInfo(@TypeOf(int_value)).int.bits <= 21) {
918 return printUnicodeCodepoint(bw, @as(u21, int_value), options);
918 return bw.printUnicodeCodepoint(@as(u21, int_value), options);
919919 } else {
920920 @compileError("cannot print integer that is larger than 21 bits as an UTF-8 sequence");
921921 }
922922 },
923 'b' => return printIntOptions(bw, int_value, 2, .lower, options),
924 'x' => return printIntOptions(bw, int_value, 16, .lower, options),
925 'X' => return printIntOptions(bw, int_value, 16, .upper, options),
926 'o' => return printIntOptions(bw, int_value, 8, .lower, options),
927 'B' => return printByteSize(bw, int_value, .decimal, options),
928 'D' => return printDuration(bw, int_value, options),
923 'b' => return bw.printIntOptions(int_value, 2, .lower, options),
924 'x' => return bw.printIntOptions(int_value, 16, .lower, options),
925 'X' => return bw.printIntOptions(int_value, 16, .upper, options),
926 'o' => return bw.printIntOptions(int_value, 8, .lower, options),
927 'B' => return bw.printByteSize(int_value, .decimal, options),
928 'D' => return bw.printDuration(int_value, options),
929929 else => invalidFmtError(fmt, value),
930930 },
931931 2 => {
932932 if (fmt[0] == 'B' and fmt[1] == 'i') {
933 return printByteSize(bw, int_value, .binary, options);
933 return bw.printByteSize(int_value, .binary, options);
934934 } else {
935935 invalidFmtError(fmt, value);
936936 }
......@@ -941,17 +941,17 @@ pub fn printInt(
941941}
942942
943943pub fn printAsciiChar(bw: *BufferedWriter, c: u8, options: std.fmt.Options) anyerror!void {
944 return alignBufferOptions(bw, @as(*const [1]u8, &c), options);
944 return bw.alignBufferOptions(@as(*const [1]u8, &c), options);
945945}
946946
947947pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) anyerror!void {
948 return alignBufferOptions(bw, bytes, options);
948 return bw.alignBufferOptions(bytes, options);
949949}
950950
951951pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) anyerror!void {
952952 var buf: [4]u8 = undefined;
953953 const len = try std.unicode.utf8Encode(c, &buf);
954 return alignBufferOptions(bw, buf[0..len], options);
954 return bw.alignBufferOptions(buf[0..len], options);
955955}
956956
957957pub fn printIntOptions(
......@@ -1019,7 +1019,7 @@ pub fn printIntOptions(
10191019 }
10201020 }
10211021
1022 return alignBufferOptions(bw, buf[index..], options);
1022 return bw.alignBufferOptions(buf[index..], options);
10231023}
10241024
10251025pub fn printFloat(
......@@ -1036,19 +1036,19 @@ pub fn printFloat(
10361036 const s = std.fmt.float.render(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) {
10371037 error.BufferTooSmall => "(float)",
10381038 };
1039 return alignBufferOptions(bw, s, options);
1039 return bw.alignBufferOptions(s, options);
10401040 },
10411041 'd' => {
10421042 const s = std.fmt.float.render(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) {
10431043 error.BufferTooSmall => "(float)",
10441044 };
1045 return alignBufferOptions(bw, s, options);
1045 return bw.alignBufferOptions(s, options);
10461046 },
10471047 'x' => {
10481048 var sub_bw: BufferedWriter = undefined;
10491049 sub_bw.initFixed(&buf);
10501050 sub_bw.printFloatHexadecimal(value, options.precision) catch unreachable;
1051 return alignBufferOptions(bw, sub_bw.getWritten(), options);
1051 return bw.alignBufferOptions(sub_bw.getWritten(), options);
10521052 },
10531053 else => invalidFmtError(fmt, value),
10541054 }
......@@ -1150,7 +1150,7 @@ pub fn printFloatHexadecimal(bw: *BufferedWriter, value: anytype, opt_precision:
11501150 try bw.splatByteAll('0', precision - trimmed.len);
11511151 };
11521152 try bw.writeAll("p");
1153 try printIntOptions(bw, exponent - exponent_bias, 10, .lower, .{});
1153 try bw.printIntOptions(exponent - exponent_bias, 10, .lower, .{});
11541154}
11551155
11561156pub const ByteSizeUnits = enum {
......@@ -1169,7 +1169,7 @@ pub fn printByteSize(
11691169 comptime units: ByteSizeUnits,
11701170 options: std.fmt.Options,
11711171) anyerror!void {
1172 if (value == 0) return alignBufferOptions(bw, "0B", options);
1172 if (value == 0) return bw.alignBufferOptions("0B", options);
11731173 // The worst case in terms of space needed is 32 bytes + 3 for the suffix.
11741174 var buf: [std.fmt.float.min_buffer_size + 3]u8 = undefined;
11751175
......@@ -1213,7 +1213,7 @@ pub fn printByteSize(
12131213 },
12141214 }
12151215
1216 return alignBufferOptions(bw, buf[0..i], options);
1216 return bw.alignBufferOptions(buf[0..i], options);
12171217}
12181218
12191219// This ANY const is a workaround for: https://github.com/ziglang/zig/issues/7948
......@@ -1250,7 +1250,7 @@ pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn {
12501250
12511251pub fn printDurationSigned(bw: *BufferedWriter, ns: i64) anyerror!void {
12521252 if (ns < 0) try bw.writeByte('-');
1253 return printDurationUnsigned(bw, @abs(ns));
1253 return bw.printDurationUnsigned(@abs(ns));
12541254}
12551255
12561256pub fn printDurationUnsigned(bw: *BufferedWriter, ns: u64) anyerror!void {
......@@ -1296,7 +1296,7 @@ pub fn printDurationUnsigned(bw: *BufferedWriter, ns: u64) anyerror!void {
12961296 }
12971297 }
12981298
1299 try printIntOptions(bw, ns_remaining, 10, .lower, .{});
1299 try bw.printIntOptions(ns_remaining, 10, .lower, .{});
13001300 try bw.writeAll("ns");
13011301}
13021302
......@@ -1312,7 +1312,7 @@ pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt
13121312 .signed => sub_bw.printDurationSigned(nanoseconds) catch unreachable,
13131313 .unsigned => sub_bw.printDurationUnsigned(nanoseconds) catch unreachable,
13141314 }
1315 return alignBufferOptions(bw, sub_bw.getWritten(), options);
1315 return bw.alignBufferOptions(sub_bw.getWritten(), options);
13161316}
13171317
13181318pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anyerror!void {
......@@ -1321,8 +1321,8 @@ pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anye
13211321 .lower => "0123456789abcdef",
13221322 };
13231323 for (bytes) |c| {
1324 try writeByte(bw, charset[c >> 4]);
1325 try writeByte(bw, charset[c & 15]);
1324 try bw.writeByte(charset[c >> 4]);
1325 try bw.writeByte(charset[c & 15]);
13261326 }
13271327}
13281328
......@@ -1334,50 +1334,67 @@ pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) anyerror!void {
13341334 }
13351335}
13361336
1337/// Write a single unsigned integer as unsigned LEB128 to the given writer.
1338pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!void {
1339 const Arg = @TypeOf(arg);
1340 const Int = switch (Arg) {
1341 comptime_int => std.math.IntFittingRange(arg, arg),
1342 else => Arg,
1343 };
1344 const Value = if (@typeInfo(Int).int.bits < 8) u8 else Int;
1345 var value: Value = arg;
1337/// Write a single unsigned integer as LEB128 to the given writer.
1338pub fn writeUleb128(bw: *BufferedWriter, value: anytype) anyerror!void {
1339 try bw.writeLeb128(switch (@typeInfo(@TypeOf(value))) {
1340 .comptime_int => @as(std.math.IntFittingRange(0, @abs(value)), value),
1341 .int => |value_info| switch (value_info.signedness) {
1342 .signed => @as(@Type(.{ .int = .{ .signedness = .unsigned, .bits = value_info.bits -| 1 } }), @intCast(value)),
1343 .unsigned => value,
1344 },
1345 else => comptime unreachable,
1346 });
1347}
13461348
1347 while (true) {
1348 const byte: u8 = @truncate(value & 0x7f);
1349 value >>= 7;
1350 if (value == 0) {
1351 try bw.writeByte(byte);
1352 return;
1353 } else {
1354 try bw.writeByte(byte | 0x80);
1355 }
1356 }
1349/// Write a single signed integer as LEB128 to the given writer.
1350pub fn writeSleb128(bw: *BufferedWriter, value: anytype) anyerror!void {
1351 try bw.writeLeb128(switch (@typeInfo(@TypeOf(value))) {
1352 .comptime_int => @as(std.math.IntFittingRange(@min(value, -1), @max(0, value)), value),
1353 .int => |value_info| switch (value_info.signedness) {
1354 .signed => value,
1355 .unsigned => @as(@Type(.{ .int = .{ .signedness = .signed, .bits = value_info.bits + 1 } }), value),
1356 },
1357 else => comptime unreachable,
1358 });
13571359}
13581360
1359/// Write a single signed integer as signed LEB128 to the given writer.
1360pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!void {
1361 const Arg = @TypeOf(arg);
1362 const Int = switch (Arg) {
1363 comptime_int => std.math.IntFittingRange(-@abs(arg), @abs(arg)),
1364 else => Arg,
1365 };
1366 const Signed = if (@typeInfo(Int).int.bits < 8) i8 else Int;
1367 const Unsigned = std.meta.Int(.unsigned, @typeInfo(Signed).int.bits);
1368 var value: Signed = arg;
1361/// Write a single integer as LEB128 to the given writer.
1362pub fn writeLeb128(bw: *BufferedWriter, value: anytype) anyerror!void {
1363 const value_info = @typeInfo(@TypeOf(value)).int;
1364 try bw.writeMultipleOf7Leb128(@as(@Type(.{ .int = .{
1365 .signedness = value_info.signedness,
1366 .bits = std.mem.alignForwardAnyAlign(u16, value_info.bits, 7),
1367 } }), value));
1368}
13691369
1370fn writeMultipleOf7Leb128(bw: *BufferedWriter, value: anytype) anyerror!void {
1371 const value_info = @typeInfo(@TypeOf(value)).int;
1372 comptime assert(value_info.bits % 7 == 0);
1373 var remaining = value;
13701374 while (true) {
1371 const unsigned: Unsigned = @bitCast(value);
1372 const byte: u8 = @truncate(unsigned);
1373 value >>= 6;
1374 if (value == -1 or value == 0) {
1375 try bw.writeByte(byte & 0x7F);
1376 return;
1377 } else {
1378 value >>= 1;
1379 try bw.writeByte(byte | 0x80);
1375 const buffer: []packed struct(u8) { bits: u7, more: bool } = @ptrCast(try bw.writableSlice(1));
1376 for (buffer, 1..) |*byte, len| {
1377 const more = switch (value_info.signedness) {
1378 .signed => remaining >> 6 != remaining >> (value_info.bits - 1),
1379 .unsigned => remaining > std.math.maxInt(u7),
1380 };
1381 byte.* = if (@inComptime()) @typeInfo(@TypeOf(buffer)).pointer.child{
1382 .bits = @bitCast(@as(@Type(.{ .int = .{
1383 .signedness = value_info.signedness,
1384 .bits = 7,
1385 } }), @truncate(remaining))),
1386 .more = more,
1387 } else .{
1388 .bits = @bitCast(@as(@Type(.{ .int = .{
1389 .signedness = value_info.signedness,
1390 .bits = 7,
1391 } }), @truncate(remaining))),
1392 .more = more,
1393 };
1394 if (value_info.bits > 7) remaining >>= 7;
1395 if (!more) return bw.advance(len);
13801396 }
1397 bw.advance(buffer.len);
13811398 }
13821399}
13831400
lib/std/leb128.zig+2-2
......@@ -55,10 +55,10 @@ test writeUnsignedFixed {
5555}
5656
5757/// This is an "advanced" function. It allows one to use a fixed amount of memory to store an
58/// ILEB128. This defeats the entire purpose of using this data encoding; it will no longer use
58/// SLEB128. This defeats the entire purpose of using this data encoding; it will no longer use
5959/// fewer bytes to store smaller numbers. The advantage of using a fixed width is that it makes
6060/// fields have a predictable size and so depending on the use case this tradeoff can be worthwhile.
61/// An example use case of this is in emitting DWARF info where one wants to make a ILEB128 field
61/// An example use case of this is in emitting DWARF info where one wants to make a SLEB128 field
6262/// "relocatable", meaning that it becomes possible to later go back and patch the number to be a
6363/// different value without shifting all the following code.
6464pub fn writeSignedFixed(comptime l: usize, ptr: *[l]u8, int: std.meta.Int(.signed, l * 7)) void {
lib/std/math/big/int.zig+16-20
......@@ -2322,13 +2322,7 @@ pub const Const = struct {
23222322 /// this function will fail to print the string, printing "(BigInt)" instead of a number.
23232323 /// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
23242324 /// See `toString` and `toStringAlloc` for a way to print big integers without failure.
2325 pub fn format(
2326 self: Const,
2327 comptime fmt: []const u8,
2328 options: std.fmt.FormatOptions,
2329 out_stream: anytype,
2330 ) !void {
2331 _ = options;
2325 pub fn format(self: Const, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
23322326 comptime var base = 10;
23332327 comptime var case: std.fmt.Case = .lower;
23342328
......@@ -2348,19 +2342,21 @@ pub const Const = struct {
23482342 std.fmt.invalidFmtError(fmt, self);
23492343 }
23502344
2351 const available_len = 64;
2352 if (self.limbs.len > available_len)
2353 return out_stream.writeAll("(BigInt)");
2354
2355 var limbs: [calcToStringLimbsBufferLen(available_len, base)]Limb = undefined;
2356
2357 const biggest: Const = .{
2358 .limbs = &([1]Limb{comptime math.maxInt(Limb)} ** available_len),
2359 .positive = false,
2360 };
2361 var buf: [biggest.sizeInBaseUpperBound(base)]u8 = undefined;
2362 const len = self.toString(&buf, base, case, &limbs);
2363 return out_stream.writeAll(buf[0..len]);
2345 const max_str_len = self.sizeInBaseUpperBound(base);
2346 const limbs_len = calcToStringLimbsBufferLen(self.limbs.len, base);
2347 if (bw.writableSlice(max_str_len + @alignOf(Limb) - 1 + @sizeOf(Limb) * limbs_len)) |buf| {
2348 const limbs: [*]Limb = @alignCast(@ptrCast(std.mem.alignPointer(buf[max_str_len..].ptr, @alignOf(Limb))));
2349 bw.advance(self.toString(buf[0..max_str_len], base, case, limbs[0..limbs_len]));
2350 return;
2351 } else |_| if (bw.writableSlice(max_str_len)) |buf| {
2352 const available_len = 64;
2353 var limbs: [calcToStringLimbsBufferLen(available_len, base)]Limb = undefined;
2354 if (limbs.len >= limbs_len) {
2355 bw.advance(self.toString(buf, base, case, &limbs));
2356 return;
2357 }
2358 } else |_| {}
2359 try bw.writeAll("(BigInt)");
23642360 }
23652361
23662362 /// Converts self to a string in the requested base.
lib/std/net.zig+2-2
......@@ -1358,7 +1358,7 @@ fn linuxLookupNameFromHosts(
13581358
13591359 var line_buf: [512]u8 = undefined;
13601360 var br = file.reader().buffered(&line_buf);
1361 while (br.takeDelimiterConclusive('\n')) |line| {
1361 while (br.takeSentinel('\n')) |line| {
13621362 var split_it = mem.splitScalar(u8, line, '#');
13631363 const no_comment_line = split_it.first();
13641364
......@@ -1550,7 +1550,7 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void {
15501550
15511551 var line_buf: [512]u8 = undefined;
15521552 var br = file.reader().buffered(&line_buf);
1553 while (br.takeDelimiterConclusive('\n')) |line_with_comment| {
1553 while (br.takeSentinel('\n')) |line_with_comment| {
15541554 const line = line: {
15551555 var split = mem.splitScalar(u8, line_with_comment, '#');
15561556 break :line split.first();
lib/std/zig.zig+4-4
......@@ -544,9 +544,9 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: u
544544 var buffer: std.ArrayListAlignedUnmanaged(u8, .@"2") = .empty;
545545 defer buffer.deinit(gpa);
546546
547 try buffer.ensureUnusedCapacity(size_hint);
547 try buffer.ensureUnusedCapacity(gpa, size_hint);
548548
549 input.readIntoArrayList(gpa, .init(max_src_size), .@"2", &buffer) catch |err| switch (err) {
549 input.readIntoArrayList(gpa, .limited(max_src_size), .@"2", &buffer) catch |err| switch (err) {
550550 error.ConnectionResetByPeer => unreachable,
551551 error.ConnectionTimedOut => unreachable,
552552 error.NotOpenForReading => unreachable,
......@@ -568,7 +568,7 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: u
568568 // If the file starts with a UTF-16 little endian BOM, translate it to UTF-8
569569 if (std.mem.startsWith(u8, buffer.items, "\xff\xfe")) {
570570 if (buffer.items.len % 2 != 0) return error.InvalidEncoding;
571 return std.unicode.utf16LeToUtf8AllocZ(gpa, buffer.items) catch |err| switch (err) {
571 return std.unicode.utf16LeToUtf8AllocZ(gpa, @ptrCast(buffer.items)) catch |err| switch (err) {
572572 error.DanglingSurrogateHalf => error.UnsupportedEncoding,
573573 error.ExpectedSecondSurrogateHalf => error.UnsupportedEncoding,
574574 error.UnexpectedSecondSurrogateHalf => error.UnsupportedEncoding,
......@@ -576,7 +576,7 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: u
576576 };
577577 }
578578
579 return buffer.toOwnedSliceSentinel(0);
579 return buffer.toOwnedSliceSentinel(gpa, 0);
580580}
581581
582582pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color: Color) !void {
lib/std/zig/Ast.zig+1-1
......@@ -562,7 +562,7 @@ pub fn renderError(tree: Ast, parse_error: Error, bw: *std.io.BufferedWriter) an
562562
563563 .invalid_byte => {
564564 const tok_slice = tree.source[tree.tokens.items(.start)[parse_error.token]..];
565 return bw.print("{s} contains invalid byte: '{'}'", .{
565 return bw.print("{s} contains invalid byte: '{f'}'", .{
566566 switch (tok_slice[0]) {
567567 '\'' => "character literal",
568568 '"', '\\' => "string literal",
lib/std/zig/AstGen.zig+7-6
......@@ -11465,7 +11465,7 @@ fn failWithStrLitError(
1146511465 astgen,
1146611466 token,
1146711467 @intCast(offset + err.offset()),
11468 "{}",
11468 "{f}",
1146911469 .{err.fmt(raw_string)},
1147011470 );
1147111471}
......@@ -13898,8 +13898,9 @@ fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void {
1389813898 assert(tree.errors.len > 0);
1389913899
1390013900 var msg: std.io.AllocatingWriter = undefined;
13901 const msg_writer = msg.init(gpa);
13901 msg.init(gpa);
1390213902 defer msg.deinit();
13903 const msg_bw = &msg.buffered_writer;
1390313904
1390413905 var notes: std.ArrayListUnmanaged(u32) = .empty;
1390513906 defer notes.deinit(gpa);
......@@ -13933,19 +13934,19 @@ fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void {
1393313934 .extra = .{ .offset = bad_off },
1393413935 };
1393513936 msg.clearRetainingCapacity();
13936 tree.renderError(err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13937 tree.renderError(err, msg_bw) catch |e| return @errorCast(e); // TODO try @errorCast(...)
1393713938 return try astgen.appendErrorTokNotesOff(tok, bad_off, "{s}", .{msg.getWritten()}, notes.items);
1393813939 }
1393913940
1394013941 var cur_err = tree.errors[0];
1394113942 for (tree.errors[1..]) |err| {
1394213943 if (err.is_note) {
13943 tree.renderError(err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13944 tree.renderError(err, msg_bw) catch |e| return @errorCast(e); // TODO try @errorCast(...)
1394413945 try notes.append(gpa, try astgen.errNoteTok(err.token, "{s}", .{msg.getWritten()}));
1394513946 } else {
1394613947 // Flush error
1394713948 const extra_offset = tree.errorOffset(cur_err);
13948 tree.renderError(cur_err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13949 tree.renderError(cur_err, msg_bw) catch |e| return @errorCast(e); // TODO try @errorCast(...)
1394913950 try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items);
1395013951 notes.clearRetainingCapacity();
1395113952 cur_err = err;
......@@ -13959,7 +13960,7 @@ fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void {
1395913960
1396013961 // Flush error
1396113962 const extra_offset = tree.errorOffset(cur_err);
13962 tree.renderError(cur_err, msg_writer) catch |e| return @errorCast(e); // TODO try @errorCast(...)
13963 tree.renderError(cur_err, msg_bw) catch |e| return @errorCast(e); // TODO try @errorCast(...)
1396313964 try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items);
1396413965}
1396513966
lib/std/zig/LibCInstallation.zig+1-1
......@@ -43,7 +43,7 @@ pub fn parse(
4343 }
4444 }
4545
46 const contents = try std.fs.cwd().readFileAlloc(allocator, libc_file, std.math.maxInt(usize));
46 const contents = try std.fs.cwd().readFileAlloc(libc_file, allocator, .unlimited);
4747 defer allocator.free(contents);
4848
4949 var it = std.mem.tokenizeScalar(u8, contents, '\n');
lib/std/zig/ZonGen.zig+3-2
......@@ -778,7 +778,7 @@ fn lowerStrLitError(
778778 zg,
779779 token,
780780 @intCast(offset + err.offset()),
781 "{}",
781 "{f}",
782782 .{err.fmt(raw_string)},
783783 );
784784}
......@@ -885,8 +885,9 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void {
885885 assert(tree.errors.len > 0);
886886
887887 var msg: std.io.AllocatingWriter = undefined;
888 const msg_bw = msg.init(gpa);
888 msg.init(gpa);
889889 defer msg.deinit();
890 const msg_bw = &msg.buffered_writer;
890891
891892 var notes: std.ArrayListUnmanaged(Zoir.CompileError.Note) = .empty;
892893 defer notes.deinit(gpa);
lib/std/zig/llvm/BitcodeReader.zig+12-12
......@@ -1,6 +1,6 @@
11allocator: std.mem.Allocator,
22record_arena: std.heap.ArenaAllocator.State,
3reader: std.io.AnyReader,
3br: *std.io.BufferedReader,
44keep_names: bool,
55bit_buffer: u32,
66bit_offset: u5,
......@@ -93,14 +93,14 @@ pub const Record = struct {
9393};
9494
9595pub const InitOptions = struct {
96 reader: std.io.AnyReader,
96 br: *std.io.BufferedReader,
9797 keep_names: bool = false,
9898};
9999pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader {
100100 return .{
101101 .allocator = allocator,
102102 .record_arena = .{},
103 .reader = options.reader,
103 .br = options.br,
104104 .keep_names = options.keep_names,
105105 .bit_buffer = 0,
106106 .bit_offset = 0,
......@@ -170,9 +170,9 @@ pub fn next(bc: *BitcodeReader) !?Item {
170170 }
171171}
172172
173pub fn skipBlock(bc: *BitcodeReader, block: Block) !void {
173pub fn skipBlock(bc: *BitcodeReader, block: Block) anyerror!void {
174174 assert(bc.bit_offset == 0);
175 try bc.reader.skipBytes(@as(u34, block.len) * 4, .{});
175 try bc.br.discard(4 * @as(u34, block.len));
176176 try bc.endBlock();
177177}
178178
......@@ -369,21 +369,21 @@ fn align32Bits(bc: *BitcodeReader) void {
369369 bc.bit_offset = 0;
370370}
371371
372fn read32Bits(bc: *BitcodeReader) !u32 {
372fn read32Bits(bc: *BitcodeReader) anyerror!u32 {
373373 assert(bc.bit_offset == 0);
374 return bc.reader.readInt(u32, .little);
374 return bc.br.takeInt(u32, .little);
375375}
376376
377fn readBytes(bc: *BitcodeReader, bytes: []u8) !void {
377fn readBytes(bc: *BitcodeReader, bytes: []u8) anyerror!void {
378378 assert(bc.bit_offset == 0);
379 try bc.reader.readNoEof(bytes);
379 try bc.br.read(bytes);
380380
381381 const trailing_bytes = bytes.len % 4;
382382 if (trailing_bytes > 0) {
383 var bit_buffer = [1]u8{0} ** 4;
384 try bc.reader.readNoEof(bit_buffer[trailing_bytes..]);
383 var bit_buffer: [4]u8 = @splat(0);
384 try bc.br.read(bit_buffer[trailing_bytes..]);
385385 bc.bit_buffer = std.mem.readInt(u32, &bit_buffer, .little);
386 bc.bit_offset = @intCast(trailing_bytes * 8);
386 bc.bit_offset = @intCast(8 * trailing_bytes);
387387 }
388388}
389389
lib/std/zig/llvm/Builder.zig+343-508
......@@ -91,26 +91,21 @@ pub const String = enum(u32) {
9191 string: String,
9292 builder: *const Builder,
9393 };
94 fn format(
95 data: FormatData,
96 comptime fmt_str: []const u8,
97 _: std.fmt.FormatOptions,
98 writer: anytype,
99 ) @TypeOf(writer).Error!void {
94 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
10095 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
10196 @compileError("invalid format string: '" ++ fmt_str ++ "'");
10297 assert(data.string != .none);
10398 const string_slice = data.string.slice(data.builder) orelse
104 return writer.print("{d}", .{@intFromEnum(data.string)});
99 return bw.print("{d}", .{@intFromEnum(data.string)});
105100 if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_|
106 return writer.writeAll(string_slice);
101 return bw.writeAll(string_slice);
107102 try printEscapedString(
108103 string_slice,
109104 if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_|
110105 .always_quote
111106 else
112107 .quote_unless_valid_identifier,
113 writer,
108 bw,
114109 );
115110 }
116111 pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(format) {
......@@ -228,7 +223,7 @@ pub const Type = enum(u32) {
228223 _,
229224
230225 pub const ptr_amdgpu_constant =
231 @field(Type, std.fmt.comptimePrint("ptr{ }", .{AddrSpace.amdgpu.constant}));
226 @field(Type, std.fmt.comptimePrint("ptr{f }", .{AddrSpace.amdgpu.constant}));
232227
233228 pub const Tag = enum(u4) {
234229 simple,
......@@ -654,17 +649,12 @@ pub const Type = enum(u32) {
654649 type: Type,
655650 builder: *const Builder,
656651 };
657 fn format(
658 data: FormatData,
659 comptime fmt_str: []const u8,
660 fmt_opts: std.fmt.FormatOptions,
661 writer: anytype,
662 ) @TypeOf(writer).Error!void {
652 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
663653 assert(data.type != .none);
664654 if (comptime std.mem.eql(u8, fmt_str, "m")) {
665655 const item = data.builder.type_items.items[@intFromEnum(data.type)];
666656 switch (item.tag) {
667 .simple => try writer.writeAll(switch (@as(Simple, @enumFromInt(item.data))) {
657 .simple => try bw.writeAll(switch (@as(Simple, @enumFromInt(item.data))) {
668658 .void => "isVoid",
669659 .half => "f16",
670660 .bfloat => "bf16",
......@@ -681,29 +671,29 @@ pub const Type = enum(u32) {
681671 .function, .vararg_function => |kind| {
682672 var extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
683673 const params = extra.trail.next(extra.data.params_len, Type, data.builder);
684 try writer.print("f_{m}", .{extra.data.ret.fmt(data.builder)});
685 for (params) |param| try writer.print("{m}", .{param.fmt(data.builder)});
674 try bw.print("f_{fm}", .{extra.data.ret.fmt(data.builder)});
675 for (params) |param| try bw.print("{fm}", .{param.fmt(data.builder)});
686676 switch (kind) {
687677 .function => {},
688 .vararg_function => try writer.writeAll("vararg"),
678 .vararg_function => try bw.writeAll("vararg"),
689679 else => unreachable,
690680 }
691 try writer.writeByte('f');
681 try bw.writeByte('f');
692682 },
693 .integer => try writer.print("i{d}", .{item.data}),
694 .pointer => try writer.print("p{d}", .{item.data}),
683 .integer => try bw.print("i{d}", .{item.data}),
684 .pointer => try bw.print("p{d}", .{item.data}),
695685 .target => {
696686 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
697687 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
698688 const ints = extra.trail.next(extra.data.ints_len, u32, data.builder);
699 try writer.print("t{s}", .{extra.data.name.slice(data.builder).?});
700 for (types) |ty| try writer.print("_{m}", .{ty.fmt(data.builder)});
701 for (ints) |int| try writer.print("_{d}", .{int});
702 try writer.writeByte('t');
689 try bw.print("t{s}", .{extra.data.name.slice(data.builder).?});
690 for (types) |ty| try bw.print("_{fm}", .{ty.fmt(data.builder)});
691 for (ints) |int| try bw.print("_{d}", .{int});
692 try bw.writeByte('t');
703693 },
704694 .vector, .scalable_vector => |kind| {
705695 const extra = data.builder.typeExtraData(Type.Vector, item.data);
706 try writer.print("{s}v{d}{m}", .{
696 try bw.print("{s}v{d}{fm}", .{
707697 switch (kind) {
708698 .vector => "",
709699 .scalable_vector => "nx",
......@@ -719,24 +709,24 @@ pub const Type = enum(u32) {
719709 .array => Type.Array,
720710 else => unreachable,
721711 }, item.data);
722 try writer.print("a{d}{m}", .{ extra.length(), extra.child.fmt(data.builder) });
712 try bw.print("a{d}{fm}", .{ extra.length(), extra.child.fmt(data.builder) });
723713 },
724714 .structure, .packed_structure => {
725715 var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
726716 const fields = extra.trail.next(extra.data.fields_len, Type, data.builder);
727 try writer.writeAll("sl_");
728 for (fields) |field| try writer.print("{m}", .{field.fmt(data.builder)});
729 try writer.writeByte('s');
717 try bw.writeAll("sl_");
718 for (fields) |field| try bw.print("{fm}", .{field.fmt(data.builder)});
719 try bw.writeByte('s');
730720 },
731721 .named_structure => {
732722 const extra = data.builder.typeExtraData(Type.NamedStructure, item.data);
733 try writer.writeAll("s_");
734 if (extra.id.slice(data.builder)) |id| try writer.writeAll(id);
723 try bw.writeAll("s_");
724 if (extra.id.slice(data.builder)) |id| try bw.writeAll(id);
735725 },
736726 }
737727 return;
738728 }
739 if (std.enums.tagName(Type, data.type)) |name| return writer.writeAll(name);
729 if (std.enums.tagName(Type, data.type)) |name| return bw.writeAll(name);
740730 const item = data.builder.type_items.items[@intFromEnum(data.type)];
741731 switch (item.tag) {
742732 .simple => unreachable,
......@@ -744,40 +734,40 @@ pub const Type = enum(u32) {
744734 var extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
745735 const params = extra.trail.next(extra.data.params_len, Type, data.builder);
746736 if (!comptime std.mem.eql(u8, fmt_str, ">"))
747 try writer.print("{%} ", .{extra.data.ret.fmt(data.builder)});
737 try bw.print("{f%} ", .{extra.data.ret.fmt(data.builder)});
748738 if (!comptime std.mem.eql(u8, fmt_str, "<")) {
749 try writer.writeByte('(');
739 try bw.writeByte('(');
750740 for (params, 0..) |param, index| {
751 if (index > 0) try writer.writeAll(", ");
752 try writer.print("{%}", .{param.fmt(data.builder)});
741 if (index > 0) try bw.writeAll(", ");
742 try bw.print("{f%}", .{param.fmt(data.builder)});
753743 }
754744 switch (kind) {
755745 .function => {},
756746 .vararg_function => {
757 if (params.len > 0) try writer.writeAll(", ");
758 try writer.writeAll("...");
747 if (params.len > 0) try bw.writeAll(", ");
748 try bw.writeAll("...");
759749 },
760750 else => unreachable,
761751 }
762 try writer.writeByte(')');
752 try bw.writeByte(')');
763753 }
764754 },
765 .integer => try writer.print("i{d}", .{item.data}),
766 .pointer => try writer.print("ptr{ }", .{@as(AddrSpace, @enumFromInt(item.data))}),
755 .integer => try bw.print("i{d}", .{item.data}),
756 .pointer => try bw.print("ptr{f }", .{@as(AddrSpace, @enumFromInt(item.data))}),
767757 .target => {
768758 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
769759 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
770760 const ints = extra.trail.next(extra.data.ints_len, u32, data.builder);
771 try writer.print(
772 \\target({"}
761 try bw.print(
762 \\target({f"}
773763 , .{extra.data.name.fmt(data.builder)});
774 for (types) |ty| try writer.print(", {%}", .{ty.fmt(data.builder)});
775 for (ints) |int| try writer.print(", {d}", .{int});
776 try writer.writeByte(')');
764 for (types) |ty| try bw.print(", {f%}", .{ty.fmt(data.builder)});
765 for (ints) |int| try bw.print(", {d}", .{int});
766 try bw.writeByte(')');
777767 },
778768 .vector, .scalable_vector => |kind| {
779769 const extra = data.builder.typeExtraData(Type.Vector, item.data);
780 try writer.print("<{s}{d} x {%}>", .{
770 try bw.print("<{s}{d} x {f%}>", .{
781771 switch (kind) {
782772 .vector => "",
783773 .scalable_vector => "vscale x ",
......@@ -793,38 +783,38 @@ pub const Type = enum(u32) {
793783 .array => Type.Array,
794784 else => unreachable,
795785 }, item.data);
796 try writer.print("[{d} x {%}]", .{ extra.length(), extra.child.fmt(data.builder) });
786 try bw.print("[{d} x {f%}]", .{ extra.length(), extra.child.fmt(data.builder) });
797787 },
798788 .structure, .packed_structure => |kind| {
799789 var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
800790 const fields = extra.trail.next(extra.data.fields_len, Type, data.builder);
801791 switch (kind) {
802792 .structure => {},
803 .packed_structure => try writer.writeByte('<'),
793 .packed_structure => try bw.writeByte('<'),
804794 else => unreachable,
805795 }
806 try writer.writeAll("{ ");
796 try bw.writeAll("{ ");
807797 for (fields, 0..) |field, index| {
808 if (index > 0) try writer.writeAll(", ");
809 try writer.print("{%}", .{field.fmt(data.builder)});
798 if (index > 0) try bw.writeAll(", ");
799 try bw.print("{f%}", .{field.fmt(data.builder)});
810800 }
811 try writer.writeAll(" }");
801 try bw.writeAll(" }");
812802 switch (kind) {
813803 .structure => {},
814 .packed_structure => try writer.writeByte('>'),
804 .packed_structure => try bw.writeByte('>'),
815805 else => unreachable,
816806 }
817807 },
818808 .named_structure => {
819809 const extra = data.builder.typeExtraData(Type.NamedStructure, item.data);
820 if (comptime std.mem.eql(u8, fmt_str, "%")) try writer.print("%{}", .{
810 if (comptime std.mem.eql(u8, fmt_str, "%")) try bw.print("%{f}", .{
821811 extra.id.fmt(data.builder),
822812 }) else switch (extra.body) {
823 .none => try writer.writeAll("opaque"),
813 .none => try bw.writeAll("opaque"),
824814 else => try format(.{
825815 .type = extra.body,
826816 .builder = data.builder,
827 }, fmt_str, fmt_opts, writer),
817 }, bw, fmt_str),
828818 }
829819 },
830820 }
......@@ -1139,12 +1129,7 @@ pub const Attribute = union(Kind) {
11391129 attribute_index: Index,
11401130 builder: *const Builder,
11411131 };
1142 fn format(
1143 data: FormatData,
1144 comptime fmt_str: []const u8,
1145 _: std.fmt.FormatOptions,
1146 writer: anytype,
1147 ) @TypeOf(writer).Error!void {
1132 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
11481133 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"#")) |_|
11491134 @compileError("invalid format string: '" ++ fmt_str ++ "'");
11501135 const attribute = data.attribute_index.toAttribute(data.builder);
......@@ -1219,37 +1204,37 @@ pub const Attribute = union(Kind) {
12191204 .no_sanitize_address,
12201205 .no_sanitize_hwaddress,
12211206 .sanitize_address_dyninit,
1222 => try writer.print(" {s}", .{@tagName(attribute)}),
1207 => try bw.print(" {s}", .{@tagName(attribute)}),
12231208 .byval,
12241209 .byref,
12251210 .preallocated,
12261211 .inalloca,
12271212 .sret,
12281213 .elementtype,
1229 => |ty| try writer.print(" {s}({%})", .{ @tagName(attribute), ty.fmt(data.builder) }),
1230 .@"align" => |alignment| try writer.print("{ }", .{alignment}),
1214 => |ty| try bw.print(" {s}({f%})", .{ @tagName(attribute), ty.fmt(data.builder) }),
1215 .@"align" => |alignment| try bw.print("{f }", .{alignment}),
12311216 .dereferenceable,
12321217 .dereferenceable_or_null,
1233 => |size| try writer.print(" {s}({d})", .{ @tagName(attribute), size }),
1218 => |size| try bw.print(" {s}({d})", .{ @tagName(attribute), size }),
12341219 .nofpclass => |fpclass| {
12351220 const Int = @typeInfo(FpClass).@"struct".backing_integer.?;
1236 try writer.print(" {s}(", .{@tagName(attribute)});
1221 try bw.print(" {s}(", .{@tagName(attribute)});
12371222 var any = false;
12381223 var remaining: Int = @bitCast(fpclass);
12391224 inline for (@typeInfo(FpClass).@"struct".decls) |decl| {
12401225 const pattern: Int = @bitCast(@field(FpClass, decl.name));
12411226 if (remaining & pattern == pattern) {
12421227 if (!any) {
1243 try writer.writeByte(' ');
1228 try bw.writeByte(' ');
12441229 any = true;
12451230 }
1246 try writer.writeAll(decl.name);
1231 try bw.writeAll(decl.name);
12471232 remaining &= ~pattern;
12481233 }
12491234 }
1250 try writer.writeByte(')');
1235 try bw.writeByte(')');
12511236 },
1252 .alignstack => |alignment| try writer.print(
1237 .alignstack => |alignment| try bw.print(
12531238 if (comptime std.mem.indexOfScalar(u8, fmt_str, '#') != null)
12541239 " {s}={d}"
12551240 else
......@@ -1257,53 +1242,53 @@ pub const Attribute = union(Kind) {
12571242 .{ @tagName(attribute), alignment.toByteUnits() orelse return },
12581243 ),
12591244 .allockind => |allockind| {
1260 try writer.print(" {s}(\"", .{@tagName(attribute)});
1245 try bw.print(" {s}(\"", .{@tagName(attribute)});
12611246 var any = false;
12621247 inline for (@typeInfo(AllocKind).@"struct".fields) |field| {
12631248 if (comptime std.mem.eql(u8, field.name, "_")) continue;
12641249 if (@field(allockind, field.name)) {
12651250 if (!any) {
1266 try writer.writeByte(',');
1251 try bw.writeByte(',');
12671252 any = true;
12681253 }
1269 try writer.writeAll(field.name);
1254 try bw.writeAll(field.name);
12701255 }
12711256 }
1272 try writer.writeAll("\")");
1257 try bw.writeAll("\")");
12731258 },
12741259 .allocsize => |allocsize| {
1275 try writer.print(" {s}({d}", .{ @tagName(attribute), allocsize.elem_size });
1260 try bw.print(" {s}({d}", .{ @tagName(attribute), allocsize.elem_size });
12761261 if (allocsize.num_elems != AllocSize.none)
1277 try writer.print(",{d}", .{allocsize.num_elems});
1278 try writer.writeByte(')');
1262 try bw.print(",{d}", .{allocsize.num_elems});
1263 try bw.writeByte(')');
12791264 },
12801265 .memory => |memory| {
1281 try writer.print(" {s}(", .{@tagName(attribute)});
1266 try bw.print(" {s}(", .{@tagName(attribute)});
12821267 var any = memory.other != .none or
12831268 (memory.argmem == .none and memory.inaccessiblemem == .none);
1284 if (any) try writer.writeAll(@tagName(memory.other));
1269 if (any) try bw.writeAll(@tagName(memory.other));
12851270 inline for (.{ "argmem", "inaccessiblemem" }) |kind| {
12861271 if (@field(memory, kind) != memory.other) {
1287 if (any) try writer.writeAll(", ");
1288 try writer.print("{s}: {s}", .{ kind, @tagName(@field(memory, kind)) });
1272 if (any) try bw.writeAll(", ");
1273 try bw.print("{s}: {s}", .{ kind, @tagName(@field(memory, kind)) });
12891274 any = true;
12901275 }
12911276 }
1292 try writer.writeByte(')');
1277 try bw.writeByte(')');
12931278 },
12941279 .uwtable => |uwtable| if (uwtable != .none) {
1295 try writer.print(" {s}", .{@tagName(attribute)});
1296 if (uwtable != UwTable.default) try writer.print("({s})", .{@tagName(uwtable)});
1280 try bw.print(" {s}", .{@tagName(attribute)});
1281 if (uwtable != UwTable.default) try bw.print("({s})", .{@tagName(uwtable)});
12971282 },
1298 .vscale_range => |vscale_range| try writer.print(" {s}({d},{d})", .{
1283 .vscale_range => |vscale_range| try bw.print(" {s}({d},{d})", .{
12991284 @tagName(attribute),
13001285 vscale_range.min.toByteUnits().?,
13011286 vscale_range.max.toByteUnits() orelse 0,
13021287 }),
13031288 .string => |string_attr| if (comptime std.mem.indexOfScalar(u8, fmt_str, '"') != null) {
1304 try writer.print(" {\"}", .{string_attr.kind.fmt(data.builder)});
1289 try bw.print(" {f\"}", .{string_attr.kind.fmt(data.builder)});
13051290 if (string_attr.value != .empty)
1306 try writer.print("={\"}", .{string_attr.value.fmt(data.builder)});
1291 try bw.print("={f\"}", .{string_attr.value.fmt(data.builder)});
13071292 },
13081293 .none => unreachable,
13091294 }
......@@ -1583,16 +1568,11 @@ pub const Attributes = enum(u32) {
15831568 attributes: Attributes,
15841569 builder: *const Builder,
15851570 };
1586 fn format(
1587 data: FormatData,
1588 comptime fmt_str: []const u8,
1589 fmt_opts: std.fmt.FormatOptions,
1590 writer: anytype,
1591 ) @TypeOf(writer).Error!void {
1571 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
15921572 for (data.attributes.slice(data.builder)) |attribute_index| try Attribute.Index.format(.{
15931573 .attribute_index = attribute_index,
15941574 .builder = data.builder,
1595 }, fmt_str, fmt_opts, writer);
1575 }, bw, fmt_str);
15961576 }
15971577 pub fn fmt(self: Attributes, builder: *const Builder) std.fmt.Formatter(format) {
15981578 return .{ .data = .{ .attributes = self, .builder = builder } };
......@@ -1781,22 +1761,12 @@ pub const Linkage = enum(u4) {
17811761 extern_weak = 7,
17821762 external = 0,
17831763
1784 pub fn format(
1785 self: Linkage,
1786 comptime _: []const u8,
1787 _: std.fmt.FormatOptions,
1788 writer: anytype,
1789 ) @TypeOf(writer).Error!void {
1790 if (self != .external) try writer.print(" {s}", .{@tagName(self)});
1764 pub fn format(self: Linkage, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1765 if (self != .external) try bw.print(" {s}", .{@tagName(self)});
17911766 }
17921767
1793 fn formatOptional(
1794 data: ?Linkage,
1795 comptime _: []const u8,
1796 _: std.fmt.FormatOptions,
1797 writer: anytype,
1798 ) @TypeOf(writer).Error!void {
1799 if (data) |linkage| try writer.print(" {s}", .{@tagName(linkage)});
1768 fn formatOptional(data: ?Linkage, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1769 if (data) |linkage| try bw.print(" {s}", .{@tagName(linkage)});
18001770 }
18011771 pub fn fmtOptional(self: ?Linkage) std.fmt.Formatter(formatOptional) {
18021772 return .{ .data = self };
......@@ -1808,13 +1778,8 @@ pub const Preemption = enum {
18081778 dso_local,
18091779 implicit_dso_local,
18101780
1811 pub fn format(
1812 self: Preemption,
1813 comptime _: []const u8,
1814 _: std.fmt.FormatOptions,
1815 writer: anytype,
1816 ) @TypeOf(writer).Error!void {
1817 if (self == .dso_local) try writer.print(" {s}", .{@tagName(self)});
1781 pub fn format(self: Preemption, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1782 if (self == .dso_local) try bw.print(" {s}", .{@tagName(self)});
18181783 }
18191784};
18201785
......@@ -1833,10 +1798,10 @@ pub const Visibility = enum(u2) {
18331798
18341799 pub fn format(
18351800 self: Visibility,
1836 comptime _: []const u8,
1837 _: std.fmt.FormatOptions,
1801 comptime format_string: []const u8,
18381802 writer: anytype,
18391803 ) @TypeOf(writer).Error!void {
1804 comptime assert(format_string.len == 0);
18401805 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
18411806 }
18421807};
......@@ -1846,13 +1811,8 @@ pub const DllStorageClass = enum(u2) {
18461811 dllimport = 1,
18471812 dllexport = 2,
18481813
1849 pub fn format(
1850 self: DllStorageClass,
1851 comptime _: []const u8,
1852 _: std.fmt.FormatOptions,
1853 writer: anytype,
1854 ) @TypeOf(writer).Error!void {
1855 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
1814 pub fn format(self: DllStorageClass, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1815 if (self != .default) try bw.print(" {s}", .{@tagName(self)});
18561816 }
18571817};
18581818
......@@ -1863,15 +1823,10 @@ pub const ThreadLocal = enum(u3) {
18631823 initialexec = 3,
18641824 localexec = 4,
18651825
1866 pub fn format(
1867 self: ThreadLocal,
1868 comptime prefix: []const u8,
1869 _: std.fmt.FormatOptions,
1870 writer: anytype,
1871 ) @TypeOf(writer).Error!void {
1826 pub fn format(self: ThreadLocal, bw: *std.io.BufferedWriter, comptime prefix: []const u8) anyerror!void {
18721827 if (self == .default) return;
1873 try writer.print("{s}thread_local", .{prefix});
1874 if (self != .generaldynamic) try writer.print("({s})", .{@tagName(self)});
1828 try bw.print("{s}thread_local", .{prefix});
1829 if (self != .generaldynamic) try bw.print("({s})", .{@tagName(self)});
18751830 }
18761831};
18771832
......@@ -1882,13 +1837,8 @@ pub const UnnamedAddr = enum(u2) {
18821837 unnamed_addr = 1,
18831838 local_unnamed_addr = 2,
18841839
1885 pub fn format(
1886 self: UnnamedAddr,
1887 comptime _: []const u8,
1888 _: std.fmt.FormatOptions,
1889 writer: anytype,
1890 ) @TypeOf(writer).Error!void {
1891 if (self != .default) try writer.print(" {s}", .{@tagName(self)});
1840 pub fn format(self: UnnamedAddr, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1841 if (self != .default) try bw.print(" {s}", .{@tagName(self)});
18921842 }
18931843};
18941844
......@@ -1981,13 +1931,8 @@ pub const AddrSpace = enum(u24) {
19811931 pub const funcref: AddrSpace = @enumFromInt(20);
19821932 };
19831933
1984 pub fn format(
1985 self: AddrSpace,
1986 comptime prefix: []const u8,
1987 _: std.fmt.FormatOptions,
1988 writer: anytype,
1989 ) @TypeOf(writer).Error!void {
1990 if (self != .default) try writer.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) });
1934 pub fn format(self: AddrSpace, bw: *std.io.BufferedWriter, comptime prefix: []const u8) anyerror!void {
1935 if (self != .default) try bw.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) });
19911936 }
19921937};
19931938
......@@ -1995,15 +1940,8 @@ pub const ExternallyInitialized = enum {
19951940 default,
19961941 externally_initialized,
19971942
1998 pub fn format(
1999 self: ExternallyInitialized,
2000 comptime _: []const u8,
2001 _: std.fmt.FormatOptions,
2002 writer: anytype,
2003 ) @TypeOf(writer).Error!void {
2004 if (self == .default) return;
2005 try writer.writeByte(' ');
2006 try writer.writeAll(@tagName(self));
1943 pub fn format(self: ExternallyInitialized, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1944 if (self != .default) try bw.print(" {s}", .{@tagName(self)});
20071945 }
20081946};
20091947
......@@ -2026,13 +1964,8 @@ pub const Alignment = enum(u6) {
20261964 return if (self == .default) 0 else (@intFromEnum(self) + 1);
20271965 }
20281966
2029 pub fn format(
2030 self: Alignment,
2031 comptime prefix: []const u8,
2032 _: std.fmt.FormatOptions,
2033 writer: anytype,
2034 ) @TypeOf(writer).Error!void {
2035 try writer.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return });
1967 pub fn format(self: Alignment, bw: *std.io.BufferedWriter, comptime prefix: []const u8) anyerror!void {
1968 try bw.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return });
20361969 }
20371970};
20381971
......@@ -2105,12 +2038,7 @@ pub const CallConv = enum(u10) {
21052038
21062039 pub const default = CallConv.ccc;
21072040
2108 pub fn format(
2109 self: CallConv,
2110 comptime _: []const u8,
2111 _: std.fmt.FormatOptions,
2112 writer: anytype,
2113 ) @TypeOf(writer).Error!void {
2041 pub fn format(self: CallConv, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
21142042 switch (self) {
21152043 default => {},
21162044 .fastcc,
......@@ -2164,8 +2092,8 @@ pub const CallConv = enum(u10) {
21642092 .aarch64_sme_preservemost_from_x2,
21652093 .m68k_rtdcc,
21662094 .riscv_vectorcallcc,
2167 => try writer.print(" {s}", .{@tagName(self)}),
2168 _ => try writer.print(" cc{d}", .{@intFromEnum(self)}),
2095 => try bw.print(" {s}", .{@tagName(self)}),
2096 _ => try bw.print(" cc{d}", .{@intFromEnum(self)}),
21692097 }
21702098 }
21712099};
......@@ -2191,26 +2119,21 @@ pub const StrtabString = enum(u32) {
21912119 string: StrtabString,
21922120 builder: *const Builder,
21932121 };
2194 fn format(
2195 data: FormatData,
2196 comptime fmt_str: []const u8,
2197 _: std.fmt.FormatOptions,
2198 writer: anytype,
2199 ) @TypeOf(writer).Error!void {
2122 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
22002123 if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
22012124 @compileError("invalid format string: '" ++ fmt_str ++ "'");
22022125 assert(data.string != .none);
22032126 const string_slice = data.string.slice(data.builder) orelse
2204 return writer.print("{d}", .{@intFromEnum(data.string)});
2127 return bw.print("{d}", .{@intFromEnum(data.string)});
22052128 if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_|
2206 return writer.writeAll(string_slice);
2129 return bw.writeAll(string_slice);
22072130 try printEscapedString(
22082131 string_slice,
22092132 if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_|
22102133 .always_quote
22112134 else
22122135 .quote_unless_valid_identifier,
2213 writer,
2136 bw,
22142137 );
22152138 }
22162139 pub fn fmt(self: StrtabString, builder: *const Builder) std.fmt.Formatter(format) {
......@@ -2264,7 +2187,7 @@ pub fn strtabStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: a
22642187}
22652188
22662189pub fn strtabStringFmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) StrtabString {
2267 self.strtab_string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable;
2190 self.strtab_string_bytes.printAssumeCapacity(fmt_str, fmt_args);
22682191 return self.trailingStrtabStringAssumeCapacity();
22692192}
22702193
......@@ -2383,13 +2306,8 @@ pub const Global = struct {
23832306 global: Index,
23842307 builder: *const Builder,
23852308 };
2386 fn format(
2387 data: FormatData,
2388 comptime _: []const u8,
2389 _: std.fmt.FormatOptions,
2390 writer: anytype,
2391 ) @TypeOf(writer).Error!void {
2392 try writer.print("@{}", .{
2309 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
2310 try bw.print("@{f}", .{
23932311 data.global.unwrap(data.builder).name(data.builder).fmt(data.builder),
23942312 });
23952313 }
......@@ -4834,28 +4752,23 @@ pub const Function = struct {
48344752 function: Function.Index,
48354753 builder: *Builder,
48364754 };
4837 fn format(
4838 data: FormatData,
4839 comptime fmt_str: []const u8,
4840 _: std.fmt.FormatOptions,
4841 writer: anytype,
4842 ) @TypeOf(writer).Error!void {
4755 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
48434756 if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_|
48444757 @compileError("invalid format string: '" ++ fmt_str ++ "'");
48454758 if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) {
48464759 if (data.instruction == .none) return;
4847 try writer.writeByte(',');
4760 try bw.writeByte(',');
48484761 }
48494762 if (comptime std.mem.indexOfScalar(u8, fmt_str, ' ') != null) {
48504763 if (data.instruction == .none) return;
4851 try writer.writeByte(' ');
4764 try bw.writeByte(' ');
48524765 }
4853 if (comptime std.mem.indexOfScalar(u8, fmt_str, '%') != null) try writer.print(
4854 "{%} ",
4766 if (comptime std.mem.indexOfScalar(u8, fmt_str, '%') != null) try bw.print(
4767 "{f%} ",
48554768 .{data.instruction.typeOf(data.function, data.builder).fmt(data.builder)},
48564769 );
48574770 assert(data.instruction != .none);
4858 try writer.print("%{}", .{
4771 try bw.print("%{f}", .{
48594772 data.instruction.name(data.function.ptrConst(data.builder)).fmt(data.builder),
48604773 });
48614774 }
......@@ -6361,7 +6274,7 @@ pub const WipFunction = struct {
63616274
63626275 while (true) {
63636276 gop.value_ptr.* = @enumFromInt(@intFromEnum(gop.value_ptr.*) + 1);
6364 const unique_name = try wip_name.builder.fmt("{r}{s}{r}", .{
6277 const unique_name = try wip_name.builder.fmt("{fr}{s}{fr}", .{
63656278 name.fmt(wip_name.builder),
63666279 sep,
63676280 gop.value_ptr.fmt(wip_name.builder),
......@@ -7031,13 +6944,8 @@ pub const MemoryAccessKind = enum(u1) {
70316944 normal,
70326945 @"volatile",
70336946
7034 pub fn format(
7035 self: MemoryAccessKind,
7036 comptime prefix: []const u8,
7037 _: std.fmt.FormatOptions,
7038 writer: anytype,
7039 ) @TypeOf(writer).Error!void {
7040 if (self != .normal) try writer.print("{s}{s}", .{ prefix, @tagName(self) });
6947 pub fn format(self: MemoryAccessKind, bw: *std.io.BufferedWriter, comptime prefix: []const u8) anyerror!void {
6948 if (self != .normal) try bw.print("{s}{s}", .{ prefix, @tagName(self) });
70416949 }
70426950};
70436951
......@@ -7045,13 +6953,8 @@ pub const SyncScope = enum(u1) {
70456953 singlethread,
70466954 system,
70476955
7048 pub fn format(
7049 self: SyncScope,
7050 comptime prefix: []const u8,
7051 _: std.fmt.FormatOptions,
7052 writer: anytype,
7053 ) @TypeOf(writer).Error!void {
7054 if (self != .system) try writer.print(
6956 pub fn format(self: SyncScope, bw: *std.io.BufferedWriter, comptime prefix: []const u8) anyerror!void {
6957 if (self != .system) try bw.print(
70556958 \\{s}syncscope("{s}")
70566959 , .{ prefix, @tagName(self) });
70576960 }
......@@ -7066,13 +6969,8 @@ pub const AtomicOrdering = enum(u3) {
70666969 acq_rel = 5,
70676970 seq_cst = 6,
70686971
7069 pub fn format(
7070 self: AtomicOrdering,
7071 comptime prefix: []const u8,
7072 _: std.fmt.FormatOptions,
7073 writer: anytype,
7074 ) @TypeOf(writer).Error!void {
7075 if (self != .none) try writer.print("{s}{s}", .{ prefix, @tagName(self) });
6972 pub fn format(self: AtomicOrdering, bw: *std.io.BufferedWriter, comptime prefix: []const u8) anyerror!void {
6973 if (self != .none) try bw.print("{s}{s}", .{ prefix, @tagName(self) });
70766974 }
70776975};
70786976
......@@ -7487,26 +7385,21 @@ pub const Constant = enum(u32) {
74877385 constant: Constant,
74887386 builder: *Builder,
74897387 };
7490 fn format(
7491 data: FormatData,
7492 comptime fmt_str: []const u8,
7493 _: std.fmt.FormatOptions,
7494 writer: anytype,
7495 ) @TypeOf(writer).Error!void {
7388 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
74967389 if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_|
74977390 @compileError("invalid format string: '" ++ fmt_str ++ "'");
74987391 if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) {
74997392 if (data.constant == .no_init) return;
7500 try writer.writeByte(',');
7393 try bw.writeByte(',');
75017394 }
75027395 if (comptime std.mem.indexOfScalar(u8, fmt_str, ' ') != null) {
75037396 if (data.constant == .no_init) return;
7504 try writer.writeByte(' ');
7397 try bw.writeByte(' ');
75057398 }
75067399 if (comptime std.mem.indexOfScalar(u8, fmt_str, '%') != null)
7507 try writer.print("{%} ", .{data.constant.typeOf(data.builder).fmt(data.builder)});
7400 try bw.print("{f%} ", .{data.constant.typeOf(data.builder).fmt(data.builder)});
75087401 assert(data.constant != .no_init);
7509 if (std.enums.tagName(Constant, data.constant)) |name| return writer.writeAll(name);
7402 if (std.enums.tagName(Constant, data.constant)) |name| return bw.writeAll(name);
75107403 switch (data.constant.unwrap()) {
75117404 .constant => |constant| {
75127405 const item = data.builder.constant_items.get(constant);
......@@ -7545,11 +7438,11 @@ pub const Constant = enum(u32) {
75457438 const allocator = stack.get();
75467439 const str = try bigint.toStringAlloc(allocator, 10, undefined);
75477440 defer allocator.free(str);
7548 try writer.writeAll(str);
7441 try bw.writeAll(str);
75497442 },
75507443 .half,
75517444 .bfloat,
7552 => |tag| try writer.print("0x{c}{X:0>4}", .{ @as(u8, switch (tag) {
7445 => |tag| try bw.print("0x{c}{X:0>4}", .{ @as(u8, switch (tag) {
75537446 .half => 'H',
75547447 .bfloat => 'R',
75557448 else => unreachable,
......@@ -7580,7 +7473,7 @@ pub const Constant = enum(u32) {
75807473 ) + 1,
75817474 else => 0,
75827475 };
7583 try writer.print("0x{X:0>16}", .{@as(u64, @bitCast(Float.Repr(f64){
7476 try bw.print("0x{X:0>16}", .{@as(u64, @bitCast(Float.Repr(f64){
75847477 .mantissa = std.math.shl(
75857478 Mantissa64,
75867479 repr.mantissa,
......@@ -7602,13 +7495,13 @@ pub const Constant = enum(u32) {
76027495 },
76037496 .double => {
76047497 const extra = data.builder.constantExtraData(Double, item.data);
7605 try writer.print("0x{X:0>8}{X:0>8}", .{ extra.hi, extra.lo });
7498 try bw.print("0x{X:0>8}{X:0>8}", .{ extra.hi, extra.lo });
76067499 },
76077500 .fp128,
76087501 .ppc_fp128,
76097502 => |tag| {
76107503 const extra = data.builder.constantExtraData(Fp128, item.data);
7611 try writer.print("0x{c}{X:0>8}{X:0>8}{X:0>8}{X:0>8}", .{
7504 try bw.print("0x{c}{X:0>8}{X:0>8}{X:0>8}{X:0>8}", .{
76127505 @as(u8, switch (tag) {
76137506 .fp128 => 'L',
76147507 .ppc_fp128 => 'M',
......@@ -7622,7 +7515,7 @@ pub const Constant = enum(u32) {
76227515 },
76237516 .x86_fp80 => {
76247517 const extra = data.builder.constantExtraData(Fp80, item.data);
7625 try writer.print("0xK{X:0>4}{X:0>8}{X:0>8}", .{
7518 try bw.print("0xK{X:0>4}{X:0>8}{X:0>8}", .{
76267519 extra.hi, extra.lo_hi, extra.lo_lo,
76277520 });
76287521 },
......@@ -7631,7 +7524,7 @@ pub const Constant = enum(u32) {
76317524 .zeroinitializer,
76327525 .undef,
76337526 .poison,
7634 => |tag| try writer.writeAll(@tagName(tag)),
7527 => |tag| try bw.writeAll(@tagName(tag)),
76357528 .structure,
76367529 .packed_structure,
76377530 .array,
......@@ -7640,7 +7533,7 @@ pub const Constant = enum(u32) {
76407533 var extra = data.builder.constantExtraDataTrail(Aggregate, item.data);
76417534 const len: u32 = @intCast(extra.data.type.aggregateLen(data.builder));
76427535 const vals = extra.trail.next(len, Constant, data.builder);
7643 try writer.writeAll(switch (tag) {
7536 try bw.writeAll(switch (tag) {
76447537 .structure => "{ ",
76457538 .packed_structure => "<{ ",
76467539 .array => "[",
......@@ -7648,10 +7541,10 @@ pub const Constant = enum(u32) {
76487541 else => unreachable,
76497542 });
76507543 for (vals, 0..) |val, index| {
7651 if (index > 0) try writer.writeAll(", ");
7652 try writer.print("{%}", .{val.fmt(data.builder)});
7544 if (index > 0) try bw.writeAll(", ");
7545 try bw.print("{f%}", .{val.fmt(data.builder)});
76537546 }
7654 try writer.writeAll(switch (tag) {
7547 try bw.writeAll(switch (tag) {
76557548 .structure => " }",
76567549 .packed_structure => " }>",
76577550 .array => "]",
......@@ -7662,20 +7555,20 @@ pub const Constant = enum(u32) {
76627555 .splat => {
76637556 const extra = data.builder.constantExtraData(Splat, item.data);
76647557 const len = extra.type.vectorLen(data.builder);
7665 try writer.writeByte('<');
7558 try bw.writeByte('<');
76667559 for (0..len) |index| {
7667 if (index > 0) try writer.writeAll(", ");
7668 try writer.print("{%}", .{extra.value.fmt(data.builder)});
7560 if (index > 0) try bw.writeAll(", ");
7561 try bw.print("{f%}", .{extra.value.fmt(data.builder)});
76697562 }
7670 try writer.writeByte('>');
7563 try bw.writeByte('>');
76717564 },
7672 .string => try writer.print("c{\"}", .{
7565 .string => try bw.print("c{f\"}", .{
76737566 @as(String, @enumFromInt(item.data)).fmt(data.builder),
76747567 }),
76757568 .blockaddress => |tag| {
76767569 const extra = data.builder.constantExtraData(BlockAddress, item.data);
76777570 const function = extra.function.ptrConst(data.builder);
7678 try writer.print("{s}({}, {})", .{
7571 try bw.print("{s}({f}, {f})", .{
76797572 @tagName(tag),
76807573 function.global.fmt(data.builder),
76817574 extra.block.toInst(function).fmt(extra.function, data.builder),
......@@ -7685,7 +7578,7 @@ pub const Constant = enum(u32) {
76857578 .no_cfi,
76867579 => |tag| {
76877580 const function: Function.Index = @enumFromInt(item.data);
7688 try writer.print("{s} {}", .{
7581 try bw.print("{s} {f}", .{
76897582 @tagName(tag),
76907583 function.ptrConst(data.builder).global.fmt(data.builder),
76917584 });
......@@ -7697,7 +7590,7 @@ pub const Constant = enum(u32) {
76977590 .addrspacecast,
76987591 => |tag| {
76997592 const extra = data.builder.constantExtraData(Cast, item.data);
7700 try writer.print("{s} ({%} to {%})", .{
7593 try bw.print("{s} ({f%} to {f%})", .{
77017594 @tagName(tag),
77027595 extra.val.fmt(data.builder),
77037596 extra.type.fmt(data.builder),
......@@ -7709,13 +7602,13 @@ pub const Constant = enum(u32) {
77097602 var extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data);
77107603 const indices =
77117604 extra.trail.next(extra.data.info.indices_len, Constant, data.builder);
7712 try writer.print("{s} ({%}, {%}", .{
7605 try bw.print("{s} ({f%}, {f%}", .{
77137606 @tagName(tag),
77147607 extra.data.type.fmt(data.builder),
77157608 extra.data.base.fmt(data.builder),
77167609 });
7717 for (indices) |index| try writer.print(", {%}", .{index.fmt(data.builder)});
7718 try writer.writeByte(')');
7610 for (indices) |index| try bw.print(", {f%}", .{index.fmt(data.builder)});
7611 try bw.writeByte(')');
77197612 },
77207613 .add,
77217614 .@"add nsw",
......@@ -7727,7 +7620,7 @@ pub const Constant = enum(u32) {
77277620 .xor,
77287621 => |tag| {
77297622 const extra = data.builder.constantExtraData(Binary, item.data);
7730 try writer.print("{s} ({%}, {%})", .{
7623 try bw.print("{s} ({f%}, {f%})", .{
77317624 @tagName(tag),
77327625 extra.lhs.fmt(data.builder),
77337626 extra.rhs.fmt(data.builder),
......@@ -7751,7 +7644,7 @@ pub const Constant = enum(u32) {
77517644 .@"asm sideeffect alignstack inteldialect unwind",
77527645 => |tag| {
77537646 const extra = data.builder.constantExtraData(Assembly, item.data);
7754 try writer.print("{s} {\"}, {\"}", .{
7647 try bw.print("{s} {f\"}, {f\"}", .{
77557648 @tagName(tag),
77567649 extra.assembly.fmt(data.builder),
77577650 extra.constraints.fmt(data.builder),
......@@ -7759,7 +7652,7 @@ pub const Constant = enum(u32) {
77597652 },
77607653 }
77617654 },
7762 .global => |global| try writer.print("{}", .{global.fmt(data.builder)}),
7655 .global => |global| try bw.print("{f}", .{global.fmt(data.builder)}),
77637656 }
77647657 }
77657658 pub fn fmt(self: Constant, builder: *Builder) std.fmt.Formatter(format) {
......@@ -7819,22 +7712,17 @@ pub const Value = enum(u32) {
78197712 function: Function.Index,
78207713 builder: *Builder,
78217714 };
7822 fn format(
7823 data: FormatData,
7824 comptime fmt_str: []const u8,
7825 fmt_opts: std.fmt.FormatOptions,
7826 writer: anytype,
7827 ) @TypeOf(writer).Error!void {
7715 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
78287716 switch (data.value.unwrap()) {
78297717 .instruction => |instruction| try Function.Instruction.Index.format(.{
78307718 .instruction = instruction,
78317719 .function = data.function,
78327720 .builder = data.builder,
7833 }, fmt_str, fmt_opts, writer),
7721 }, bw, fmt_str),
78347722 .constant => |constant| try Constant.format(.{
78357723 .constant = constant,
78367724 .builder = data.builder,
7837 }, fmt_str, fmt_opts, writer),
7725 }, bw, fmt_str),
78387726 .metadata => unreachable,
78397727 }
78407728 }
......@@ -7869,13 +7757,8 @@ pub const MetadataString = enum(u32) {
78697757 metadata_string: MetadataString,
78707758 builder: *const Builder,
78717759 };
7872 fn format(
7873 data: FormatData,
7874 comptime _: []const u8,
7875 _: std.fmt.FormatOptions,
7876 writer: anytype,
7877 ) @TypeOf(writer).Error!void {
7878 try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, writer);
7760 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
7761 try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, bw);
78797762 }
78807763 fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Formatter(format) {
78817764 return .{ .data = .{ .metadata_string = self, .builder = builder } };
......@@ -8039,29 +7922,24 @@ pub const Metadata = enum(u32) {
80397922 AllCallsDescribed: bool = false,
80407923 Unused: u2 = 0,
80417924
8042 pub fn format(
8043 self: DIFlags,
8044 comptime _: []const u8,
8045 _: std.fmt.FormatOptions,
8046 writer: anytype,
8047 ) @TypeOf(writer).Error!void {
7925 pub fn format(self: DIFlags, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
80487926 var need_pipe = false;
80497927 inline for (@typeInfo(DIFlags).@"struct".fields) |field| {
80507928 switch (@typeInfo(field.type)) {
80517929 .bool => if (@field(self, field.name)) {
8052 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
8053 try writer.print("DIFlag{s}", .{field.name});
7930 if (need_pipe) try bw.writeAll(" | ") else need_pipe = true;
7931 try bw.print("DIFlag{s}", .{field.name});
80547932 },
80557933 .@"enum" => if (@field(self, field.name) != .Zero) {
8056 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
8057 try writer.print("DIFlag{s}", .{@tagName(@field(self, field.name))});
7934 if (need_pipe) try bw.writeAll(" | ") else need_pipe = true;
7935 try bw.print("DIFlag{s}", .{@tagName(@field(self, field.name))});
80587936 },
80597937 .int => assert(@field(self, field.name) == 0),
80607938 else => @compileError("bad field type: " ++ field.name ++ ": " ++
80617939 @typeName(field.type)),
80627940 }
80637941 }
8064 if (!need_pipe) try writer.writeByte('0');
7942 if (!need_pipe) try bw.writeByte('0');
80657943 }
80667944 };
80677945
......@@ -8101,29 +7979,24 @@ pub const Metadata = enum(u32) {
81017979 ObjCDirect: bool = false,
81027980 Unused: u20 = 0,
81037981
8104 pub fn format(
8105 self: DISPFlags,
8106 comptime _: []const u8,
8107 _: std.fmt.FormatOptions,
8108 writer: anytype,
8109 ) @TypeOf(writer).Error!void {
7982 pub fn format(self: DISPFlags, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
81107983 var need_pipe = false;
81117984 inline for (@typeInfo(DISPFlags).@"struct".fields) |field| {
81127985 switch (@typeInfo(field.type)) {
81137986 .bool => if (@field(self, field.name)) {
8114 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
8115 try writer.print("DISPFlag{s}", .{field.name});
7987 if (need_pipe) try bw.writeAll(" | ") else need_pipe = true;
7988 try bw.print("DISPFlag{s}", .{field.name});
81167989 },
81177990 .@"enum" => if (@field(self, field.name) != .Zero) {
8118 if (need_pipe) try writer.writeAll(" | ") else need_pipe = true;
8119 try writer.print("DISPFlag{s}", .{@tagName(@field(self, field.name))});
7991 if (need_pipe) try bw.writeAll(" | ") else need_pipe = true;
7992 try bw.print("DISPFlag{s}", .{@tagName(@field(self, field.name))});
81207993 },
81217994 .int => assert(@field(self, field.name) == 0),
81227995 else => @compileError("bad field type: " ++ field.name ++ ": " ++
81237996 @typeName(field.type)),
81247997 }
81257998 }
8126 if (!need_pipe) try writer.writeByte('0');
7999 if (!need_pipe) try bw.writeByte('0');
81278000 }
81288001 };
81298002
......@@ -8323,20 +8196,15 @@ pub const Metadata = enum(u32) {
83238196 };
83248197 };
83258198 };
8326 fn format(
8327 data: FormatData,
8328 comptime fmt_str: []const u8,
8329 fmt_opts: std.fmt.FormatOptions,
8330 writer: anytype,
8331 ) @TypeOf(writer).Error!void {
8199 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) anyerror!void {
83328200 if (data.node == .none) return;
83338201
83348202 const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S';
83358203 const recurse_fmt_str = if (is_specialized) fmt_str[1..] else fmt_str;
83368204
8337 if (data.formatter.need_comma) try writer.writeAll(", ");
8205 if (data.formatter.need_comma) try bw.writeAll(", ");
83388206 defer data.formatter.need_comma = true;
8339 try writer.writeAll(data.prefix);
8207 try bw.writeAll(data.prefix);
83408208
83418209 const builder = data.formatter.builder;
83428210 switch (data.node) {
......@@ -8351,48 +8219,44 @@ pub const Metadata = enum(u32) {
83518219 .expression => {
83528220 var extra = builder.metadataExtraDataTrail(Expression, item.data);
83538221 const elements = extra.trail.next(extra.data.elements_len, u32, builder);
8354 try writer.writeAll("!DIExpression(");
8222 try bw.writeAll("!DIExpression(");
83558223 for (elements) |element| try format(.{
83568224 .formatter = data.formatter,
83578225 .node = .{ .u64 = element },
8358 }, "%", fmt_opts, writer);
8359 try writer.writeByte(')');
8226 }, bw, "%");
8227 try bw.writeByte(')');
83608228 },
83618229 .constant => try Constant.format(.{
83628230 .constant = @enumFromInt(item.data),
83638231 .builder = builder,
8364 }, recurse_fmt_str, fmt_opts, writer),
8232 }, bw, recurse_fmt_str),
83658233 else => unreachable,
83668234 }
83678235 },
8368 .index => |node| try writer.print("!{d}", .{node}),
8236 .index => |node| try bw.print("!{d}", .{node}),
83698237 inline .local_value, .local_metadata => |node, tag| try Value.format(.{
83708238 .value = node.value,
83718239 .function = node.function,
83728240 .builder = builder,
8373 }, switch (tag) {
8241 }, bw, switch (tag) {
83748242 .local_value => recurse_fmt_str,
83758243 .local_metadata => "%",
83768244 else => unreachable,
8377 }, fmt_opts, writer),
8245 }),
83788246 inline .local_inline, .local_index => |node, tag| {
83798247 if (comptime std.mem.eql(u8, recurse_fmt_str, "%"))
8380 try writer.print("{%} ", .{Type.metadata.fmt(builder)});
8248 try bw.print("{f%} ", .{Type.metadata.fmt(builder)});
83818249 try format(.{
83828250 .formatter = data.formatter,
83838251 .node = @unionInit(FormatData.Node, @tagName(tag)["local_".len..], node),
8384 }, "%", fmt_opts, writer);
8252 }, bw, "%");
83858253 },
8386 .string => |node| try writer.print((if (is_specialized) "" else "!") ++ "{}", .{
8254 .string => |node| try bw.print((if (is_specialized) "" else "!") ++ "{f}", .{
83878255 node.fmt(builder),
83888256 }),
8389 inline .bool,
8390 .u32,
8391 .u64,
8392 .di_flags,
8393 .sp_flags,
8394 => |node| try writer.print("{}", .{node}),
8395 .raw => |node| try writer.writeAll(node),
8257 inline .bool, .u32, .u64 => |node| try bw.print("{}", .{node}),
8258 inline .di_flags, .sp_flags => |node| try bw.print("{f}", .{node}),
8259 .raw => |node| try bw.writeAll(node),
83968260 }
83978261 }
83988262 inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype) switch (@TypeOf(node)) {
......@@ -8506,8 +8370,8 @@ pub const Metadata = enum(u32) {
85068370 DIGlobalVariableExpression,
85078371 },
85088372 nodes: anytype,
8509 writer: anytype,
8510 ) !void {
8373 bw: *std.io.BufferedWriter,
8374 ) anyerror!void {
85118375 comptime var fmt_str: []const u8 = "";
85128376 const names = comptime std.meta.fieldNames(@TypeOf(nodes));
85138377 comptime var fields: [2 + names.len]std.builtin.Type.StructField = undefined;
......@@ -8523,7 +8387,7 @@ pub const Metadata = enum(u32) {
85238387 }
85248388 fmt_str = fmt_str ++ "(";
85258389 inline for (fields[2..], names) |*field, name| {
8526 fmt_str = fmt_str ++ "{[" ++ name ++ "]S}";
8390 fmt_str = fmt_str ++ "{[" ++ name ++ "]fS}";
85278391 field.* = .{
85288392 .name = name,
85298393 .type = std.fmt.Formatter(format),
......@@ -8546,7 +8410,7 @@ pub const Metadata = enum(u32) {
85468410 name ++ ": ",
85478411 @field(nodes, name),
85488412 );
8549 try writer.print(fmt_str, fmt_args);
8413 try bw.print(fmt_str, fmt_args);
85508414 }
85518415 };
85528416};
......@@ -8636,7 +8500,7 @@ pub fn init(options: Options) Allocator.Error!Builder {
86368500 inline for (.{ 0, 4 }) |addr_space_index| {
86378501 const addr_space: AddrSpace = @enumFromInt(addr_space_index);
86388502 assert(self.ptrTypeAssumeCapacity(addr_space) ==
8639 @field(Type, std.fmt.comptimePrint("ptr{ }", .{addr_space})));
8503 @field(Type, std.fmt.comptimePrint("ptr{f }", .{addr_space})));
86408504 }
86418505 }
86428506
......@@ -8759,16 +8623,17 @@ pub fn deinit(self: *Builder) void {
87598623 self.* = undefined;
87608624}
87618625
8762pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {
8626pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter {
87638627 self.module_asm.clearRetainingCapacity();
8764 return self.appendModuleAsm();
8628 return self.appendModuleAsm(aw);
87658629}
87668630
8767pub fn appendModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer {
8768 return self.module_asm.writer(self.gpa);
8631pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter {
8632 return aw.fromArrayList(self.gpa, &self.module_asm);
87698633}
87708634
8771pub fn finishModuleAsm(self: *Builder) Allocator.Error!void {
8635pub fn finishModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) Allocator.Error!void {
8636 self.module_asm = aw.toArrayList();
87728637 if (self.module_asm.getLastOrNull()) |last| if (last != '\n')
87738638 try self.module_asm.append(self.gpa, '\n');
87748639}
......@@ -8804,7 +8669,7 @@ pub fn fmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allo
88048669}
88058670
88068671pub fn fmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) String {
8807 self.string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable;
8672 self.string_bytes.printAssumeCapacity(fmt_str, fmt_args);
88088673 return self.trailingStringAssumeCapacity();
88098674}
88108675
......@@ -9076,9 +8941,13 @@ pub fn getIntrinsic(
90768941 const allocator = stack.get();
90778942
90788943 const name = name: {
9079 const writer = self.strtab_string_bytes.writer(self.gpa);
9080 try writer.print("llvm.{s}", .{@tagName(id)});
9081 for (overload) |ty| try writer.print(".{m}", .{ty.fmt(self)});
8944 {
8945 var aw: std.io.AllocatingWriter = undefined;
8946 const bw = aw.fromArrayList(self.gpa, &self.strtab_string_bytes);
8947 defer self.strtab_string_bytes = aw.toArrayList();
8948 bw.print("llvm.{s}", .{@tagName(id)}) catch |err| return @errorCast(err);
8949 for (overload) |ty| bw.print(".{fm}", .{ty.fmt(self)}) catch |err| return @errorCast(err);
8950 }
90828951 break :name try self.trailingStrtabString();
90838952 };
90848953 if (self.getGlobal(name)) |global| return global.ptrConst(self).kind.function;
......@@ -9494,108 +9363,78 @@ pub fn asmValue(
94949363
94959364pub fn dump(self: *Builder) void {
94969365 const stderr: std.fs.File = .stderr();
9497 self.print(stderr.writer().unbuffered()) catch {};
9366 self.printBuffered(stderr.writer()) catch {};
94989367}
94999368
9500pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool {
9369pub fn printToFile(self: *Builder, path: []const u8) bool {
95019370 var file = std.fs.cwd().createFile(path, .{}) catch |err| {
95029371 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
95039372 return false;
95049373 };
95059374 defer file.close();
9506 self.print(file.writer()) catch |err| {
9375 self.printBuffered(file.writer()) catch |err| {
95079376 log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) });
95089377 return false;
95099378 };
95109379 return true;
95119380}
95129381
9513pub fn print(self: *Builder, writer: *std.io.BufferedWriter) (@TypeOf(writer).Error || Allocator.Error)!void {
9514 var bw = std.io.bufferedWriter(writer);
9515 try self.printUnbuffered(bw.writer());
9382pub fn printBuffered(self: *Builder, writer: std.io.Writer) anyerror!void {
9383 var buffer: [4096]u8 = undefined;
9384 var bw = writer.buffered(&buffer);
9385 try self.print(&bw);
95169386 try bw.flush();
95179387}
95189388
9519fn WriterWithErrors(comptime BackingWriter: type, comptime ExtraErrors: type) type {
9520 return struct {
9521 backing_writer: BackingWriter,
9522
9523 pub const Error = BackingWriter.Error || ExtraErrors;
9524 pub const Writer = std.io.Writer(*const Self, Error, write);
9525
9526 const Self = @This();
9527
9528 pub fn writer(self: *const Self) Writer {
9529 return .{ .context = self };
9530 }
9531
9532 pub fn write(self: *const Self, bytes: []const u8) Error!usize {
9533 return self.backing_writer.write(bytes);
9534 }
9535 };
9536}
9537fn writerWithErrors(
9538 backing_writer: anytype,
9539 comptime ExtraErrors: type,
9540) WriterWithErrors(@TypeOf(backing_writer), ExtraErrors) {
9541 return .{ .backing_writer = backing_writer };
9542}
9543
9544pub fn printUnbuffered(
9545 self: *Builder,
9546 backing_writer: anytype,
9547) (@TypeOf(backing_writer).Error || Allocator.Error)!void {
9548 const writer_with_errors = writerWithErrors(backing_writer, Allocator.Error);
9549 const writer = writer_with_errors.writer();
9550
9389pub fn print(self: *Builder, bw: *std.io.BufferedWriter) anyerror!void {
95519390 var need_newline = false;
95529391 var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined };
95539392 defer metadata_formatter.map.deinit(self.gpa);
95549393
95559394 if (self.source_filename != .none or self.data_layout != .none or self.target_triple != .none) {
9556 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9557 if (self.source_filename != .none) try writer.print(
9395 if (need_newline) try bw.writeByte('\n') else need_newline = true;
9396 if (self.source_filename != .none) try bw.print(
95589397 \\; ModuleID = '{s}'
9559 \\source_filename = {"}
9398 \\source_filename = {f"}
95609399 \\
95619400 , .{ self.source_filename.slice(self).?, self.source_filename.fmt(self) });
9562 if (self.data_layout != .none) try writer.print(
9563 \\target datalayout = {"}
9401 if (self.data_layout != .none) try bw.print(
9402 \\target datalayout = {f"}
95649403 \\
95659404 , .{self.data_layout.fmt(self)});
9566 if (self.target_triple != .none) try writer.print(
9567 \\target triple = {"}
9405 if (self.target_triple != .none) try bw.print(
9406 \\target triple = {f"}
95689407 \\
95699408 , .{self.target_triple.fmt(self)});
95709409 }
95719410
95729411 if (self.module_asm.items.len > 0) {
9573 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9412 if (need_newline) try bw.writeByte('\n') else need_newline = true;
95749413 var line_it = std.mem.tokenizeScalar(u8, self.module_asm.items, '\n');
95759414 while (line_it.next()) |line| {
9576 try writer.writeAll("module asm ");
9577 try printEscapedString(line, .always_quote, writer);
9578 try writer.writeByte('\n');
9415 try bw.writeAll("module asm ");
9416 try printEscapedString(line, .always_quote, bw);
9417 try bw.writeByte('\n');
95799418 }
95809419 }
95819420
95829421 if (self.types.count() > 0) {
9583 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9584 for (self.types.keys(), self.types.values()) |id, ty| try writer.print(
9585 \\%{} = type {}
9422 if (need_newline) try bw.writeByte('\n') else need_newline = true;
9423 for (self.types.keys(), self.types.values()) |id, ty| try bw.print(
9424 \\%{f} = type {f}
95869425 \\
95879426 , .{ id.fmt(self), ty.fmt(self) });
95889427 }
95899428
95909429 if (self.variables.items.len > 0) {
9591 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9430 if (need_newline) try bw.writeByte('\n') else need_newline = true;
95929431 for (self.variables.items) |variable| {
95939432 if (variable.global.getReplacement(self) != .none) continue;
95949433 const global = variable.global.ptrConst(self);
95959434 metadata_formatter.need_comma = true;
95969435 defer metadata_formatter.need_comma = undefined;
9597 try writer.print(
9598 \\{} ={}{}{}{}{ }{}{ }{} {s} {%}{ }{, }{}
9436 try bw.print(
9437 \\{f} ={f}{f}{f}{f}{f }{f}{f }{f} {s} {f%}{f }{f, }{f}
95999438 \\
96009439 , .{
96019440 variable.global.fmt(self),
......@@ -9618,14 +9457,14 @@ pub fn printUnbuffered(
96189457 }
96199458
96209459 if (self.aliases.items.len > 0) {
9621 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9460 if (need_newline) try bw.writeByte('\n') else need_newline = true;
96229461 for (self.aliases.items) |alias| {
96239462 if (alias.global.getReplacement(self) != .none) continue;
96249463 const global = alias.global.ptrConst(self);
96259464 metadata_formatter.need_comma = true;
96269465 defer metadata_formatter.need_comma = undefined;
9627 try writer.print(
9628 \\{} ={}{}{}{}{ }{} alias {%}, {%}{}
9466 try bw.print(
9467 \\{f} ={f}{f}{f}{f}{f }{f} alias {f%}, {f%}{f}
96299468 \\
96309469 , .{
96319470 alias.global.fmt(self),
......@@ -9647,17 +9486,17 @@ pub fn printUnbuffered(
96479486
96489487 for (0.., self.functions.items) |function_i, function| {
96499488 if (function.global.getReplacement(self) != .none) continue;
9650 if (need_newline) try writer.writeByte('\n') else need_newline = true;
9489 if (need_newline) try bw.writeByte('\n') else need_newline = true;
96519490 const function_index: Function.Index = @enumFromInt(function_i);
96529491 const global = function.global.ptrConst(self);
96539492 const params_len = global.type.functionParameters(self).len;
96549493 const function_attributes = function.attributes.func(self);
9655 if (function_attributes != .none) try writer.print(
9656 \\; Function Attrs:{}
9494 if (function_attributes != .none) try bw.print(
9495 \\; Function Attrs:{f}
96579496 \\
96589497 , .{function_attributes.fmt(self)});
9659 try writer.print(
9660 \\{s}{}{}{}{}{}{"} {%} {}(
9498 try bw.print(
9499 \\{s}{f}{f}{f}{f}{f}{f"} {f%} {f}(
96619500 , .{
96629501 if (function.instructions.len > 0) "define" else "declare",
96639502 global.linkage,
......@@ -9670,40 +9509,40 @@ pub fn printUnbuffered(
96709509 function.global.fmt(self),
96719510 });
96729511 for (0..params_len) |arg| {
9673 if (arg > 0) try writer.writeAll(", ");
9674 try writer.print(
9675 \\{%}{"}
9512 if (arg > 0) try bw.writeAll(", ");
9513 try bw.print(
9514 \\{f%}{f"}
96769515 , .{
96779516 global.type.functionParameters(self)[arg].fmt(self),
96789517 function.attributes.param(arg, self).fmt(self),
96799518 });
96809519 if (function.instructions.len > 0)
9681 try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
9520 try bw.print(" {f}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
96829521 else
9683 try writer.print(" %{d}", .{arg});
9522 try bw.print(" %{d}", .{arg});
96849523 }
96859524 switch (global.type.functionKind(self)) {
96869525 .normal => {},
96879526 .vararg => {
9688 if (params_len > 0) try writer.writeAll(", ");
9689 try writer.writeAll("...");
9527 if (params_len > 0) try bw.writeAll(", ");
9528 try bw.writeAll("...");
96909529 },
96919530 }
9692 try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space });
9693 if (function_attributes != .none) try writer.print(" #{d}", .{
9531 try bw.print("){f}{f }", .{ global.unnamed_addr, global.addr_space });
9532 if (function_attributes != .none) try bw.print(" #{d}", .{
96949533 (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
96959534 });
96969535 {
96979536 metadata_formatter.need_comma = false;
96989537 defer metadata_formatter.need_comma = undefined;
9699 try writer.print("{ }{}", .{
9538 try bw.print("{f }{f}", .{
97009539 function.alignment,
97019540 try metadata_formatter.fmt(" !dbg ", global.dbg),
97029541 });
97039542 }
97049543 if (function.instructions.len > 0) {
97059544 var block_incoming_len: u32 = undefined;
9706 try writer.writeAll(" {\n");
9545 try bw.writeAll(" {\n");
97079546 var maybe_dbg_index: ?u32 = null;
97089547 for (params_len..function.instructions.len) |instruction_i| {
97099548 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
......@@ -9801,7 +9640,7 @@ pub fn printUnbuffered(
98019640 .xor,
98029641 => |tag| {
98039642 const extra = function.extraData(Function.Instruction.Binary, instruction.data);
9804 try writer.print(" %{} = {s} {%}, {}", .{
9643 try bw.print(" %{f} = {s} {f%}, {f}", .{
98059644 instruction_index.name(&function).fmt(self),
98069645 @tagName(tag),
98079646 extra.lhs.fmt(function_index, self),
......@@ -9823,7 +9662,7 @@ pub fn printUnbuffered(
98239662 .zext,
98249663 => |tag| {
98259664 const extra = function.extraData(Function.Instruction.Cast, instruction.data);
9826 try writer.print(" %{} = {s} {%} to {%}", .{
9665 try bw.print(" %{f} = {s} {f%} to {f%}", .{
98279666 instruction_index.name(&function).fmt(self),
98289667 @tagName(tag),
98299668 extra.val.fmt(function_index, self),
......@@ -9834,7 +9673,7 @@ pub fn printUnbuffered(
98349673 .@"alloca inalloca",
98359674 => |tag| {
98369675 const extra = function.extraData(Function.Instruction.Alloca, instruction.data);
9837 try writer.print(" %{} = {s} {%}{,%}{, }{, }", .{
9676 try bw.print(" %{f} = {s} {f%}{f,%}{f, }{f, }", .{
98389677 instruction_index.name(&function).fmt(self),
98399678 @tagName(tag),
98409679 extra.type.fmt(self),
......@@ -9850,7 +9689,7 @@ pub fn printUnbuffered(
98509689 .atomicrmw => |tag| {
98519690 const extra =
98529691 function.extraData(Function.Instruction.AtomicRmw, instruction.data);
9853 try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }", .{
9692 try bw.print(" %{f} = {s}{f } {s} {f%}, {f%}{f }{f }{f, }", .{
98549693 instruction_index.name(&function).fmt(self),
98559694 @tagName(tag),
98569695 extra.info.access_kind,
......@@ -9866,19 +9705,19 @@ pub fn printUnbuffered(
98669705 block_incoming_len = instruction.data;
98679706 const name = instruction_index.name(&function);
98689707 if (@intFromEnum(instruction_index) > params_len)
9869 try writer.writeByte('\n');
9870 try writer.print("{}:\n", .{name.fmt(self)});
9708 try bw.writeByte('\n');
9709 try bw.print("{f}:\n", .{name.fmt(self)});
98719710 continue;
98729711 },
98739712 .br => |tag| {
98749713 const target: Function.Block.Index = @enumFromInt(instruction.data);
9875 try writer.print(" {s} {%}", .{
9714 try bw.print(" {s} {f%}", .{
98769715 @tagName(tag), target.toInst(&function).fmt(function_index, self),
98779716 });
98789717 },
98799718 .br_cond => {
98809719 const extra = function.extraData(Function.Instruction.BrCond, instruction.data);
9881 try writer.print(" br {%}, {%}, {%}", .{
9720 try bw.print(" br {f%}, {f%}, {f%}", .{
98829721 extra.cond.fmt(function_index, self),
98839722 extra.then.toInst(&function).fmt(function_index, self),
98849723 extra.@"else".toInst(&function).fmt(function_index, self),
......@@ -9887,8 +9726,8 @@ pub fn printUnbuffered(
98879726 defer metadata_formatter.need_comma = undefined;
98889727 switch (extra.weights) {
98899728 .none => {},
9890 .unpredictable => try writer.writeAll("!unpredictable !{}"),
9891 _ => try writer.print("{}", .{
9729 .unpredictable => try bw.writeAll("!unpredictable !{}"),
9730 _ => try bw.print("{f}", .{
98929731 try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights)))),
98939732 }),
98949733 }
......@@ -9905,16 +9744,16 @@ pub fn printUnbuffered(
99059744 var extra =
99069745 function.extraDataTrail(Function.Instruction.Call, instruction.data);
99079746 const args = extra.trail.next(extra.data.args_len, Value, &function);
9908 try writer.writeAll(" ");
9747 try bw.writeAll(" ");
99099748 const ret_ty = extra.data.ty.functionReturn(self);
99109749 switch (ret_ty) {
99119750 .void => {},
9912 else => try writer.print("%{} = ", .{
9751 else => try bw.print("%{f} = ", .{
99139752 instruction_index.name(&function).fmt(self),
99149753 }),
99159754 .none => unreachable,
99169755 }
9917 try writer.print("{s}{}{}{} {%} {}(", .{
9756 try bw.print("{s}{f}{f}{f} {f%} {f}(", .{
99189757 @tagName(tag),
99199758 extra.data.info.call_conv,
99209759 extra.data.attributes.ret(self).fmt(self),
......@@ -9926,21 +9765,21 @@ pub fn printUnbuffered(
99269765 extra.data.callee.fmt(function_index, self),
99279766 });
99289767 for (0.., args) |arg_index, arg| {
9929 if (arg_index > 0) try writer.writeAll(", ");
9768 if (arg_index > 0) try bw.writeAll(", ");
99309769 metadata_formatter.need_comma = false;
99319770 defer metadata_formatter.need_comma = undefined;
9932 try writer.print("{%}{}{}", .{
9771 try bw.print("{f%}{f}{f}", .{
99339772 arg.typeOf(function_index, self).fmt(self),
99349773 extra.data.attributes.param(arg_index, self).fmt(self),
99359774 try metadata_formatter.fmtLocal(" ", arg, function_index),
99369775 });
99379776 }
9938 try writer.writeByte(')');
9777 try bw.writeByte(')');
99399778 if (extra.data.info.has_op_bundle_cold) {
9940 try writer.writeAll(" [ \"cold\"() ]");
9779 try bw.writeAll(" [ \"cold\"() ]");
99419780 }
99429781 const call_function_attributes = extra.data.attributes.func(self);
9943 if (call_function_attributes != .none) try writer.print(" #{d}", .{
9782 if (call_function_attributes != .none) try bw.print(" #{d}", .{
99449783 (try attribute_groups.getOrPutValue(
99459784 self.gpa,
99469785 call_function_attributes,
......@@ -9953,7 +9792,7 @@ pub fn printUnbuffered(
99539792 => |tag| {
99549793 const extra =
99559794 function.extraData(Function.Instruction.CmpXchg, instruction.data);
9956 try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }", .{
9795 try bw.print(" %{f} = {s}{f } {f%}, {f%}, {f%}{f }{f }{f }{f, }", .{
99579796 instruction_index.name(&function).fmt(self),
99589797 @tagName(tag),
99599798 extra.info.access_kind,
......@@ -9969,7 +9808,7 @@ pub fn printUnbuffered(
99699808 .extractelement => |tag| {
99709809 const extra =
99719810 function.extraData(Function.Instruction.ExtractElement, instruction.data);
9972 try writer.print(" %{} = {s} {%}, {%}", .{
9811 try bw.print(" %{f} = {s} {f%}, {f%}", .{
99739812 instruction_index.name(&function).fmt(self),
99749813 @tagName(tag),
99759814 extra.val.fmt(function_index, self),
......@@ -9982,16 +9821,16 @@ pub fn printUnbuffered(
99829821 instruction.data,
99839822 );
99849823 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
9985 try writer.print(" %{} = {s} {%}", .{
9824 try bw.print(" %{f} = {s} {f%}", .{
99869825 instruction_index.name(&function).fmt(self),
99879826 @tagName(tag),
99889827 extra.data.val.fmt(function_index, self),
99899828 });
9990 for (indices) |index| try writer.print(", {d}", .{index});
9829 for (indices) |index| try bw.print(", {d}", .{index});
99919830 },
99929831 .fence => |tag| {
99939832 const info: MemoryAccessInfo = @bitCast(instruction.data);
9994 try writer.print(" {s}{ }{ }", .{
9833 try bw.print(" {s}{f }{f }", .{
99959834 @tagName(tag),
99969835 info.sync_scope,
99979836 info.success_ordering,
......@@ -10001,7 +9840,7 @@ pub fn printUnbuffered(
100019840 .@"fneg fast",
100029841 => |tag| {
100039842 const val: Value = @enumFromInt(instruction.data);
10004 try writer.print(" %{} = {s} {%}", .{
9843 try bw.print(" %{f} = {s} {f%}", .{
100059844 instruction_index.name(&function).fmt(self),
100069845 @tagName(tag),
100079846 val.fmt(function_index, self),
......@@ -10015,13 +9854,13 @@ pub fn printUnbuffered(
100159854 instruction.data,
100169855 );
100179856 const indices = extra.trail.next(extra.data.indices_len, Value, &function);
10018 try writer.print(" %{} = {s} {%}, {%}", .{
9857 try bw.print(" %{f} = {s} {f%}, {f%}", .{
100199858 instruction_index.name(&function).fmt(self),
100209859 @tagName(tag),
100219860 extra.data.type.fmt(self),
100229861 extra.data.base.fmt(function_index, self),
100239862 });
10024 for (indices) |index| try writer.print(", {%}", .{
9863 for (indices) |index| try bw.print(", {f%}", .{
100259864 index.fmt(function_index, self),
100269865 });
100279866 },
......@@ -10030,22 +9869,22 @@ pub fn printUnbuffered(
100309869 function.extraDataTrail(Function.Instruction.IndirectBr, instruction.data);
100319870 const targets =
100329871 extra.trail.next(extra.data.targets_len, Function.Block.Index, &function);
10033 try writer.print(" {s} {%}, [", .{
9872 try bw.print(" {s} {f%}, [", .{
100349873 @tagName(tag),
100359874 extra.data.addr.fmt(function_index, self),
100369875 });
100379876 for (0.., targets) |target_index, target| {
10038 if (target_index > 0) try writer.writeAll(", ");
10039 try writer.print("{%}", .{
9877 if (target_index > 0) try bw.writeAll(", ");
9878 try bw.print("{f%}", .{
100409879 target.toInst(&function).fmt(function_index, self),
100419880 });
100429881 }
10043 try writer.writeByte(']');
9882 try bw.writeByte(']');
100449883 },
100459884 .insertelement => |tag| {
100469885 const extra =
100479886 function.extraData(Function.Instruction.InsertElement, instruction.data);
10048 try writer.print(" %{} = {s} {%}, {%}, {%}", .{
9887 try bw.print(" %{f} = {s} {f%}, {f%}, {f%}", .{
100499888 instruction_index.name(&function).fmt(self),
100509889 @tagName(tag),
100519890 extra.val.fmt(function_index, self),
......@@ -10057,19 +9896,19 @@ pub fn printUnbuffered(
100579896 var extra =
100589897 function.extraDataTrail(Function.Instruction.InsertValue, instruction.data);
100599898 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
10060 try writer.print(" %{} = {s} {%}, {%}", .{
9899 try bw.print(" %{f} = {s} {f%}, {f%}", .{
100619900 instruction_index.name(&function).fmt(self),
100629901 @tagName(tag),
100639902 extra.data.val.fmt(function_index, self),
100649903 extra.data.elem.fmt(function_index, self),
100659904 });
10066 for (indices) |index| try writer.print(", {d}", .{index});
9905 for (indices) |index| try bw.print(", {d}", .{index});
100679906 },
100689907 .load,
100699908 .@"load atomic",
100709909 => |tag| {
100719910 const extra = function.extraData(Function.Instruction.Load, instruction.data);
10072 try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }", .{
9911 try bw.print(" %{f} = {s}{f } {f%}, {f%}{f }{f }{f, }", .{
100739912 instruction_index.name(&function).fmt(self),
100749913 @tagName(tag),
100759914 extra.info.access_kind,
......@@ -10087,14 +9926,14 @@ pub fn printUnbuffered(
100879926 const vals = extra.trail.next(block_incoming_len, Value, &function);
100889927 const blocks =
100899928 extra.trail.next(block_incoming_len, Function.Block.Index, &function);
10090 try writer.print(" %{} = {s} {%} ", .{
9929 try bw.print(" %{f} = {s} {f%} ", .{
100919930 instruction_index.name(&function).fmt(self),
100929931 @tagName(tag),
100939932 vals[0].typeOf(function_index, self).fmt(self),
100949933 });
100959934 for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| {
10096 if (incoming_index > 0) try writer.writeAll(", ");
10097 try writer.print("[ {}, {} ]", .{
9935 if (incoming_index > 0) try bw.writeAll(", ");
9936 try bw.print("[ {f}, {f} ]", .{
100989937 incoming_val.fmt(function_index, self),
100999938 incoming_block.toInst(&function).fmt(function_index, self),
101009939 });
......@@ -10102,19 +9941,19 @@ pub fn printUnbuffered(
101029941 },
101039942 .ret => |tag| {
101049943 const val: Value = @enumFromInt(instruction.data);
10105 try writer.print(" {s} {%}", .{
9944 try bw.print(" {s} {f%}", .{
101069945 @tagName(tag),
101079946 val.fmt(function_index, self),
101089947 });
101099948 },
101109949 .@"ret void",
101119950 .@"unreachable",
10112 => |tag| try writer.print(" {s}", .{@tagName(tag)}),
9951 => |tag| try bw.print(" {s}", .{@tagName(tag)}),
101139952 .select,
101149953 .@"select fast",
101159954 => |tag| {
101169955 const extra = function.extraData(Function.Instruction.Select, instruction.data);
10117 try writer.print(" %{} = {s} {%}, {%}, {%}", .{
9956 try bw.print(" %{f} = {s} {f%}, {f%}, {f%}", .{
101189957 instruction_index.name(&function).fmt(self),
101199958 @tagName(tag),
101209959 extra.cond.fmt(function_index, self),
......@@ -10125,7 +9964,7 @@ pub fn printUnbuffered(
101259964 .shufflevector => |tag| {
101269965 const extra =
101279966 function.extraData(Function.Instruction.ShuffleVector, instruction.data);
10128 try writer.print(" %{} = {s} {%}, {%}, {%}", .{
9967 try bw.print(" %{f} = {s} {f%}, {f%}, {f%}", .{
101299968 instruction_index.name(&function).fmt(self),
101309969 @tagName(tag),
101319970 extra.lhs.fmt(function_index, self),
......@@ -10137,7 +9976,7 @@ pub fn printUnbuffered(
101379976 .@"store atomic",
101389977 => |tag| {
101399978 const extra = function.extraData(Function.Instruction.Store, instruction.data);
10140 try writer.print(" {s}{ } {%}, {%}{ }{ }{, }", .{
9979 try bw.print(" {s}{f } {f%}, {f%}{f }{f }{f, }", .{
101419980 @tagName(tag),
101429981 extra.info.access_kind,
101439982 extra.val.fmt(function_index, self),
......@@ -10153,32 +9992,32 @@ pub fn printUnbuffered(
101539992 const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
101549993 const blocks =
101559994 extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
10156 try writer.print(" {s} {%}, {%} [\n", .{
9995 try bw.print(" {s} {f%}, {f%} [\n", .{
101579996 @tagName(tag),
101589997 extra.data.val.fmt(function_index, self),
101599998 extra.data.default.toInst(&function).fmt(function_index, self),
101609999 });
10161 for (vals, blocks) |case_val, case_block| try writer.print(
10162 " {%}, {%}\n",
10000 for (vals, blocks) |case_val, case_block| try bw.print(
10001 " {f%}, {f%}\n",
1016310002 .{
1016410003 case_val.fmt(self),
1016510004 case_block.toInst(&function).fmt(function_index, self),
1016610005 },
1016710006 );
10168 try writer.writeAll(" ]");
10007 try bw.writeAll(" ]");
1016910008 metadata_formatter.need_comma = true;
1017010009 defer metadata_formatter.need_comma = undefined;
1017110010 switch (extra.data.weights) {
1017210011 .none => {},
10173 .unpredictable => try writer.writeAll("!unpredictable !{}"),
10174 _ => try writer.print("{}", .{
10012 .unpredictable => try bw.writeAll("!unpredictable !{}"),
10013 _ => try bw.print("{f}", .{
1017510014 try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights)))),
1017610015 }),
1017710016 }
1017810017 },
1017910018 .va_arg => |tag| {
1018010019 const extra = function.extraData(Function.Instruction.VaArg, instruction.data);
10181 try writer.print(" %{} = {s} {%}, {%}", .{
10020 try bw.print(" %{f} = {s} {f%}, {f%}", .{
1018210021 instruction_index.name(&function).fmt(self),
1018310022 @tagName(tag),
1018410023 extra.list.fmt(function_index, self),
......@@ -10188,45 +10027,45 @@ pub fn printUnbuffered(
1018810027 }
1018910028
1019010029 if (maybe_dbg_index) |dbg_index| {
10191 try writer.print(", !dbg !{}", .{dbg_index});
10030 try bw.print(", !dbg !{d}", .{dbg_index});
1019210031 }
10193 try writer.writeByte('\n');
10032 try bw.writeByte('\n');
1019410033 }
10195 try writer.writeByte('}');
10034 try bw.writeByte('}');
1019610035 }
10197 try writer.writeByte('\n');
10036 try bw.writeByte('\n');
1019810037 }
1019910038
1020010039 if (attribute_groups.count() > 0) {
10201 if (need_newline) try writer.writeByte('\n') else need_newline = true;
10040 if (need_newline) try bw.writeByte('\n') else need_newline = true;
1020210041 for (0.., attribute_groups.keys()) |attribute_group_index, attribute_group|
10203 try writer.print(
10204 \\attributes #{d} = {{{#"} }}
10042 try bw.print(
10043 \\attributes #{d} = {{{f#"} }}
1020510044 \\
1020610045 , .{ attribute_group_index, attribute_group.fmt(self) });
1020710046 }
1020810047
1020910048 if (self.metadata_named.count() > 0) {
10210 if (need_newline) try writer.writeByte('\n') else need_newline = true;
10049 if (need_newline) try bw.writeByte('\n') else need_newline = true;
1021110050 for (self.metadata_named.keys(), self.metadata_named.values()) |name, data| {
1021210051 const elements: []const Metadata =
1021310052 @ptrCast(self.metadata_extra.items[data.index..][0..data.len]);
10214 try writer.writeByte('!');
10215 try printEscapedString(name.slice(self), .quote_unless_valid_identifier, writer);
10216 try writer.writeAll(" = !{");
10053 try bw.writeByte('!');
10054 try printEscapedString(name.slice(self), .quote_unless_valid_identifier, bw);
10055 try bw.writeAll(" = !{");
1021710056 metadata_formatter.need_comma = false;
1021810057 defer metadata_formatter.need_comma = undefined;
10219 for (elements) |element| try writer.print("{}", .{try metadata_formatter.fmt("", element)});
10220 try writer.writeAll("}\n");
10058 for (elements) |element| try bw.print("{f}", .{try metadata_formatter.fmt("", element)});
10059 try bw.writeAll("}\n");
1022110060 }
1022210061 }
1022310062
1022410063 if (metadata_formatter.map.count() > 0) {
10225 if (need_newline) try writer.writeByte('\n') else need_newline = true;
10064 if (need_newline) try bw.writeByte('\n') else need_newline = true;
1022610065 var metadata_index: usize = 0;
1022710066 while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) {
1022810067 @setEvalBranchQuota(10_000);
10229 try writer.print("!{} = ", .{metadata_index});
10068 try bw.print("!{d} = ", .{metadata_index});
1023010069 metadata_formatter.need_comma = false;
1023110070 defer metadata_formatter.need_comma = undefined;
1023210071
......@@ -10239,7 +10078,7 @@ pub fn printUnbuffered(
1023910078 .scope = location.scope,
1024010079 .inlinedAt = location.inlined_at,
1024110080 .isImplicitCode = false,
10242 }, writer);
10081 }, bw);
1024310082 continue;
1024410083 },
1024510084 .metadata => |metadata| self.metadata_items.get(@intFromEnum(metadata)),
......@@ -10255,7 +10094,7 @@ pub fn printUnbuffered(
1025510094 .checksumkind = null,
1025610095 .checksum = null,
1025710096 .source = null,
10258 }, writer);
10097 }, bw);
1025910098 },
1026010099 .compile_unit,
1026110100 .@"compile_unit optimized",
......@@ -10286,7 +10125,7 @@ pub fn printUnbuffered(
1028610125 .rangesBaseAddress = null,
1028710126 .sysroot = null,
1028810127 .sdk = null,
10289 }, writer);
10128 }, bw);
1029010129 },
1029110130 .subprogram,
1029210131 .@"subprogram local",
......@@ -10320,7 +10159,7 @@ pub fn printUnbuffered(
1032010159 .thrownTypes = null,
1032110160 .annotations = null,
1032210161 .targetFuncName = null,
10323 }, writer);
10162 }, bw);
1032410163 },
1032510164 .lexical_block => {
1032610165 const extra = self.metadataExtraData(Metadata.LexicalBlock, metadata_item.data);
......@@ -10329,7 +10168,7 @@ pub fn printUnbuffered(
1032910168 .file = extra.file,
1033010169 .line = extra.line,
1033110170 .column = extra.column,
10332 }, writer);
10171 }, bw);
1033310172 },
1033410173 .location => {
1033510174 const extra = self.metadataExtraData(Metadata.Location, metadata_item.data);
......@@ -10339,7 +10178,7 @@ pub fn printUnbuffered(
1033910178 .scope = extra.scope,
1034010179 .inlinedAt = extra.inlined_at,
1034110180 .isImplicitCode = false,
10342 }, writer);
10181 }, bw);
1034310182 },
1034410183 .basic_bool_type,
1034510184 .basic_unsigned_type,
......@@ -10368,7 +10207,7 @@ pub fn printUnbuffered(
1036810207 else => unreachable,
1036910208 }),
1037010209 .flags = null,
10371 }, writer);
10210 }, bw);
1037210211 },
1037310212 .composite_struct_type,
1037410213 .composite_union_type,
......@@ -10413,7 +10252,7 @@ pub fn printUnbuffered(
1041310252 .allocated = null,
1041410253 .rank = null,
1041510254 .annotations = null,
10416 }, writer);
10255 }, bw);
1041710256 },
1041810257 .derived_pointer_type,
1041910258 .derived_member_type,
......@@ -10446,7 +10285,7 @@ pub fn printUnbuffered(
1044610285 .extraData = null,
1044710286 .dwarfAddressSpace = null,
1044810287 .annotations = null,
10449 }, writer);
10288 }, bw);
1045010289 },
1045110290 .subroutine_type => {
1045210291 const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data);
......@@ -10454,7 +10293,7 @@ pub fn printUnbuffered(
1045410293 .flags = null,
1045510294 .cc = null,
1045610295 .types = extra.types_tuple,
10457 }, writer);
10296 }, bw);
1045810297 },
1045910298 .enumerator_unsigned,
1046010299 .enumerator_signed_positive,
......@@ -10504,7 +10343,7 @@ pub fn printUnbuffered(
1050410343 => false,
1050510344 else => unreachable,
1050610345 },
10507 }, writer);
10346 }, bw);
1050810347 },
1050910348 .subrange => {
1051010349 const extra = self.metadataExtraData(Metadata.Subrange, metadata_item.data);
......@@ -10513,31 +10352,31 @@ pub fn printUnbuffered(
1051310352 .lowerBound = extra.lower_bound,
1051410353 .upperBound = null,
1051510354 .stride = null,
10516 }, writer);
10355 }, bw);
1051710356 },
1051810357 .tuple => {
1051910358 var extra = self.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data);
1052010359 const elements = extra.trail.next(extra.data.elements_len, Metadata, self);
10521 try writer.writeAll("!{");
10522 for (elements) |element| try writer.print("{[element]%}", .{
10360 try bw.writeAll("!{");
10361 for (elements) |element| try bw.print("{[element]f%}", .{
1052310362 .element = try metadata_formatter.fmt("", element),
1052410363 });
10525 try writer.writeAll("}\n");
10364 try bw.writeAll("}\n");
1052610365 },
1052710366 .str_tuple => {
1052810367 var extra = self.metadataExtraDataTrail(Metadata.StrTuple, metadata_item.data);
1052910368 const elements = extra.trail.next(extra.data.elements_len, Metadata, self);
10530 try writer.print("!{{{[str]%}", .{
10369 try bw.print("!{{{[str]f%}", .{
1053110370 .str = try metadata_formatter.fmt("", extra.data.str),
1053210371 });
10533 for (elements) |element| try writer.print("{[element]%}", .{
10372 for (elements) |element| try bw.print("{[element]f%}", .{
1053410373 .element = try metadata_formatter.fmt("", element),
1053510374 });
10536 try writer.writeAll("}\n");
10375 try bw.writeAll("}\n");
1053710376 },
1053810377 .module_flag => {
1053910378 const extra = self.metadataExtraData(Metadata.ModuleFlag, metadata_item.data);
10540 try writer.print("!{{{[behavior]%}{[name]%}{[constant]%}}}\n", .{
10379 try bw.print("!{{{[behavior]f%}{[name]f%}{[constant]f%}}}\n", .{
1054110380 .behavior = try metadata_formatter.fmt("", extra.behavior),
1054210381 .name = try metadata_formatter.fmt("", extra.name),
1054310382 .constant = try metadata_formatter.fmt("", extra.constant),
......@@ -10555,7 +10394,7 @@ pub fn printUnbuffered(
1055510394 .flags = null,
1055610395 .@"align" = null,
1055710396 .annotations = null,
10558 }, writer);
10397 }, bw);
1055910398 },
1056010399 .parameter => {
1056110400 const extra = self.metadataExtraData(Metadata.Parameter, metadata_item.data);
......@@ -10569,7 +10408,7 @@ pub fn printUnbuffered(
1056910408 .flags = null,
1057010409 .@"align" = null,
1057110410 .annotations = null,
10572 }, writer);
10411 }, bw);
1057310412 },
1057410413 .global_var,
1057510414 .@"global_var local",
......@@ -10592,7 +10431,7 @@ pub fn printUnbuffered(
1059210431 .templateParams = null,
1059310432 .@"align" = null,
1059410433 .annotations = null,
10595 }, writer);
10434 }, bw);
1059610435 },
1059710436 .global_var_expression => {
1059810437 const extra =
......@@ -10600,7 +10439,7 @@ pub fn printUnbuffered(
1060010439 try metadata_formatter.specialized(.@"!", .DIGlobalVariableExpression, .{
1060110440 .@"var" = extra.variable,
1060210441 .expr = extra.expression,
10603 }, writer);
10442 }, bw);
1060410443 },
1060510444 }
1060610445 }
......@@ -10619,22 +10458,18 @@ fn isValidIdentifier(id: []const u8) bool {
1061910458}
1062010459
1062110460const QuoteBehavior = enum { always_quote, quote_unless_valid_identifier };
10622fn printEscapedString(
10623 slice: []const u8,
10624 quotes: QuoteBehavior,
10625 writer: anytype,
10626) @TypeOf(writer).Error!void {
10461fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *std.io.BufferedWriter) anyerror!void {
1062710462 const need_quotes = switch (quotes) {
1062810463 .always_quote => true,
1062910464 .quote_unless_valid_identifier => !isValidIdentifier(slice),
1063010465 };
10631 if (need_quotes) try writer.writeByte('"');
10466 if (need_quotes) try bw.writeByte('"');
1063210467 for (slice) |byte| switch (byte) {
10633 '\\' => try writer.writeAll("\\\\"),
10634 ' '...'"' - 1, '"' + 1...'\\' - 1, '\\' + 1...'~' => try writer.writeByte(byte),
10635 else => try writer.print("\\{X:0>2}", .{byte}),
10468 '\\' => try bw.writeAll("\\\\"),
10469 ' '...'"' - 1, '"' + 1...'\\' - 1, '\\' + 1...'~' => try bw.writeByte(byte),
10470 else => try bw.print("\\{X:0>2}", .{byte}),
1063610471 };
10637 if (need_quotes) try writer.writeByte('"');
10472 if (need_quotes) try bw.writeByte('"');
1063810473}
1063910474
1064010475fn ensureUnusedGlobalCapacity(self: *Builder, name: StrtabString) Allocator.Error!void {
......@@ -12019,7 +11854,7 @@ pub fn metadataStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args:
1201911854}
1202011855
1202111856pub fn metadataStringFmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) MetadataString {
12022 self.metadata_string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable;
11857 self.metadata_string_bytes.printAssumeCapacity(fmt_str, fmt_args);
1202311858 return self.trailingMetadataStringAssumeCapacity();
1202411859}
1202511860
lib/std/zig/render.zig+23-13
......@@ -77,7 +77,7 @@ const Render = struct {
7777
7878pub fn renderTree(gpa: Allocator, bw: *std.io.BufferedWriter, tree: Ast, fixups: Fixups) anyerror!void {
7979 assert(tree.errors.len == 0); // Cannot render an invalid tree.
80 var auto_indenting_stream: AutoIndentingStream = .init(bw, indent_delta);
80 var auto_indenting_stream: AutoIndentingStream = .init(gpa, bw, indent_delta);
8181 defer auto_indenting_stream.deinit();
8282 var r: Render = .{
8383 .gpa = gpa,
......@@ -2135,13 +2135,13 @@ fn renderArrayInit(
21352135 const section_exprs = row_exprs[0..section_end];
21362136
21372137 var sub_expr_buffer: std.io.AllocatingWriter = undefined;
2138 const sub_expr_buffer_writer = sub_expr_buffer.init(gpa);
2138 sub_expr_buffer.init(gpa);
21392139 defer sub_expr_buffer.deinit();
21402140
21412141 const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1);
21422142 defer gpa.free(sub_expr_buffer_starts);
21432143
2144 var auto_indenting_stream: AutoIndentingStream = .init(sub_expr_buffer_writer, indent_delta);
2144 var auto_indenting_stream: AutoIndentingStream = .init(gpa, &sub_expr_buffer.buffered_writer, indent_delta);
21452145 defer auto_indenting_stream.deinit();
21462146 var sub_render: Render = .{
21472147 .gpa = r.gpa,
......@@ -2160,8 +2160,9 @@ fn renderArrayInit(
21602160
21612161 if (i + 1 < section_exprs.len) {
21622162 try renderExpression(&sub_render, expr, .none);
2163 const width = sub_expr_buffer.getWritten().len - start;
2164 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.getWritten()[start..], '\n') != null;
2163 const written = sub_expr_buffer.getWritten();
2164 const width = written.len - start;
2165 const this_contains_newline = mem.indexOfScalar(u8, written[start..], '\n') != null;
21652166 contains_newline = contains_newline or this_contains_newline;
21662167 expr_widths[i] = width;
21672168 expr_newlines[i] = this_contains_newline;
......@@ -2183,8 +2184,9 @@ fn renderArrayInit(
21832184 try renderExpression(&sub_render, expr, .comma);
21842185 ais.popSpace();
21852186
2186 const width = sub_expr_buffer.items.len - start - 2;
2187 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.getWritten()[start .. sub_expr_buffer.items.len - 1], '\n') != null;
2187 const written = sub_expr_buffer.getWritten();
2188 const width = written.len - start - 2;
2189 const this_contains_newline = mem.indexOfScalar(u8, written[start .. written.len - 1], '\n') != null;
21882190 contains_newline = contains_newline or this_contains_newline;
21892191 expr_widths[i] = width;
21902192 expr_newlines[i] = contains_newline;
......@@ -2682,7 +2684,7 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space:
26822684 const tree = r.tree;
26832685 const ais = r.ais;
26842686 const lexeme = tokenSliceForRender(tree, token_index);
2685 try ais.writer().writeAll(lexeme);
2687 try ais.writeAll(lexeme);
26862688 ais.enableSpaceMode(override_space);
26872689 defer ais.disableSpaceMode();
26882690 try renderSpace(r, token_index, lexeme.len, space);
......@@ -3259,6 +3261,14 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi
32593261const AutoIndentingStream = struct {
32603262 underlying_writer: *std.io.BufferedWriter,
32613263
3264 /// Offset into the source at which formatting has been disabled with
3265 /// a `zig fmt: off` comment.
3266 ///
3267 /// If non-null, the AutoIndentingStream will not write any bytes
3268 /// to the underlying writer. It will however continue to track the
3269 /// indentation level.
3270 disabled_offset: ?usize = null,
3271
32623272 indent_count: usize = 0,
32633273 indent_delta: usize,
32643274 indent_stack: std.ArrayList(StackElem),
......@@ -3284,12 +3294,12 @@ const AutoIndentingStream = struct {
32843294 indent_count: usize,
32853295 };
32863296
3287 pub fn init(buffer: *std.ArrayList(u8), indent_delta_: usize) AutoIndentingStream {
3297 pub fn init(gpa: Allocator, bw: *std.io.BufferedWriter, indent_delta_: usize) AutoIndentingStream {
32883298 return .{
3289 .underlying_writer = buffer.writer(),
3299 .underlying_writer = bw,
32903300 .indent_delta = indent_delta_,
3291 .indent_stack = std.ArrayList(StackElem).init(buffer.allocator),
3292 .space_stack = std.ArrayList(SpaceElem).init(buffer.allocator),
3301 .indent_stack = .init(gpa),
3302 .space_stack = .init(gpa),
32933303 };
32943304 }
32953305
......@@ -3477,7 +3487,7 @@ const AutoIndentingStream = struct {
34773487 const current_indent = ais.currentIndent();
34783488 if (ais.current_line_empty and current_indent > 0) {
34793489 if (ais.disabled_offset == null) {
3480 try ais.underlying_writer.writeByteNTimes(' ', current_indent);
3490 try ais.underlying_writer.splatByteAll(' ', current_indent);
34813491 }
34823492 ais.applied_indent = current_indent;
34833493 }
lib/std/zig/string_literal.zig+16-22
......@@ -44,50 +44,44 @@ pub const Error = union(enum) {
4444 raw_string: []const u8,
4545 };
4646
47 fn formatMessage(
48 self: FormatMessage,
49 comptime f: []const u8,
50 options: std.fmt.FormatOptions,
51 writer: anytype,
52 ) !void {
47 fn formatMessage(self: FormatMessage, bw: *std.io.BufferedWriter, comptime f: []const u8) anyerror!void {
5348 _ = f;
54 _ = options;
5549 switch (self.err) {
56 .invalid_escape_character => |bad_index| try writer.print(
50 .invalid_escape_character => |bad_index| try bw.print(
5751 "invalid escape character: '{c}'",
5852 .{self.raw_string[bad_index]},
5953 ),
60 .expected_hex_digit => |bad_index| try writer.print(
54 .expected_hex_digit => |bad_index| try bw.print(
6155 "expected hex digit, found '{c}'",
6256 .{self.raw_string[bad_index]},
6357 ),
64 .empty_unicode_escape_sequence => try writer.writeAll(
58 .empty_unicode_escape_sequence => try bw.writeAll(
6559 "empty unicode escape sequence",
6660 ),
67 .expected_hex_digit_or_rbrace => |bad_index| try writer.print(
61 .expected_hex_digit_or_rbrace => |bad_index| try bw.print(
6862 "expected hex digit or '}}', found '{c}'",
6963 .{self.raw_string[bad_index]},
7064 ),
71 .invalid_unicode_codepoint => try writer.writeAll(
65 .invalid_unicode_codepoint => try bw.writeAll(
7266 "unicode escape does not correspond to a valid unicode scalar value",
7367 ),
74 .expected_lbrace => |bad_index| try writer.print(
68 .expected_lbrace => |bad_index| try bw.print(
7569 "expected '{{', found '{c}'",
7670 .{self.raw_string[bad_index]},
7771 ),
78 .expected_rbrace => |bad_index| try writer.print(
72 .expected_rbrace => |bad_index| try bw.print(
7973 "expected '}}', found '{c}'",
8074 .{self.raw_string[bad_index]},
8175 ),
82 .expected_single_quote => |bad_index| try writer.print(
76 .expected_single_quote => |bad_index| try bw.print(
8377 "expected single quote ('), found '{c}'",
8478 .{self.raw_string[bad_index]},
8579 ),
86 .invalid_character => |bad_index| try writer.print(
80 .invalid_character => |bad_index| try bw.print(
8781 "invalid byte in string or character literal: '{c}'",
8882 .{self.raw_string[bad_index]},
8983 ),
90 .empty_char_literal => try writer.writeAll(
84 .empty_char_literal => try bw.writeAll(
9185 "empty character literal",
9286 ),
9387 }
......@@ -363,13 +357,13 @@ pub fn parseWrite(writer: *std.io.BufferedWriter, bytes: []const u8) anyerror!Re
363357/// Higher level API. Does not return extra info about parse errors.
364358/// Caller owns returned memory.
365359pub fn parseAlloc(allocator: std.mem.Allocator, bytes: []const u8) ParseError![]u8 {
366 var buf: std.io.AllocatingWriter = undefined;
367 const bw = buf.init(allocator);
368 defer buf.deinit();
360 var aw: std.io.AllocatingWriter = undefined;
361 aw.init(allocator);
362 defer aw.deinit();
369363 // TODO try @errorCast(...)
370 const result = parseWrite(bw, bytes) catch |err| return @errorCast(err);
364 const result = parseWrite(&aw.buffered_writer, bytes) catch |err| return @errorCast(err);
371365 switch (result) {
372 .success => return buf.toOwnedSlice(),
366 .success => return aw.toOwnedSlice(),
373367 .failure => return error.InvalidLiteral,
374368 }
375369}
lib/std/zon/stringify.zig+5-5
......@@ -583,7 +583,7 @@ pub const Serializer = struct {
583583
584584 /// Serialize an integer.
585585 pub fn int(self: *Serializer, val: anytype) anyerror!void {
586 try std.fmt.formatInt(val, 10, .lower, .{}, self.writer);
586 try self.writer.printIntOptions(val, 10, .lower, .{});
587587 }
588588
589589 /// Serialize a float.
......@@ -613,7 +613,7 @@ pub const Serializer = struct {
613613 ///
614614 /// Escapes the identifier if necessary.
615615 pub fn ident(self: *Serializer, name: []const u8) anyerror!void {
616 try self.writer.print(".{p_}", .{std.zig.fmtId(name)});
616 try self.writer.print(".{fp_}", .{std.zig.fmtId(name)});
617617 }
618618
619619 /// Serialize `val` as a Unicode codepoint.
......@@ -626,7 +626,7 @@ pub const Serializer = struct {
626626 var buf: [8]u8 = undefined;
627627 const len = std.unicode.utf8Encode(val, &buf) catch return error.InvalidCodepoint;
628628 const str = buf[0..len];
629 try std.fmt.format(self.writer, "'{'}'", .{std.zig.fmtEscapes(str)});
629 try std.fmt.format(self.writer, "'{f'}'", .{std.zig.fmtEscapes(str)});
630630 }
631631
632632 /// Like `value`, but always serializes `val` as a tuple.
......@@ -684,7 +684,7 @@ pub const Serializer = struct {
684684
685685 /// Like `value`, but always serializes `val` as a string.
686686 pub fn string(self: *Serializer, val: []const u8) anyerror!void {
687 try std.fmt.format(self.writer, "\"{}\"", .{std.zig.fmtEscapes(val)});
687 try std.fmt.format(self.writer, "\"{f}\"", .{std.zig.fmtEscapes(val)});
688688 }
689689
690690 /// Options for formatting multiline strings.
......@@ -758,7 +758,7 @@ pub const Serializer = struct {
758758
759759 fn indent(self: *Serializer) anyerror!void {
760760 if (self.options.whitespace) {
761 try self.writer.writeByteNTimes(' ', 4 * self.indent_level);
761 try self.writer.splatByteAll(' ', 4 * self.indent_level);
762762 }
763763 }
764764
src/Air.zig+4-9
......@@ -957,18 +957,13 @@ pub const Inst = struct {
957957 return index.unwrap().target;
958958 }
959959
960 pub fn format(
961 index: Index,
962 comptime _: []const u8,
963 _: std.fmt.Options,
964 writer: *std.io.BufferedWriter,
965 ) anyerror!void {
966 try writer.writeByte('%');
960 pub fn format(index: Index, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
961 try bw.writeByte('%');
967962 switch (index.unwrap()) {
968963 .ref => {},
969 .target => try writer.writeByte('t'),
964 .target => try bw.writeByte('t'),
970965 }
971 try writer.print("{d}", .{@as(u31, @truncate(@intFromEnum(index)))});
966 try bw.print("{d}", .{@as(u31, @truncate(@intFromEnum(index)))});
972967 }
973968 };
974969
src/Air/Liveness.zig+25-25
......@@ -1323,7 +1323,7 @@ fn analyzeOperands(
13231323 const mask = @as(Bpi, 1) << @as(OperandInt, @intCast(i));
13241324
13251325 if ((try data.live_set.fetchPut(gpa, operand, {})) == null) {
1326 log.debug("[{}] %{}: added %{} to live set (operand dies here)", .{ pass, @intFromEnum(inst), operand });
1326 log.debug("[{}] %{}: added %{f} to live set (operand dies here)", .{ pass, @intFromEnum(inst), operand });
13271327 tomb_bits |= mask;
13281328 }
13291329 }
......@@ -1462,19 +1462,19 @@ fn analyzeInstBlock(
14621462 },
14631463
14641464 .main_analysis => {
1465 log.debug("[{}] %{}: block live set is {}", .{ pass, inst, fmtInstSet(&data.live_set) });
1465 log.debug("[{}] %{f}: block live set is {f}", .{ pass, inst, fmtInstSet(&data.live_set) });
14661466 // We can move the live set because the body should have a noreturn
14671467 // instruction which overrides the set.
14681468 try data.block_scopes.put(gpa, inst, .{
14691469 .live_set = data.live_set.move(),
14701470 });
14711471 defer {
1472 log.debug("[{}] %{}: popped block scope", .{ pass, inst });
1472 log.debug("[{}] %{f}: popped block scope", .{ pass, inst });
14731473 var scope = data.block_scopes.fetchRemove(inst).?.value;
14741474 scope.live_set.deinit(gpa);
14751475 }
14761476
1477 log.debug("[{}] %{}: pushed new block scope", .{ pass, inst });
1477 log.debug("[{}] %{f}: pushed new block scope", .{ pass, inst });
14781478 try analyzeBody(a, pass, data, body);
14791479
14801480 // If the block is noreturn, block deaths not only aren't useful, they're impossible to
......@@ -1501,7 +1501,7 @@ fn analyzeInstBlock(
15011501 }
15021502 assert(measured_num == num_deaths); // post-live-set should be a subset of pre-live-set
15031503 try a.special.put(gpa, inst, extra_index);
1504 log.debug("[{}] %{}: block deaths are {}", .{
1504 log.debug("[{}] %{f}: block deaths are {f}", .{
15051505 pass,
15061506 inst,
15071507 fmtInstList(@ptrCast(a.extra.items[extra_index + 1 ..][0..num_deaths])),
......@@ -1538,7 +1538,7 @@ fn writeLoopInfo(
15381538 const block_inst = key.*;
15391539 a.extra.appendAssumeCapacity(@intFromEnum(block_inst));
15401540 }
1541 log.debug("[{}] %{}: includes breaks to {}", .{ LivenessPass.loop_analysis, inst, fmtInstSet(&data.breaks) });
1541 log.debug("[{}] %{f}: includes breaks to {f}", .{ LivenessPass.loop_analysis, inst, fmtInstSet(&data.breaks) });
15421542
15431543 // Now we put the live operands from the loop body in too
15441544 const num_live = data.live_set.count();
......@@ -1550,7 +1550,7 @@ fn writeLoopInfo(
15501550 const alive = key.*;
15511551 a.extra.appendAssumeCapacity(@intFromEnum(alive));
15521552 }
1553 log.debug("[{}] %{}: maintain liveness of {}", .{ LivenessPass.loop_analysis, inst, fmtInstSet(&data.live_set) });
1553 log.debug("[{}] %{f}: maintain liveness of {f}", .{ LivenessPass.loop_analysis, inst, fmtInstSet(&data.live_set) });
15541554
15551555 try a.special.put(gpa, inst, extra_index);
15561556
......@@ -1591,7 +1591,7 @@ fn resolveLoopLiveSet(
15911591 try data.live_set.ensureUnusedCapacity(gpa, @intCast(loop_live.len));
15921592 for (loop_live) |alive| data.live_set.putAssumeCapacity(alive, {});
15931593
1594 log.debug("[{}] %{}: block live set is {}", .{ LivenessPass.main_analysis, inst, fmtInstSet(&data.live_set) });
1594 log.debug("[{}] %{f}: block live set is {f}", .{ LivenessPass.main_analysis, inst, fmtInstSet(&data.live_set) });
15951595
15961596 for (breaks) |block_inst| {
15971597 // We might break to this block, so include every operand that the block needs alive
......@@ -1604,7 +1604,7 @@ fn resolveLoopLiveSet(
16041604 }
16051605 }
16061606
1607 log.debug("[{}] %{}: loop live set is {}", .{ LivenessPass.main_analysis, inst, fmtInstSet(&data.live_set) });
1607 log.debug("[{}] %{f}: loop live set is {f}", .{ LivenessPass.main_analysis, inst, fmtInstSet(&data.live_set) });
16081608}
16091609
16101610fn analyzeInstLoop(
......@@ -1642,7 +1642,7 @@ fn analyzeInstLoop(
16421642 .live_set = data.live_set.move(),
16431643 });
16441644 defer {
1645 log.debug("[{}] %{}: popped loop block scop", .{ pass, inst });
1645 log.debug("[{}] %{f}: popped loop block scop", .{ pass, inst });
16461646 var scope = data.block_scopes.fetchRemove(inst).?.value;
16471647 scope.live_set.deinit(gpa);
16481648 }
......@@ -1743,13 +1743,13 @@ fn analyzeInstCondBr(
17431743 }
17441744 }
17451745
1746 log.debug("[{}] %{}: 'then' branch mirrored deaths are {}", .{ pass, inst, fmtInstList(then_mirrored_deaths.items) });
1747 log.debug("[{}] %{}: 'else' branch mirrored deaths are {}", .{ pass, inst, fmtInstList(else_mirrored_deaths.items) });
1746 log.debug("[{}] %{f}: 'then' branch mirrored deaths are {f}", .{ pass, inst, fmtInstList(then_mirrored_deaths.items) });
1747 log.debug("[{}] %{f}: 'else' branch mirrored deaths are {f}", .{ pass, inst, fmtInstList(else_mirrored_deaths.items) });
17481748
17491749 data.live_set.deinit(gpa);
17501750 data.live_set = then_live.move(); // Really the union of both live sets
17511751
1752 log.debug("[{}] %{}: new live set is {}", .{ pass, inst, fmtInstSet(&data.live_set) });
1752 log.debug("[{}] %{f}: new live set is {f}", .{ pass, inst, fmtInstSet(&data.live_set) });
17531753
17541754 // Write the mirrored deaths to `extra`
17551755 const then_death_count = @as(u32, @intCast(then_mirrored_deaths.items.len));
......@@ -1817,7 +1817,7 @@ fn analyzeInstSwitchBr(
18171817 });
18181818 }
18191819 defer if (is_dispatch_loop) {
1820 log.debug("[{}] %{}: popped loop block scop", .{ pass, inst });
1820 log.debug("[{}] %{f}: popped loop block scop", .{ pass, inst });
18211821 var scope = data.block_scopes.fetchRemove(inst).?.value;
18221822 scope.live_set.deinit(gpa);
18231823 };
......@@ -1875,13 +1875,13 @@ fn analyzeInstSwitchBr(
18751875 }
18761876
18771877 for (mirrored_deaths, 0..) |mirrored, i| {
1878 log.debug("[{}] %{}: case {} mirrored deaths are {}", .{ pass, inst, i, fmtInstList(mirrored.items) });
1878 log.debug("[{}] %{f}: case {} mirrored deaths are {f}", .{ pass, inst, i, fmtInstList(mirrored.items) });
18791879 }
18801880
18811881 data.live_set.deinit(gpa);
18821882 data.live_set = all_alive.move();
18831883
1884 log.debug("[{}] %{}: new live set is {}", .{ pass, inst, fmtInstSet(&data.live_set) });
1884 log.debug("[{}] %{f}: new live set is {f}", .{ pass, inst, fmtInstSet(&data.live_set) });
18851885 }
18861886
18871887 const else_death_count = @as(u32, @intCast(mirrored_deaths[ncases].items.len));
......@@ -1980,7 +1980,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
19801980
19811981 .main_analysis => {
19821982 if ((try big.data.live_set.fetchPut(gpa, operand, {})) == null) {
1983 log.debug("[{}] %{}: added %{} to live set (operand dies here)", .{ pass, big.inst, operand });
1983 log.debug("[{}] %{f}: added %{f} to live set (operand dies here)", .{ pass, big.inst, operand });
19841984 big.extra_tombs[extra_byte] |= @as(u32, 1) << extra_bit;
19851985 }
19861986 },
......@@ -2036,15 +2036,15 @@ fn fmtInstSet(set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void)) FmtIns
20362036const FmtInstSet = struct {
20372037 set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void),
20382038
2039 pub fn format(val: FmtInstSet, comptime _: []const u8, _: std.fmt.FormatOptions, w: anytype) !void {
2039 pub fn format(val: FmtInstSet, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
20402040 if (val.set.count() == 0) {
2041 try w.writeAll("[no instructions]");
2041 try bw.writeAll("[no instructions]");
20422042 return;
20432043 }
20442044 var it = val.set.keyIterator();
2045 try w.print("%{}", .{it.next().?.*});
2045 try bw.print("%{f}", .{it.next().?.*});
20462046 while (it.next()) |key| {
2047 try w.print(" %{}", .{key.*});
2047 try bw.print(" %{f}", .{key.*});
20482048 }
20492049 }
20502050};
......@@ -2056,14 +2056,14 @@ fn fmtInstList(list: []const Air.Inst.Index) FmtInstList {
20562056const FmtInstList = struct {
20572057 list: []const Air.Inst.Index,
20582058
2059 pub fn format(val: FmtInstList, comptime _: []const u8, _: std.fmt.FormatOptions, w: anytype) !void {
2059 pub fn format(val: FmtInstList, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
20602060 if (val.list.len == 0) {
2061 try w.writeAll("[no instructions]");
2061 try bw.writeAll("[no instructions]");
20622062 return;
20632063 }
2064 try w.print("%{}", .{val.list[0]});
2064 try bw.print("%{f}", .{val.list[0]});
20652065 for (val.list[1..]) |inst| {
2066 try w.print(" %{}", .{inst});
2066 try bw.print(" %{f}", .{inst});
20672067 }
20682068 }
20692069};
src/Air/Liveness/Verify.zig+8-8
......@@ -73,7 +73,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
7373 .trap, .unreach => {
7474 try self.verifyInstOperands(inst, .{ .none, .none, .none });
7575 // This instruction terminates the function, so everything should be dead
76 if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
76 if (self.live.count() > 0) return invalid("%{f}: instructions still alive", .{inst});
7777 },
7878
7979 // unary
......@@ -166,7 +166,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
166166 const un_op = data[@intFromEnum(inst)].un_op;
167167 try self.verifyInstOperands(inst, .{ un_op, .none, .none });
168168 // This instruction terminates the function, so everything should be dead
169 if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
169 if (self.live.count() > 0) return invalid("%{f}: instructions still alive", .{inst});
170170 },
171171 .dbg_var_ptr,
172172 .dbg_var_val,
......@@ -450,7 +450,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
450450 .repeat => {
451451 const repeat = data[@intFromEnum(inst)].repeat;
452452 const expected_live = self.loops.get(repeat.loop_inst) orelse
453 return invalid("%{}: loop %{} not in scope", .{ @intFromEnum(inst), @intFromEnum(repeat.loop_inst) });
453 return invalid("%{d}: loop %{d} not in scope", .{ @intFromEnum(inst), @intFromEnum(repeat.loop_inst) });
454454
455455 try self.verifyMatchingLiveness(repeat.loop_inst, expected_live);
456456 },
......@@ -460,7 +460,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
460460 try self.verifyOperand(inst, br.operand, self.liveness.operandDies(inst, 0));
461461
462462 const expected_live = self.loops.get(br.block_inst) orelse
463 return invalid("%{}: loop %{} not in scope", .{ @intFromEnum(inst), @intFromEnum(br.block_inst) });
463 return invalid("%{d}: loop %{d} not in scope", .{ @intFromEnum(inst), @intFromEnum(br.block_inst) });
464464
465465 try self.verifyMatchingLiveness(br.block_inst, expected_live);
466466 },
......@@ -601,9 +601,9 @@ fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies
601601 return;
602602 };
603603 if (dies) {
604 if (!self.live.remove(operand)) return invalid("%{}: dead operand %{} reused and killed again", .{ inst, operand });
604 if (!self.live.remove(operand)) return invalid("%{f}: dead operand %{f} reused and killed again", .{ inst, operand });
605605 } else {
606 if (!self.live.contains(operand)) return invalid("%{}: dead operand %{} reused", .{ inst, operand });
606 if (!self.live.contains(operand)) return invalid("%{f}: dead operand %{f} reused", .{ inst, operand });
607607 }
608608}
609609
......@@ -628,9 +628,9 @@ fn verifyInst(self: *Verify, inst: Air.Inst.Index) Error!void {
628628}
629629
630630fn verifyMatchingLiveness(self: *Verify, block: Air.Inst.Index, live: LiveMap) Error!void {
631 if (self.live.count() != live.count()) return invalid("%{}: different deaths across branches", .{block});
631 if (self.live.count() != live.count()) return invalid("%{f}: different deaths across branches", .{block});
632632 var live_it = self.live.keyIterator();
633 while (live_it.next()) |live_inst| if (!live.contains(live_inst.*)) return invalid("%{}: different deaths across branches", .{block});
633 while (live_it.next()) |live_inst| if (!live.contains(live_inst.*)) return invalid("%{f}: different deaths across branches", .{block});
634634}
635635
636636fn invalid(comptime fmt: []const u8, args: anytype) error{LivenessInvalid} {
src/Air/print.zig+14-14
......@@ -101,7 +101,7 @@ const Writer = struct {
101101 fn writeInst(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) anyerror!void {
102102 const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)];
103103 try s.splatByteAll(' ', w.indent);
104 try s.print("{}{c}= {s}(", .{
104 try s.print("{f}{c}= {s}(", .{
105105 inst,
106106 @as(u8, if (if (w.liveness) |liveness| liveness.isUnused(inst) else false) '!' else ' '),
107107 @tagName(tag),
......@@ -416,7 +416,7 @@ const Writer = struct {
416416 try s.writeAll("}");
417417
418418 for (liveness_block.deaths) |operand| {
419 try s.print(" {}!", .{operand});
419 try s.print(" {f}!", .{operand});
420420 }
421421 }
422422
......@@ -708,7 +708,7 @@ const Writer = struct {
708708 }
709709 }
710710 const asm_source = std.mem.sliceAsBytes(w.air.extra.items[extra_i..])[0..extra.data.source_len];
711 try s.print(", \"{}\"", .{std.zig.fmtEscapes(asm_source)});
711 try s.print(", \"{f}\"", .{std.zig.fmtEscapes(asm_source)});
712712 }
713713
714714 fn writeDbgStmt(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) anyerror!void {
......@@ -720,7 +720,7 @@ const Writer = struct {
720720 const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
721721 try w.writeOperand(s, inst, 0, pl_op.operand);
722722 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
723 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))});
723 try s.print(", \"{f}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))});
724724 }
725725
726726 fn writeCall(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) anyerror!void {
......@@ -767,7 +767,7 @@ const Writer = struct {
767767 try s.splatByteAll(' ', w.indent);
768768 for (liveness_condbr.else_deaths, 0..) |operand, i| {
769769 if (i != 0) try s.writeAll(" ");
770 try s.print("{}!", .{operand});
770 try s.print("{f}!", .{operand});
771771 }
772772 try s.writeAll("\n");
773773 }
......@@ -778,7 +778,7 @@ const Writer = struct {
778778 try s.writeAll("}");
779779
780780 for (liveness_condbr.then_deaths) |operand| {
781 try s.print(" {}!", .{operand});
781 try s.print(" {f}!", .{operand});
782782 }
783783 }
784784
......@@ -804,7 +804,7 @@ const Writer = struct {
804804 try s.splatByteAll(' ', w.indent);
805805 for (liveness_condbr.else_deaths, 0..) |operand, i| {
806806 if (i != 0) try s.writeAll(" ");
807 try s.print("{}!", .{operand});
807 try s.print("{f}!", .{operand});
808808 }
809809 try s.writeAll("\n");
810810 }
......@@ -815,7 +815,7 @@ const Writer = struct {
815815 try s.writeAll("}");
816816
817817 for (liveness_condbr.then_deaths) |operand| {
818 try s.print(" {}!", .{operand});
818 try s.print(" {f}!", .{operand});
819819 }
820820 }
821821
......@@ -846,7 +846,7 @@ const Writer = struct {
846846 try s.splatByteAll(' ', w.indent);
847847 for (liveness_condbr.then_deaths, 0..) |operand, i| {
848848 if (i != 0) try s.writeAll(" ");
849 try s.print("{}!", .{operand});
849 try s.print("{f}!", .{operand});
850850 }
851851 try s.writeAll("\n");
852852 }
......@@ -866,7 +866,7 @@ const Writer = struct {
866866 try s.splatByteAll(' ', w.indent);
867867 for (liveness_condbr.else_deaths, 0..) |operand, i| {
868868 if (i != 0) try s.writeAll(" ");
869 try s.print("{}!", .{operand});
869 try s.print("{f}!", .{operand});
870870 }
871871 try s.writeAll("\n");
872872 }
......@@ -923,7 +923,7 @@ const Writer = struct {
923923 try s.splatByteAll(' ', w.indent);
924924 for (deaths, 0..) |operand, i| {
925925 if (i != 0) try s.writeAll(" ");
926 try s.print("{}!", .{operand});
926 try s.print("{f}!", .{operand});
927927 }
928928 try s.writeAll("\n");
929929 }
......@@ -949,7 +949,7 @@ const Writer = struct {
949949 try s.splatByteAll(' ', w.indent);
950950 for (deaths, 0..) |operand, i| {
951951 if (i != 0) try s.writeAll(" ");
952 try s.print("{}!", .{operand});
952 try s.print("{f}!", .{operand});
953953 }
954954 try s.writeAll("\n");
955955 }
......@@ -1017,7 +1017,7 @@ const Writer = struct {
10171017 } else if (operand.toInterned()) |ip_index| {
10181018 const pt = w.pt;
10191019 const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf());
1020 try s.print("<{}, {}>", .{
1020 try s.print("<{f}, {f}>", .{
10211021 ty.fmt(pt),
10221022 Value.fromInterned(ip_index).fmtValue(pt),
10231023 });
......@@ -1033,7 +1033,7 @@ const Writer = struct {
10331033 dies: bool,
10341034 ) anyerror!void {
10351035 _ = w;
1036 try s.print("{}", .{inst});
1036 try s.print("{f}", .{inst});
10371037 if (dies) try s.writeByte('!');
10381038 }
10391039
src/Builtin.zig+17-17
......@@ -57,18 +57,18 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
5757 \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
5858 \\pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable;
5959 \\pub const zig_version_string = "{s}";
60 \\pub const zig_backend = std.builtin.CompilerBackend.{p_};
60 \\pub const zig_backend = std.builtin.CompilerBackend.{fp_};
6161 \\
62 \\pub const output_mode: std.builtin.OutputMode = .{p_};
63 \\pub const link_mode: std.builtin.LinkMode = .{p_};
64 \\pub const unwind_tables: std.builtin.UnwindTables = .{p_};
62 \\pub const output_mode: std.builtin.OutputMode = .{fp_};
63 \\pub const link_mode: std.builtin.LinkMode = .{fp_};
64 \\pub const unwind_tables: std.builtin.UnwindTables = .{fp_};
6565 \\pub const is_test = {};
6666 \\pub const single_threaded = {};
67 \\pub const abi: std.Target.Abi = .{p_};
67 \\pub const abi: std.Target.Abi = .{fp_};
6868 \\pub const cpu: std.Target.Cpu = .{{
69 \\ .arch = .{p_},
70 \\ .model = &std.Target.{p_}.cpu.{p_},
71 \\ .features = std.Target.{p_}.featureSet(&.{{
69 \\ .arch = .{fp_},
70 \\ .model = &std.Target.{fp_}.cpu.{fp_},
71 \\ .features = std.Target.{fp_}.featureSet(&.{{
7272 \\
7373 , .{
7474 build_options.version,
......@@ -89,14 +89,14 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
8989 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
9090 const is_enabled = target.cpu.features.isEnabled(index);
9191 if (is_enabled) {
92 try buffer.print(" .{p_},\n", .{std.zig.fmtId(feature.name)});
92 try buffer.print(" .{fp_},\n", .{std.zig.fmtId(feature.name)});
9393 }
9494 }
9595 try buffer.print(
9696 \\ }}),
9797 \\}};
9898 \\pub const os: std.Target.Os = .{{
99 \\ .tag = .{p_},
99 \\ .tag = .{fp_},
100100 \\ .version_range = .{{
101101 ,
102102 .{std.zig.fmtId(@tagName(target.os.tag))},
......@@ -200,8 +200,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
200200 }),
201201 .windows => |windows| try buffer.print(
202202 \\ .windows = .{{
203 \\ .min = {c},
204 \\ .max = {c},
203 \\ .min = {fc},
204 \\ .max = {fc},
205205 \\ }}}},
206206 \\
207207 , .{ windows.min, windows.max }),
......@@ -238,8 +238,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
238238 const link_libc = opts.link_libc;
239239
240240 try buffer.print(
241 \\pub const object_format: std.Target.ObjectFormat = .{p_};
242 \\pub const mode: std.builtin.OptimizeMode = .{p_};
241 \\pub const object_format: std.Target.ObjectFormat = .{fp_};
242 \\pub const mode: std.builtin.OptimizeMode = .{fp_};
243243 \\pub const link_libc = {};
244244 \\pub const link_libcpp = {};
245245 \\pub const have_error_return_tracing = {};
......@@ -249,7 +249,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
249249 \\pub const position_independent_code = {};
250250 \\pub const position_independent_executable = {};
251251 \\pub const strip_debug_info = {};
252 \\pub const code_model: std.builtin.CodeModel = .{p_};
252 \\pub const code_model: std.builtin.CodeModel = .{fp_};
253253 \\pub const omit_frame_pointer = {};
254254 \\
255255 , .{
......@@ -270,7 +270,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
270270
271271 if (target.os.tag == .wasi) {
272272 try buffer.print(
273 \\pub const wasi_exec_model: std.builtin.WasiExecModel = .{p_};
273 \\pub const wasi_exec_model: std.builtin.WasiExecModel = .{fp_};
274274 \\
275275 , .{std.zig.fmtId(@tagName(opts.wasi_exec_model))});
276276 }
......@@ -317,7 +317,7 @@ pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void {
317317 if (root_dir.statFile(sub_path)) |stat| {
318318 if (stat.size != file.source.?.len) {
319319 std.log.warn(
320 "the cached file '{}' had the wrong size. Expected {d}, found {d}. " ++
320 "the cached file '{f}{s}' had the wrong size. Expected {d}, found {d}. " ++
321321 "Overwriting with correct file contents now",
322322 .{ file.path.fmt(comp), file.source.?.len, stat.size },
323323 );
src/Compilation.zig+20-23
......@@ -1068,11 +1068,12 @@ pub const CObject = struct {
10681068 }
10691069 };
10701070
1071 var buffer: [1024]u8 = undefined;
10711072 const file = try std.fs.cwd().openFile(path, .{});
10721073 defer file.close();
1073 var br = std.io.bufferedReader(file.reader());
1074 const reader = br.reader();
1075 var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = reader.any() });
1074 var br: std.io.BufferedReader = undefined;
1075 br.init(file.reader(), &buffer);
1076 var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .br = &br });
10761077 defer bc.deinit();
10771078
10781079 var file_names: std.AutoArrayHashMapUnmanaged(u32, []const u8) = .empty;
......@@ -2709,7 +2710,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
27092710 const prefix = man.cache.prefixes()[pp.prefix];
27102711 return comp.setMiscFailure(
27112712 .check_whole_cache,
2712 "failed to check cache: '{}{s}' {s} {s}",
2713 "failed to check cache: '{f}{s}' {s} {s}",
27132714 .{ prefix, pp.sub_path, @tagName(man.diagnostic), @errorName(op.err) },
27142715 );
27152716 },
......@@ -2926,7 +2927,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
29262927 renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| {
29272928 return comp.setMiscFailure(
29282929 .rename_results,
2929 "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}",
2930 "failed to rename compilation results ('{f}{s}') into local cache ('{f}{s}'): {s}",
29302931 .{
29312932 comp.dirs.local_cache, tmp_dir_sub_path,
29322933 comp.dirs.local_cache, o_sub_path,
......@@ -4847,7 +4848,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {
48474848 var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| {
48484849 return comp.lockAndSetMiscFailure(
48494850 .docs_copy,
4850 "unable to create output directory '{}': {s}",
4851 "unable to create output directory '{f}': {s}",
48514852 .{ docs_path, @errorName(err) },
48524853 );
48534854 };
......@@ -4867,7 +4868,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void {
48674868 var tar_file = out_dir.createFile("sources.tar", .{}) catch |err| {
48684869 return comp.lockAndSetMiscFailure(
48694870 .docs_copy,
4870 "unable to create '{}/sources.tar': {s}",
4871 "unable to create '{f}/sources.tar': {s}",
48714872 .{ docs_path, @errorName(err) },
48724873 );
48734874 };
......@@ -4896,7 +4897,7 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8,
48964897 const root_dir, const sub_path = root.openInfo(comp.dirs);
48974898 break :d root_dir.openDir(sub_path, .{ .iterate = true });
48984899 } catch |err| {
4899 return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{}': {s}", .{
4900 return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{f}': {s}", .{
49004901 root.fmt(comp), @errorName(err),
49014902 });
49024903 };
......@@ -5142,7 +5143,7 @@ fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void {
51425143 defer comp.mutex.unlock();
51435144 comp.setMiscFailure(
51445145 .write_builtin_zig,
5145 "unable to write '{}': {s}",
5146 "unable to write '{f}': {s}",
51465147 .{ file.path.fmt(comp), @errorName(err) },
51475148 );
51485149 };
......@@ -5863,7 +5864,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
58635864
58645865 try child.spawn();
58655866
5866 const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize));
5867 const stderr = try child.stderr.?.readToEndAlloc(arena, .unlimited);
58675868
58685869 const term = child.wait() catch |err| {
58695870 return comp.failCObj(c_object, "failed to spawn zig clang {s}: {s}", .{ argv.items[0], @errorName(err) });
......@@ -6023,13 +6024,12 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
60236024
60246025 // In .rc files, a " within a quoted string is escaped as ""
60256026 const fmtRcEscape = struct {
6026 fn formatRcEscape(bytes: []const u8, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
6027 fn formatRcEscape(bytes: []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
60276028 _ = fmt;
6028 _ = options;
60296029 for (bytes) |byte| switch (byte) {
6030 '"' => try writer.writeAll("\"\""),
6031 '\\' => try writer.writeAll("\\\\"),
6032 else => try writer.writeByte(byte),
6030 '"' => try bw.writeAll("\"\""),
6031 '\\' => try bw.writeAll("\\\\"),
6032 else => try bw.writeByte(byte),
60336033 };
60346034 }
60356035
......@@ -6047,7 +6047,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
60476047 // 24 is RT_MANIFEST
60486048 const resource_type = 24;
60496049
6050 const input = try std.fmt.allocPrint(arena, "{} {} \"{s}\"", .{ resource_id, resource_type, fmtRcEscape(src_path) });
6050 const input = try std.fmt.allocPrint(arena, "{} {} \"{f}\"", .{ resource_id, resource_type, fmtRcEscape(src_path) });
60516051
60526052 try o_dir.writeFile(.{ .sub_path = rc_basename, .data = input });
60536053
......@@ -6227,13 +6227,10 @@ fn spawnZigRc(
62276227 const stdout = poller.fifo(.stdout);
62286228
62296229 poll: while (true) {
6230 while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) {
6231 if (!(try poller.poll())) break :poll;
6232 }
6233 const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable;
6234 while (stdout.readableLength() < header.bytes_len) {
6235 if (!(try poller.poll())) break :poll;
6236 }
6230 while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) if (!try poller.poll()) break :poll;
6231 var header: std.zig.Server.Message.Header = undefined;
6232 assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(std.zig.Server.Message.Header));
6233 while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll;
62376234 const body = stdout.readableSliceOfLen(header.bytes_len);
62386235
62396236 switch (header.tag) {
src/InternPool.zig+6-11
......@@ -1888,17 +1888,12 @@ pub const NullTerminatedString = enum(u32) {
18881888 string: NullTerminatedString,
18891889 ip: *const InternPool,
18901890 };
1891 fn format(
1892 data: FormatData,
1893 comptime specifier: []const u8,
1894 _: std.fmt.FormatOptions,
1895 writer: anytype,
1896 ) @TypeOf(writer).Error!void {
1891 fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime specifier: []const u8) anyerror!void {
18971892 const slice = data.string.toSlice(data.ip);
18981893 if (comptime std.mem.eql(u8, specifier, "")) {
1899 try writer.writeAll(slice);
1894 try bw.writeAll(slice);
19001895 } else if (comptime std.mem.eql(u8, specifier, "i")) {
1901 try writer.print("{p}", .{std.zig.fmtId(slice)});
1896 try bw.print("{fp}", .{std.zig.fmtId(slice)});
19021897 } else @compileError("invalid format string '" ++ specifier ++ "' for '" ++ @typeName(NullTerminatedString) ++ "'");
19031898 }
19041899
......@@ -9758,7 +9753,7 @@ fn finishFuncInstance(
97589753 const fn_namespace = fn_owner_nav.analysis.?.namespace;
97599754
97609755 // TODO: improve this name
9761 const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
9756 const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{f}__anon_{d}", .{
97629757 fn_owner_nav.name.fmt(ip), @intFromEnum(func_index),
97639758 }, .no_embedded_nulls);
97649759 const nav_index = try ip.createNav(gpa, tid, .{
......@@ -11415,12 +11410,12 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1141511410 var it = instances.iterator();
1141611411 while (it.next()) |entry| {
1141711412 const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);
11418 try bw.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
11413 try bw.print("{f} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
1141911414 for (entry.value_ptr.items) |index| {
1142011415 const unwrapped_index = index.unwrap(ip);
1142111416 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
1142211417 const owner_nav = ip.getNav(func.owner_nav);
11423 try bw.print(" {}: (", .{owner_nav.name.fmt(ip)});
11418 try bw.print(" {f}: (", .{owner_nav.name.fmt(ip)});
1142411419 for (func.comptime_args.get(ip)) |arg| {
1142511420 if (arg != .none) {
1142611421 const key = ip.indexToKey(arg);
src/Package.zig+1-1
......@@ -134,7 +134,7 @@ pub const Hash = struct {
134134 }
135135 var bin_digest: [Algo.digest_length]u8 = undefined;
136136 Algo.hash(sub_path, &bin_digest, .{});
137 _ = std.fmt.bufPrint(result.bytes[i..], "{}", .{std.fmt.fmtSliceHexLower(&bin_digest)}) catch unreachable;
137 _ = std.fmt.bufPrint(result.bytes[i..], "{x}", .{&bin_digest}) catch unreachable;
138138 return result;
139139 }
140140};
src/Package/Fetch.zig+15-15
......@@ -185,7 +185,7 @@ pub const JobQueue = struct {
185185 const hash_slice = hash.toSlice();
186186
187187 try buf.print(
188 \\ pub const {} = struct {{
188 \\ pub const {f} = struct {{
189189 \\
190190 , .{std.zig.fmtId(hash_slice)});
191191
......@@ -211,13 +211,13 @@ pub const JobQueue = struct {
211211 }
212212
213213 try buf.print(
214 \\ pub const build_root = "{q}";
214 \\ pub const build_root = "{fq}";
215215 \\
216216 , .{fetch.package_root});
217217
218218 if (fetch.has_build_zig) {
219219 try buf.print(
220 \\ pub const build_zig = @import("{}");
220 \\ pub const build_zig = @import("{f}");
221221 \\
222222 , .{std.zig.fmtEscapes(hash_slice)});
223223 }
......@@ -230,7 +230,7 @@ pub const JobQueue = struct {
230230 for (manifest.dependencies.keys(), manifest.dependencies.values()) |name, dep| {
231231 const h = depDigest(fetch.package_root, jq.global_cache, dep) orelse continue;
232232 try buf.print(
233 " .{{ \"{}\", \"{}\" }},\n",
233 " .{{ \"{f}\", \"{f}\" }},\n",
234234 .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(h.toSlice()) },
235235 );
236236 }
......@@ -262,7 +262,7 @@ pub const JobQueue = struct {
262262 for (root_manifest.dependencies.keys(), root_manifest.dependencies.values()) |name, dep| {
263263 const h = depDigest(root_fetch.package_root, jq.global_cache, dep) orelse continue;
264264 try buf.print(
265 " .{{ \"{}\", \"{}\" }},\n",
265 " .{{ \"{f}\", \"{f}\" }},\n",
266266 .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(h.toSlice()) },
267267 );
268268 }
......@@ -353,7 +353,7 @@ pub fn run(f: *Fetch) RunError!void {
353353 if (!std.mem.startsWith(u8, pkg_root.sub_path, expected_prefix)) {
354354 return f.fail(
355355 f.location_tok,
356 try eb.printString("dependency path outside project: '{}'", .{pkg_root}),
356 try eb.printString("dependency path outside project: '{f}'", .{pkg_root}),
357357 );
358358 }
359359 }
......@@ -604,7 +604,7 @@ pub fn computedPackageHash(f: *const Fetch) Package.Hash {
604604 const saturated_size = std.math.cast(u32, f.computed_hash.total_size) orelse std.math.maxInt(u32);
605605 if (f.manifest) |man| {
606606 var version_buffer: [32]u8 = undefined;
607 const version: []const u8 = std.fmt.bufPrint(&version_buffer, "{}", .{man.version}) catch &version_buffer;
607 const version: []const u8 = std.fmt.bufPrint(&version_buffer, "{f}", .{man.version}) catch &version_buffer;
608608 return .init(f.computed_hash.digest, man.name, version, man.id, saturated_size);
609609 }
610610 // In the future build.zig.zon fields will be added to allow overriding these values
......@@ -622,7 +622,7 @@ fn checkBuildFileExistence(f: *Fetch) RunError!void {
622622 error.FileNotFound => {},
623623 else => |e| {
624624 try eb.addRootErrorMessage(.{
625 .msg = try eb.printString("unable to access '{}{s}': {s}", .{
625 .msg = try eb.printString("unable to access '{f}{s}': {s}", .{
626626 f.package_root, Package.build_zig_basename, @errorName(e),
627627 }),
628628 });
......@@ -636,9 +636,9 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
636636 const eb = &f.error_bundle;
637637 const arena = f.arena.allocator();
638638 const manifest_bytes = pkg_root.root_dir.handle.readFileAllocOptions(
639 arena,
640639 try fs.path.join(arena, &.{ pkg_root.sub_path, Manifest.basename }),
641 Manifest.max_bytes,
640 arena,
641 .limited(Manifest.max_bytes),
642642 null,
643643 .@"1",
644644 0,
......@@ -647,7 +647,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
647647 else => |e| {
648648 const file_path = try pkg_root.join(arena, Manifest.basename);
649649 try eb.addRootErrorMessage(.{
650 .msg = try eb.printString("unable to load package manifest '{}': {s}", .{
650 .msg = try eb.printString("unable to load package manifest '{f}': {s}", .{
651651 file_path, @errorName(e),
652652 }),
653653 });
......@@ -659,7 +659,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
659659 ast.* = try std.zig.Ast.parse(arena, manifest_bytes, .zon);
660660
661661 if (ast.errors.len > 0) {
662 const file_path = try std.fmt.allocPrint(arena, "{}" ++ fs.path.sep_str ++ Manifest.basename, .{pkg_root});
662 const file_path = try std.fmt.allocPrint(arena, "{f}" ++ fs.path.sep_str ++ Manifest.basename, .{pkg_root});
663663 try std.zig.putAstErrorsIntoBundle(arena, ast.*, file_path, eb);
664664 return error.FetchFailed;
665665 }
......@@ -672,7 +672,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
672672 const manifest = &f.manifest.?;
673673
674674 if (manifest.errors.len > 0) {
675 const src_path = try eb.printString("{}" ++ fs.path.sep_str ++ "{s}", .{ pkg_root, Manifest.basename });
675 const src_path = try eb.printString("{f}" ++ fs.path.sep_str ++ "{s}", .{ pkg_root, Manifest.basename });
676676 try manifest.copyErrorsIntoBundle(ast.*, src_path, eb);
677677 return error.FetchFailed;
678678 }
......@@ -827,7 +827,7 @@ fn srcLoc(
827827 const ast = f.parent_manifest_ast orelse return .none;
828828 const eb = &f.error_bundle;
829829 const start_loc = ast.tokenLocation(0, tok);
830 const src_path = try eb.printString("{}" ++ fs.path.sep_str ++ Manifest.basename, .{f.parent_package_root});
830 const src_path = try eb.printString("{f}" ++ fs.path.sep_str ++ Manifest.basename, .{f.parent_package_root});
831831 const msg_off = 0;
832832 return eb.addSourceLocation(.{
833833 .src_path = src_path,
......@@ -1512,7 +1512,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute
15121512
15131513 while (walker.next() catch |err| {
15141514 try eb.addRootErrorMessage(.{ .msg = try eb.printString(
1515 "unable to walk temporary directory '{}': {s}",
1515 "unable to walk temporary directory '{f}': {s}",
15161516 .{ pkg_path, @errorName(err) },
15171517 ) });
15181518 return error.FetchFailed;
src/Package/Fetch/git.zig+2-8
......@@ -119,15 +119,9 @@ pub const Oid = union(Format) {
119119 } else error.InvalidOid;
120120 }
121121
122 pub fn format(
123 oid: Oid,
124 comptime fmt: []const u8,
125 options: std.fmt.Options,
126 writer: *std.io.BufferedWriter,
127 ) anyerror!void {
122 pub fn format(oid: Oid, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
128123 _ = fmt;
129 _ = options;
130 try writer.print("{x}", .{oid.slice()});
124 try bw.print("{x}", .{oid.slice()});
131125 }
132126
133127 pub fn slice(oid: *const Oid) []const u8 {
src/Package/Manifest.zig+2-2
......@@ -401,7 +401,7 @@ const Parse = struct {
401401 return fail(p, main_token, "name must be a valid bare zig identifier (hint: switch from string to enum literal)", .{});
402402
403403 if (name.len > max_name_len)
404 return fail(p, main_token, "name '{}' exceeds max length of {d}", .{
404 return fail(p, main_token, "name '{f}' exceeds max length of {d}", .{
405405 std.zig.fmtId(name), max_name_len,
406406 });
407407
......@@ -416,7 +416,7 @@ const Parse = struct {
416416 return fail(p, main_token, "name must be a valid bare zig identifier", .{});
417417
418418 if (ident_name.len > max_name_len)
419 return fail(p, main_token, "name '{}' exceeds max length of {d}", .{
419 return fail(p, main_token, "name '{f}' exceeds max length of {d}", .{
420420 std.zig.fmtId(ident_name), max_name_len,
421421 });
422422
src/Sema.zig+419-416
......@@ -888,7 +888,7 @@ const ComptimeReason = union(enum) {
888888 /// Evaluating at comptime because of a comptime-only type. This field is separate so that
889889 /// the type in question can be included in the error message. AstGen could never emit this
890890 /// reason, because it knows nothing of types.
891 /// The format string looks like "foo '{}' bar", where "{}" is the comptime-only type.
891 /// The format string looks like "foo '{f}' bar", where "{f}" is the comptime-only type.
892892 /// We will then explain why this type is comptime-only.
893893 comptime_only: struct {
894894 ty: Type,
......@@ -930,17 +930,17 @@ const ComptimeReason = union(enum) {
930930 .struct_init => .{ "initializer of comptime-only struct", "must be comptime-known" },
931931 .tuple_init => .{ "initializer of comptime-only tuple", "must be comptime-known" },
932932 };
933 try sema.errNote(src, err_msg, "{s} '{}' {s}", .{ pre, co.ty.fmt(sema.pt), post });
933 try sema.errNote(src, err_msg, "{s} '{f}' {s}", .{ pre, co.ty.fmt(sema.pt), post });
934934 try sema.explainWhyTypeIsComptime(err_msg, src, co.ty);
935935 },
936936 .comptime_only_param_ty => |co| {
937 try sema.errNote(src, err_msg, "argument to parameter with comptime-only type '{}' must be comptime-known", .{co.ty.fmt(sema.pt)});
937 try sema.errNote(src, err_msg, "argument to parameter with comptime-only type '{f}' must be comptime-known", .{co.ty.fmt(sema.pt)});
938938 try sema.errNote(co.param_ty_src, err_msg, "parameter type declared here", .{});
939939 try sema.explainWhyTypeIsComptime(err_msg, src, co.ty);
940940 },
941941 .comptime_only_ret_ty => |co| {
942942 const function_with: []const u8 = if (co.is_generic_inst) "generic function instantiated with" else "function with";
943 try sema.errNote(src, err_msg, "call to {s} comptime-only return type '{}' is evaluated at comptime", .{ function_with, co.ty.fmt(sema.pt) });
943 try sema.errNote(src, err_msg, "call to {s} comptime-only return type '{f}' is evaluated at comptime", .{ function_with, co.ty.fmt(sema.pt) });
944944 try sema.errNote(co.ret_ty_src, err_msg, "return type declared here", .{});
945945 try sema.explainWhyTypeIsComptime(err_msg, src, co.ty);
946946 },
......@@ -1909,7 +1909,7 @@ fn analyzeBodyInner(
19091909 const err_union = try sema.resolveInst(extra.data.operand);
19101910 const err_union_ty = sema.typeOf(err_union);
19111911 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
1912 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
1912 return sema.fail(block, operand_src, "expected error union type, found '{f}'", .{
19131913 err_union_ty.fmt(pt),
19141914 });
19151915 }
......@@ -2343,7 +2343,7 @@ pub fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) Compile
23432343
23442344fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError {
23452345 const pt = sema.pt;
2346 return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{
2346 return sema.fail(block, src, "remainder division with '{f}' and '{f}': signed integers and floats must use @rem or @mod", .{
23472347 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
23482348 });
23492349}
......@@ -2351,7 +2351,7 @@ fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: T
23512351fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError {
23522352 const pt = sema.pt;
23532353 const msg = msg: {
2354 const msg = try sema.errMsg(src, "expected optional type, found '{}'", .{
2354 const msg = try sema.errMsg(src, "expected optional type, found '{f}'", .{
23552355 non_optional_ty.fmt(pt),
23562356 });
23572357 errdefer msg.destroy(sema.gpa);
......@@ -2367,12 +2367,12 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non
23672367fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
23682368 const pt = sema.pt;
23692369 const msg = msg: {
2370 const msg = try sema.errMsg(src, "type '{}' does not support array initialization syntax", .{
2370 const msg = try sema.errMsg(src, "type '{f}' does not support array initialization syntax", .{
23712371 ty.fmt(pt),
23722372 });
23732373 errdefer msg.destroy(sema.gpa);
23742374 if (ty.isSlice(pt.zcu)) {
2375 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(pt.zcu).fmt(pt)});
2375 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{f}'", .{ty.elemType2(pt.zcu).fmt(pt)});
23762376 }
23772377 break :msg msg;
23782378 };
......@@ -2381,7 +2381,7 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty
23812381
23822382fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
23832383 const pt = sema.pt;
2384 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{
2384 return sema.fail(block, src, "type '{f}' does not support struct initialization syntax", .{
23852385 ty.fmt(pt),
23862386 });
23872387}
......@@ -2394,7 +2394,7 @@ fn failWithErrorSetCodeMissing(
23942394 src_err_set_ty: Type,
23952395) CompileError {
23962396 const pt = sema.pt;
2397 return sema.fail(block, src, "expected type '{}', found type '{}'", .{
2397 return sema.fail(block, src, "expected type '{f}', found type '{f}'", .{
23982398 dest_err_set_ty.fmt(pt), src_err_set_ty.fmt(pt),
23992399 });
24002400}
......@@ -2402,7 +2402,7 @@ fn failWithErrorSetCodeMissing(
24022402pub fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: ?usize) CompileError {
24032403 const pt = sema.pt;
24042404 return sema.failWithOwnedErrorMsg(block, msg: {
2405 const msg = try sema.errMsg(src, "overflow of integer type '{}' with value '{}'", .{
2405 const msg = try sema.errMsg(src, "overflow of integer type '{f}' with value '{f}'", .{
24062406 int_ty.fmt(pt), val.fmtValueSema(pt, sema),
24072407 });
24082408 errdefer msg.destroy(sema.gpa);
......@@ -2452,7 +2452,7 @@ fn failWithInvalidFieldAccess(
24522452 const child_ty = inner_ty.optionalChild(zcu);
24532453 if (!typeSupportsFieldAccess(zcu, child_ty, field_name)) break :opt;
24542454 const msg = msg: {
2455 const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(pt)});
2455 const msg = try sema.errMsg(src, "optional type '{f}' does not support field access", .{object_ty.fmt(pt)});
24562456 errdefer msg.destroy(sema.gpa);
24572457 try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{});
24582458 break :msg msg;
......@@ -2462,14 +2462,14 @@ fn failWithInvalidFieldAccess(
24622462 const child_ty = inner_ty.errorUnionPayload(zcu);
24632463 if (!typeSupportsFieldAccess(zcu, child_ty, field_name)) break :err;
24642464 const msg = msg: {
2465 const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(pt)});
2465 const msg = try sema.errMsg(src, "error union type '{f}' does not support field access", .{object_ty.fmt(pt)});
24662466 errdefer msg.destroy(sema.gpa);
24672467 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
24682468 break :msg msg;
24692469 };
24702470 return sema.failWithOwnedErrorMsg(block, msg);
24712471 }
2472 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(pt)});
2472 return sema.fail(block, src, "type '{f}' does not support field access", .{object_ty.fmt(pt)});
24732473}
24742474
24752475fn typeSupportsFieldAccess(zcu: *const Zcu, ty: Type, field_name: InternPool.NullTerminatedString) bool {
......@@ -2498,7 +2498,7 @@ fn failWithComptimeErrorRetTrace(
24982498 const pt = sema.pt;
24992499 const zcu = pt.zcu;
25002500 const msg = msg: {
2501 const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&zcu.intern_pool)});
2501 const msg = try sema.errMsg(src, "caught unexpected error '{f}'", .{name.fmt(&zcu.intern_pool)});
25022502 errdefer msg.destroy(sema.gpa);
25032503
25042504 for (sema.comptime_err_ret_trace.items) |src_loc| {
......@@ -3009,7 +3009,7 @@ pub fn createTypeName(
30093009 inst: ?Zir.Inst.Index,
30103010 /// This is used purely to give the type a unique name in the `anon` case.
30113011 type_index: InternPool.Index,
3012) !struct {
3012) CompileError!struct {
30133013 name: InternPool.NullTerminatedString,
30143014 nav: InternPool.Nav.Index.Optional,
30153015} {
......@@ -3028,11 +3028,11 @@ pub fn createTypeName(
30283028 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail);
30293029 const zir_tags = sema.code.instructions.items(.tag);
30303030
3031 var buf: std.ArrayListUnmanaged(u8) = .empty;
3032 defer buf.deinit(gpa);
3033
3034 const writer = buf.writer(gpa);
3035 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});
3031 var aw: std.io.AllocatingWriter = undefined;
3032 aw.init(gpa);
3033 defer aw.deinit();
3034 const bw = &aw.buffered_writer;
3035 bw.print("{f}(", .{block.type_name_ctx.fmt(ip)}) catch |err| return @errorCast(err);
30363036
30373037 var arg_i: usize = 0;
30383038 for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {
......@@ -3045,18 +3045,18 @@ pub fn createTypeName(
30453045 // result in a compile error.
30463046 const arg_val = try sema.resolveValue(arg) orelse break :func_strat; // fall through to anon strat
30473047
3048 if (arg_i != 0) try writer.writeByte(',');
3048 if (arg_i != 0) bw.writeByte(',') catch |err| return @errorCast(err);
30493049
30503050 // Limiting the depth here helps avoid type names getting too long, which
30513051 // in turn helps to avoid unreasonably long symbol names for namespaced
30523052 // symbols. Such names should ideally be human-readable, and additionally,
30533053 // some tooling may not support very long symbol names.
3054 try writer.print("{}", .{Value.fmtValueSemaFull(.{
3054 bw.print("{f}", .{Value.fmtValueSemaFull(.{
30553055 .val = arg_val,
30563056 .pt = pt,
30573057 .opt_sema = sema,
30583058 .depth = 1,
3059 })});
3059 })}) catch |err| return @errorCast(err);
30603060
30613061 arg_i += 1;
30623062 continue;
......@@ -3064,9 +3064,9 @@ pub fn createTypeName(
30643064 else => continue,
30653065 };
30663066
3067 try writer.writeByte(')');
3067 try bw.writeByte(')');
30683068 return .{
3069 .name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls),
3069 .name = try ip.getOrPutString(gpa, pt.tid, aw.getWritten(), .no_embedded_nulls),
30703070 .nav = .none,
30713071 };
30723072 },
......@@ -3078,7 +3078,7 @@ pub fn createTypeName(
30783078 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
30793079 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
30803080 return .{
3081 .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
3081 .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}.{s}", .{
30823082 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
30833083 }, .no_embedded_nulls),
30843084 .nav = .none,
......@@ -3101,7 +3101,7 @@ pub fn createTypeName(
31013101 // that builtin from the language, we can consider this.
31023102
31033103 return .{
3104 .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
3104 .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}__{s}_{d}", .{
31053105 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
31063106 }, .no_embedded_nulls),
31073107 .nav = .none,
......@@ -3585,7 +3585,7 @@ fn ensureResultUsed(
35853585 },
35863586 else => {
35873587 const msg = msg: {
3588 const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(pt)});
3588 const msg = try sema.errMsg(src, "value of type '{f}' ignored", .{ty.fmt(pt)});
35893589 errdefer msg.destroy(sema.gpa);
35903590 try sema.errNote(src, msg, "all non-void values must be used", .{});
35913591 try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});
......@@ -3855,7 +3855,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
38553855 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.
38563856 // TODO: source location of runtime control flow
38573857 const init_src = block.src(.{ .node_offset_var_decl_init = inst_data.src_node });
3858 return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(pt)});
3858 return sema.fail(block, init_src, "value with comptime-only type '{f}' depends on runtime control flow", .{elem_ty.fmt(pt)});
38593859 }
38603860
38613861 // This is a runtime value.
......@@ -4352,7 +4352,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
43524352 // The alloc wasn't comptime-known per the above logic, so the
43534353 // type cannot be comptime-only.
43544354 // TODO: source location of runtime control flow
4355 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});
4355 return sema.fail(block, src, "value with comptime-only type '{f}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});
43564356 }
43574357 if (sema.func_is_naked and try final_elem_ty.hasRuntimeBitsSema(pt)) {
43584358 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
......@@ -4449,7 +4449,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
44494449 if (!object_ty.isIndexable(zcu)) {
44504450 // Instead of using checkIndexable we customize this error.
44514451 const msg = msg: {
4452 const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(pt)});
4452 const msg = try sema.errMsg(arg_src, "type '{f}' is not indexable and not a range", .{object_ty.fmt(pt)});
44534453 errdefer msg.destroy(sema.gpa);
44544454 try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});
44554455
......@@ -4484,10 +4484,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
44844484 .for_node_offset = inst_data.src_node,
44854485 .input_index = len_idx,
44864486 } });
4487 try sema.errNote(a_src, msg, "length {} here", .{
4487 try sema.errNote(a_src, msg, "length {f} here", .{
44884488 v.fmtValueSema(pt, sema),
44894489 });
4490 try sema.errNote(arg_src, msg, "length {} here", .{
4490 try sema.errNote(arg_src, msg, "length {f} here", .{
44914491 arg_val.fmtValueSema(pt, sema),
44924492 });
44934493 break :msg msg;
......@@ -4519,7 +4519,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
45194519 .for_node_offset = inst_data.src_node,
45204520 .input_index = i,
45214521 } });
4522 try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{
4522 try sema.errNote(arg_src, msg, "type '{f}' has no upper bound", .{
45234523 object_ty.fmt(pt),
45244524 });
45254525 }
......@@ -4595,7 +4595,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
45954595 switch (val_ty.zigTypeTag(zcu)) {
45964596 .array, .vector => {},
45974597 else => if (!val_ty.isTuple(zcu)) {
4598 return sema.fail(block, src, "expected array of '{}', found '{}'", .{ elem_ty.fmt(pt), val_ty.fmt(pt) });
4598 return sema.fail(block, src, "expected array of '{f}', found '{f}'", .{ elem_ty.fmt(pt), val_ty.fmt(pt) });
45994599 },
46004600 }
46014601 const want_ty = try pt.arrayType(.{
......@@ -4669,7 +4669,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
46694669 const ty_operand = try sema.resolveTypeOrPoison(block, src, un_tok.operand) orelse return;
46704670 if (ty_operand.optEuBaseType(zcu).zigTypeTag(zcu) != .pointer) {
46714671 return sema.failWithOwnedErrorMsg(block, msg: {
4672 const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(pt)});
4672 const msg = try sema.errMsg(src, "expected type '{f}', found pointer", .{ty_operand.fmt(pt)});
46734673 errdefer msg.destroy(sema.gpa);
46744674 try sema.errNote(src, msg, "address-of operator always returns a pointer", .{});
46754675 break :msg msg;
......@@ -5078,7 +5078,7 @@ fn validateStructInit(
50785078 }
50795079 continue;
50805080 };
5081 const template = "missing struct field: {}";
5081 const template = "missing struct field: {f}";
50825082 const args = .{field_name.fmt(ip)};
50835083 if (root_msg) |msg| {
50845084 try sema.errNote(init_src, msg, template, args);
......@@ -5208,7 +5208,7 @@ fn validateStructInit(
52085208 }
52095209 continue;
52105210 };
5211 const template = "missing struct field: {}";
5211 const template = "missing struct field: {f}";
52125212 const args = .{field_name.fmt(ip)};
52135213 if (root_msg) |msg| {
52145214 try sema.errNote(init_src, msg, template, args);
......@@ -5512,11 +5512,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
55125512 const operand_ty = sema.typeOf(operand);
55135513
55145514 if (operand_ty.zigTypeTag(zcu) != .pointer) {
5515 return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(pt)});
5515 return sema.fail(block, src, "cannot dereference non-pointer type '{f}'", .{operand_ty.fmt(pt)});
55165516 } else switch (operand_ty.ptrSize(zcu)) {
55175517 .one, .c => {},
5518 .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(pt)}),
5519 .slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(pt)}),
5518 .many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{f}'", .{operand_ty.fmt(pt)}),
5519 .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{operand_ty.fmt(pt)}),
55205520 }
55215521
55225522 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(zcu))) != null) {
......@@ -5533,7 +5533,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
55335533 const msg = msg: {
55345534 const msg = try sema.errMsg(
55355535 src,
5536 "values of type '{}' must be comptime-known, but operand value is runtime-known",
5536 "values of type '{f}' must be comptime-known, but operand value is runtime-known",
55375537 .{elem_ty.fmt(pt)},
55385538 );
55395539 errdefer msg.destroy(sema.gpa);
......@@ -5565,7 +5565,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
55655565
55665566 if (!typeIsDestructurable(operand_ty, zcu)) {
55675567 return sema.failWithOwnedErrorMsg(block, msg: {
5568 const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(pt)});
5568 const msg = try sema.errMsg(src, "type '{f}' cannot be destructured", .{operand_ty.fmt(pt)});
55695569 errdefer msg.destroy(sema.gpa);
55705570 try sema.errNote(destructure_src, msg, "result destructured here", .{});
55715571 if (operand_ty.zigTypeTag(pt.zcu) == .error_union) {
......@@ -5608,12 +5608,12 @@ fn failWithBadMemberAccess(
56085608 else => unreachable,
56095609 };
56105610 if (agg_ty.typeDeclInst(zcu)) |inst| if ((inst.resolve(ip) orelse return error.AnalysisFail) == .main_struct_inst) {
5611 return sema.fail(block, field_src, "root source file struct '{}' has no member named '{}'", .{
5611 return sema.fail(block, field_src, "root source file struct '{f}' has no member named '{f}'", .{
56125612 agg_ty.fmt(pt), field_name.fmt(ip),
56135613 });
56145614 };
56155615
5616 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5616 return sema.fail(block, field_src, "{s} '{f}' has no member named '{f}'", .{
56175617 kw_name, agg_ty.fmt(pt), field_name.fmt(ip),
56185618 });
56195619}
......@@ -5633,7 +5633,7 @@ fn failWithBadStructFieldAccess(
56335633 const msg = msg: {
56345634 const msg = try sema.errMsg(
56355635 field_src,
5636 "no field named '{}' in struct '{}'",
5636 "no field named '{f}' in struct '{f}'",
56375637 .{ field_name.fmt(ip), struct_type.name.fmt(ip) },
56385638 );
56395639 errdefer msg.destroy(sema.gpa);
......@@ -5659,7 +5659,7 @@ fn failWithBadUnionFieldAccess(
56595659 const msg = msg: {
56605660 const msg = try sema.errMsg(
56615661 field_src,
5662 "no field named '{}' in union '{}'",
5662 "no field named '{f}' in union '{f}'",
56635663 .{ field_name.fmt(ip), union_obj.name.fmt(ip) },
56645664 );
56655665 errdefer msg.destroy(gpa);
......@@ -5911,30 +5911,30 @@ fn zirCompileLog(
59115911 const zcu = pt.zcu;
59125912 const gpa = zcu.gpa;
59135913
5914 var buf: std.ArrayListUnmanaged(u8) = .empty;
5915 defer buf.deinit(gpa);
5916
5917 const writer = buf.writer(gpa);
5914 var aw: std.io.AllocatingWriter = undefined;
5915 const bw = aw.init(sema.gpa);
5916 defer aw.deinit();
59185917
59195918 const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
59205919 const src_node = extra.data.src_node;
59215920 const args = sema.code.refSlice(extra.end, extended.small);
59225921
59235922 for (args, 0..) |arg_ref, i| {
5924 if (i != 0) try writer.print(", ", .{});
5923 if (i != 0) bw.writeAll(", ") catch |err| return @errorCast(err);
59255924
59265925 const arg = try sema.resolveInst(arg_ref);
59275926 const arg_ty = sema.typeOf(arg);
59285927 if (try sema.resolveValueResolveLazy(arg)) |val| {
5929 try writer.print("@as({}, {})", .{
5928 bw.print("@as({f}, {f})", .{
59305929 arg_ty.fmt(pt), val.fmtValueSema(pt, sema),
5931 });
5930 }) catch |err| return @errorCast(err);
59325931 } else {
5933 try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(pt)});
5932 bw.print("@as({f}, [runtime value])", .{arg_ty.fmt(pt)}) catch |err| return @errorCast(err);
59345933 }
59355934 }
5935 try bw.print("\n", .{});
59365936
5937 const line_data = try zcu.intern_pool.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
5937 const line_data = try zcu.intern_pool.getOrPutString(gpa, pt.tid, aw.getWritten(), .no_embedded_nulls);
59385938
59395939 const line_idx: Zcu.CompileLogLine.Index = if (zcu.free_compile_log_lines.pop()) |idx| idx: {
59405940 zcu.compile_log_lines.items[@intFromEnum(idx)] = .{
......@@ -6476,7 +6476,7 @@ fn resolveAnalyzedBlock(
64766476 const type_src = src; // TODO: better source location
64776477 if (try resolved_ty.comptimeOnlySema(pt)) {
64786478 const msg = msg: {
6479 const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(pt)});
6479 const msg = try sema.errMsg(type_src, "value with comptime-only type '{f}' depends on runtime control flow", .{resolved_ty.fmt(pt)});
64806480 errdefer msg.destroy(sema.gpa);
64816481
64826482 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
......@@ -6592,7 +6592,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
65926592
65936593 {
65946594 if (ptr_ty.zigTypeTag(zcu) != .pointer) {
6595 return sema.fail(block, ptr_src, "expected pointer type, found '{}'", .{ptr_ty.fmt(pt)});
6595 return sema.fail(block, ptr_src, "expected pointer type, found '{f}'", .{ptr_ty.fmt(pt)});
65966596 }
65976597 const ptr_ty_info = ptr_ty.ptrInfo(zcu);
65986598 if (ptr_ty_info.flags.size == .slice) {
......@@ -6615,7 +6615,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
66156615 const export_ty = Value.fromInterned(uav.val).typeOf(zcu);
66166616 if (!try sema.validateExternType(export_ty, .other)) {
66176617 return sema.failWithOwnedErrorMsg(block, msg: {
6618 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
6618 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
66196619 errdefer msg.destroy(sema.gpa);
66206620 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
66216621 try sema.addDeclaredHereNote(msg, export_ty);
......@@ -6667,7 +6667,7 @@ pub fn analyzeExport(
66676667
66686668 if (!try sema.validateExternType(export_ty, .other)) {
66696669 return sema.failWithOwnedErrorMsg(block, msg: {
6670 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
6670 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
66716671 errdefer msg.destroy(gpa);
66726672
66736673 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
......@@ -7363,7 +7363,7 @@ fn checkCallArgumentCount(
73637363 opt_child.childType(zcu).zigTypeTag(zcu) == .@"fn"))
73647364 {
73657365 const msg = msg: {
7366 const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{
7366 const msg = try sema.errMsg(func_src, "cannot call optional type '{f}'", .{
73677367 callee_ty.fmt(pt),
73687368 });
73697369 errdefer msg.destroy(sema.gpa);
......@@ -7375,7 +7375,7 @@ fn checkCallArgumentCount(
73757375 },
73767376 else => {},
73777377 }
7378 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(pt)});
7378 return sema.fail(block, func_src, "type '{f}' not a function", .{callee_ty.fmt(pt)});
73797379 };
73807380
73817381 const func_ty_info = zcu.typeToFunc(func_ty).?;
......@@ -7438,7 +7438,7 @@ fn callBuiltin(
74387438 },
74397439 else => {},
74407440 }
7441 std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(pt)});
7441 std.debug.panic("type '{f}' is not a function calling builtin fn", .{callee_ty.fmt(pt)});
74427442 };
74437443
74447444 const func_ty_info = zcu.typeToFunc(func_ty).?;
......@@ -7826,7 +7826,7 @@ fn analyzeCall(
78267826
78277827 if (!param_ty.isValidParamType(zcu)) {
78287828 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
7829 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
7829 return sema.fail(block, param_src, "parameter of {s}type '{f}' not allowed", .{
78307830 opaque_str, param_ty.fmt(pt),
78317831 });
78327832 }
......@@ -7923,7 +7923,7 @@ fn analyzeCall(
79237923
79247924 if (!full_ty.isValidReturnType(zcu)) {
79257925 const opaque_str = if (full_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
7926 return sema.fail(block, func_ret_ty_src, "{s}return type '{}' not allowed", .{
7926 return sema.fail(block, func_ret_ty_src, "{s}return type '{f}' not allowed", .{
79277927 opaque_str, full_ty.fmt(pt),
79287928 });
79297929 }
......@@ -8382,7 +8382,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ
83828382 }
83838383 const owner_func_ty: Type = .fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty);
83848384 if (owner_func_ty.toIntern() != func_ty.toIntern()) {
8385 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
8385 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{f}' does not match type of calling function '{f}'", .{
83868386 func_ty.fmt(pt), owner_func_ty.fmt(pt),
83878387 });
83888388 }
......@@ -8406,9 +8406,9 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
84068406 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
84078407 const child_type = try sema.resolveType(block, operand_src, inst_data.operand);
84088408 if (child_type.zigTypeTag(zcu) == .@"opaque") {
8409 return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(pt)});
8409 return sema.fail(block, operand_src, "opaque type '{f}' cannot be optional", .{child_type.fmt(pt)});
84108410 } else if (child_type.zigTypeTag(zcu) == .null) {
8411 return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(pt)});
8411 return sema.fail(block, operand_src, "type '{f}' cannot be optional", .{child_type.fmt(pt)});
84128412 }
84138413 const opt_type = try pt.optionalType(child_type.toIntern());
84148414
......@@ -8469,7 +8469,7 @@ fn zirVecArrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
84698469 const vec_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, un_node.operand) orelse return .generic_poison_type;
84708470 switch (vec_ty.zigTypeTag(zcu)) {
84718471 .array, .vector => {},
8472 else => return sema.fail(block, block.nodeOffset(un_node.src_node), "expected array or vector type, found '{}'", .{vec_ty.fmt(pt)}),
8472 else => return sema.fail(block, block.nodeOffset(un_node.src_node), "expected array or vector type, found '{f}'", .{vec_ty.fmt(pt)}),
84738473 }
84748474 return Air.internedToRef(vec_ty.childType(zcu).toIntern());
84758475}
......@@ -8537,7 +8537,7 @@ fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src:
85378537 const pt = sema.pt;
85388538 const zcu = pt.zcu;
85398539 if (elem_type.zigTypeTag(zcu) == .@"opaque") {
8540 return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(pt)});
8540 return sema.fail(block, elem_src, "array of opaque type '{f}' not allowed", .{elem_type.fmt(pt)});
85418541 } else if (elem_type.zigTypeTag(zcu) == .noreturn) {
85428542 return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{});
85438543 }
......@@ -8573,7 +8573,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
85738573 const payload = try sema.resolveType(block, rhs_src, extra.rhs);
85748574
85758575 if (error_set.zigTypeTag(zcu) != .error_set) {
8576 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{
8576 return sema.fail(block, lhs_src, "expected error set type, found '{f}'", .{
85778577 error_set.fmt(pt),
85788578 });
85798579 }
......@@ -8586,11 +8586,11 @@ fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, p
85868586 const pt = sema.pt;
85878587 const zcu = pt.zcu;
85888588 if (payload_ty.zigTypeTag(zcu) == .@"opaque") {
8589 return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{
8589 return sema.fail(block, payload_src, "error union with payload of opaque type '{f}' not allowed", .{
85908590 payload_ty.fmt(pt),
85918591 });
85928592 } else if (payload_ty.zigTypeTag(zcu) == .error_set) {
8593 return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{
8593 return sema.fail(block, payload_src, "error union with payload of error set type '{f}' not allowed", .{
85948594 payload_ty.fmt(pt),
85958595 });
85968596 }
......@@ -8728,9 +8728,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
87288728 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
87298729 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
87308730 if (lhs_ty.zigTypeTag(zcu) != .error_set)
8731 return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(pt)});
8731 return sema.fail(block, lhs_src, "expected error set type, found '{f}'", .{lhs_ty.fmt(pt)});
87328732 if (rhs_ty.zigTypeTag(zcu) != .error_set)
8733 return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(pt)});
8733 return sema.fail(block, rhs_src, "expected error set type, found '{f}'", .{rhs_ty.fmt(pt)});
87348734
87358735 // Anything merged with anyerror is anyerror.
87368736 if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) {
......@@ -8840,7 +8840,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88408840 return sema.fail(
88418841 block,
88428842 operand_src,
8843 "untagged union '{}' cannot be converted to integer",
8843 "untagged union '{f}' cannot be converted to integer",
88448844 .{operand_ty.fmt(pt)},
88458845 );
88468846 };
......@@ -8848,7 +8848,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88488848 break :blk try sema.unionToTag(block, tag_ty, operand, operand_src);
88498849 },
88508850 else => {
8851 return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{
8851 return sema.fail(block, operand_src, "expected enum or tagged union, found '{f}'", .{
88528852 operand_ty.fmt(pt),
88538853 });
88548854 },
......@@ -8859,7 +8859,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88598859 // TODO: use correct solution
88608860 // https://github.com/ziglang/zig/issues/15909
88618861 if (enum_tag_ty.enumFieldCount(zcu) == 0 and !enum_tag_ty.isNonexhaustiveEnum(zcu)) {
8862 return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{}'", .{
8862 return sema.fail(block, operand_src, "cannot use @intFromEnum on empty enum '{f}'", .{
88638863 enum_tag_ty.fmt(pt),
88648864 });
88658865 }
......@@ -8893,7 +8893,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
88938893 const operand_ty = sema.typeOf(operand);
88948894
88958895 if (dest_ty.zigTypeTag(zcu) != .@"enum") {
8896 return sema.fail(block, src, "expected enum, found '{}'", .{dest_ty.fmt(pt)});
8896 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});
88978897 }
88988898 _ = try sema.checkIntType(block, operand_src, operand_ty);
88998899
......@@ -8903,7 +8903,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89038903 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
89048904 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
89058905 }
8906 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
8906 return sema.fail(block, src, "int value '{f}' out of range of non-exhaustive enum '{f}'", .{
89078907 int_val.fmtValueSema(pt, sema), dest_ty.fmt(pt),
89088908 });
89098909 }
......@@ -8911,7 +8911,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
89118911 return sema.failWithUseOfUndef(block, operand_src);
89128912 }
89138913 if (!(try sema.enumHasInt(dest_ty, int_val))) {
8914 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
8914 return sema.fail(block, src, "enum '{f}' has no tag with value '{f}'", .{
89158915 dest_ty.fmt(pt), int_val.fmtValueSema(pt, sema),
89168916 });
89178917 }
......@@ -9105,7 +9105,7 @@ fn zirErrUnionPayload(
91059105 const operand_src = src;
91069106 const err_union_ty = sema.typeOf(operand);
91079107 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
9108 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
9108 return sema.fail(block, operand_src, "expected error union type, found '{f}'", .{
91099109 err_union_ty.fmt(pt),
91109110 });
91119111 }
......@@ -9173,7 +9173,7 @@ fn analyzeErrUnionPayloadPtr(
91739173 assert(operand_ty.zigTypeTag(zcu) == .pointer);
91749174
91759175 if (operand_ty.childType(zcu).zigTypeTag(zcu) != .error_union) {
9176 return sema.fail(block, src, "expected error union type, found '{}'", .{
9176 return sema.fail(block, src, "expected error union type, found '{f}'", .{
91779177 operand_ty.childType(zcu).fmt(pt),
91789178 });
91799179 }
......@@ -9250,7 +9250,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air
92509250 const zcu = pt.zcu;
92519251 const operand_ty = sema.typeOf(operand);
92529252 if (operand_ty.zigTypeTag(zcu) != .error_union) {
9253 return sema.fail(block, src, "expected error union type, found '{}'", .{
9253 return sema.fail(block, src, "expected error union type, found '{f}'", .{
92549254 operand_ty.fmt(pt),
92559255 });
92569256 }
......@@ -9286,7 +9286,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand:
92869286 assert(operand_ty.zigTypeTag(zcu) == .pointer);
92879287
92889288 if (operand_ty.childType(zcu).zigTypeTag(zcu) != .error_union) {
9289 return sema.fail(block, src, "expected error union type, found '{}'", .{
9289 return sema.fail(block, src, "expected error union type, found '{f}'", .{
92909290 operand_ty.childType(zcu).fmt(pt),
92919291 });
92929292 }
......@@ -9544,19 +9544,18 @@ fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention.Tag) bool {
95449544fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention.Tag) CompileError!void {
95459545 const CallingConventionsSupportingVarArgsList = struct {
95469546 arch: std.Target.Cpu.Arch,
9547 pub fn format(ctx: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
9547 pub fn format(ctx: @This(), bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
95489548 _ = fmt;
9549 _ = options;
95509549 var first = true;
95519550 for (calling_conventions_supporting_var_args) |cc_inner| {
95529551 for (std.Target.Cpu.Arch.fromCallingConvention(cc_inner)) |supported_arch| {
95539552 if (supported_arch == ctx.arch) break;
95549553 } else continue; // callconv not supported by this arch
95559554 if (!first) {
9556 try writer.writeAll(", ");
9555 try bw.writeAll(", ");
95579556 }
95589557 first = false;
9559 try writer.print("'{s}'", .{@tagName(cc_inner)});
9558 try bw.print("'{s}'", .{@tagName(cc_inner)});
95609559 }
95619560 }
95629561 };
......@@ -9566,7 +9565,7 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:
95669565 const msg = try sema.errMsg(src, "variadic function does not support '{s}' calling convention", .{@tagName(cc)});
95679566 errdefer msg.destroy(sema.gpa);
95689567 const target = sema.pt.zcu.getTarget();
9569 try sema.errNote(src, msg, "supported calling conventions: {}", .{CallingConventionsSupportingVarArgsList{ .arch = target.cpu.arch }});
9568 try sema.errNote(src, msg, "supported calling conventions: {f}", .{CallingConventionsSupportingVarArgsList{ .arch = target.cpu.arch }});
95709569 break :msg msg;
95719570 });
95729571 }
......@@ -9614,7 +9613,7 @@ fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type)
96149613 }
96159614
96169615 return sema.failWithOwnedErrorMsg(block, msg: {
9617 const msg = try sema.errMsg(src, "value with non-mergable pointer type '{}' depends on runtime control flow", .{peer_ty.fmt(pt)});
9616 const msg = try sema.errMsg(src, "value with non-mergable pointer type '{f}' depends on runtime control flow", .{peer_ty.fmt(pt)});
96189617 errdefer msg.destroy(sema.gpa);
96199618
96209619 const runtime_src = block.runtime_cond orelse block.runtime_loop.?;
......@@ -9692,13 +9691,13 @@ fn funcCommon(
96929691 }
96939692 if (!param_ty.isValidParamType(zcu)) {
96949693 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
9695 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
9694 return sema.fail(block, param_src, "parameter of {s}type '{f}' not allowed", .{
96969695 opaque_str, param_ty.fmt(pt),
96979696 });
96989697 }
96999698 if (!param_ty_generic and !target_util.fnCallConvAllowsZigTypes(cc) and !try sema.validateExternType(param_ty, .param_ty)) {
97009699 const msg = msg: {
9701 const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
9700 const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{
97029701 param_ty.fmt(pt), @tagName(cc),
97039702 });
97049703 errdefer msg.destroy(sema.gpa);
......@@ -9712,7 +9711,7 @@ fn funcCommon(
97129711 }
97139712 if (param_ty_comptime and !param_is_comptime and has_body and !block.isComptime()) {
97149713 const msg = msg: {
9715 const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{
9714 const msg = try sema.errMsg(param_src, "parameter of type '{f}' must be declared comptime", .{
97169715 param_ty.fmt(pt),
97179716 });
97189717 errdefer msg.destroy(sema.gpa);
......@@ -9892,7 +9891,7 @@ fn finishFunc(
98929891
98939892 if (!return_type.isValidReturnType(zcu)) {
98949893 const opaque_str = if (return_type.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
9895 return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{
9894 return sema.fail(block, ret_ty_src, "{s}return type '{f}' not allowed", .{
98969895 opaque_str, return_type.fmt(pt),
98979896 });
98989897 }
......@@ -9900,7 +9899,7 @@ fn finishFunc(
99009899 !try sema.validateExternType(return_type, .ret_ty))
99019900 {
99029901 const msg = msg: {
9903 const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
9902 const msg = try sema.errMsg(ret_ty_src, "return type '{f}' not allowed in function with calling convention '{s}'", .{
99049903 return_type.fmt(pt), @tagName(cc_resolved),
99059904 });
99069905 errdefer msg.destroy(gpa);
......@@ -9922,7 +9921,7 @@ fn finishFunc(
99229921
99239922 const msg = try sema.errMsg(
99249923 ret_ty_src,
9925 "function with comptime-only return type '{}' requires all parameters to be comptime",
9924 "function with comptime-only return type '{f}' requires all parameters to be comptime",
99269925 .{return_type.fmt(pt)},
99279926 );
99289927 errdefer msg.destroy(sema.gpa);
......@@ -9991,17 +9990,16 @@ fn finishFunc(
99919990 .bad_arch => |allowed_archs| {
99929991 const ArchListFormatter = struct {
99939992 archs: []const std.Target.Cpu.Arch,
9994 pub fn format(formatter: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
9993 pub fn format(formatter: @This(), bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
99959994 _ = fmt;
9996 _ = options;
99979995 for (formatter.archs, 0..) |arch, i| {
99989996 if (i != 0)
9999 try writer.writeAll(", ");
10000 try writer.print("'{s}'", .{@tagName(arch)});
9997 try bw.writeAll(", ");
9998 try bw.print("'{s}'", .{@tagName(arch)});
100019999 }
1000210000 }
1000310001 };
10004 return sema.fail(block, cc_src, "calling convention '{s}' only available on architectures {}", .{
10002 return sema.fail(block, cc_src, "calling convention '{s}' only available on architectures {f}", .{
1000510003 @tagName(cc_resolved),
1000610004 ArchListFormatter{ .archs = allowed_archs },
1000710005 });
......@@ -10102,7 +10100,7 @@ fn analyzeAs(
1010210100 const operand = try sema.resolveInst(zir_operand);
1010310101 const dest_ty = try sema.resolveTypeOrPoison(block, src, zir_dest_type) orelse return operand;
1010410102 switch (dest_ty.zigTypeTag(zcu)) {
10105 .@"opaque" => return sema.fail(block, src, "cannot cast to opaque type '{}'", .{dest_ty.fmt(pt)}),
10103 .@"opaque" => return sema.fail(block, src, "cannot cast to opaque type '{f}'", .{dest_ty.fmt(pt)}),
1010610104 .noreturn => return sema.fail(block, src, "cannot cast to noreturn", .{}),
1010710105 else => {},
1010810106 }
......@@ -10130,12 +10128,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1013010128 const ptr_ty = operand_ty.scalarType(zcu);
1013110129 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
1013210130 if (!ptr_ty.isPtrAtRuntime(zcu)) {
10133 return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)});
10131 return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)});
1013410132 }
1013510133 const pointee_ty = ptr_ty.childType(zcu);
1013610134 if (try ptr_ty.comptimeOnlySema(pt)) {
1013710135 const msg = msg: {
10138 const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(pt)});
10136 const msg = try sema.errMsg(ptr_src, "comptime-only type '{f}' has no pointer address", .{pointee_ty.fmt(pt)});
1013910137 errdefer msg.destroy(sema.gpa);
1014010138 try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);
1014110139 break :msg msg;
......@@ -10383,14 +10381,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1038310381 .type,
1038410382 .undefined,
1038510383 .void,
10386 => return sema.fail(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)}),
10384 => return sema.fail(block, src, "cannot @bitCast to '{f}'", .{dest_ty.fmt(pt)}),
1038710385
1038810386 .@"enum" => {
1038910387 const msg = msg: {
10390 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)});
10388 const msg = try sema.errMsg(src, "cannot @bitCast to '{f}'", .{dest_ty.fmt(pt)});
1039110389 errdefer msg.destroy(sema.gpa);
1039210390 switch (operand_ty.zigTypeTag(zcu)) {
10393 .int, .comptime_int => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(pt)}),
10391 .int, .comptime_int => try sema.errNote(src, msg, "use @enumFromInt to cast from '{f}'", .{operand_ty.fmt(pt)}),
1039410392 else => {},
1039510393 }
1039610394
......@@ -10401,11 +10399,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1040110399
1040210400 .pointer => {
1040310401 const msg = msg: {
10404 const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(pt)});
10402 const msg = try sema.errMsg(src, "cannot @bitCast to '{f}'", .{dest_ty.fmt(pt)});
1040510403 errdefer msg.destroy(sema.gpa);
1040610404 switch (operand_ty.zigTypeTag(zcu)) {
10407 .int, .comptime_int => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(pt)}),
10408 .pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(pt)}),
10405 .int, .comptime_int => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{f}'", .{operand_ty.fmt(pt)}),
10406 .pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{f}'", .{operand_ty.fmt(pt)}),
1040910407 else => {},
1041010408 }
1041110409
......@@ -10419,7 +10417,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1041910417 .@"union" => "union",
1042010418 else => unreachable,
1042110419 };
10422 return sema.fail(block, src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{
10420 return sema.fail(block, src, "cannot @bitCast to '{f}'; {s} does not have a guaranteed in-memory layout", .{
1042310421 dest_ty.fmt(pt), container,
1042410422 });
1042510423 },
......@@ -10447,14 +10445,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1044710445 .type,
1044810446 .undefined,
1044910447 .void,
10450 => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)}),
10448 => return sema.fail(block, operand_src, "cannot @bitCast from '{f}'", .{operand_ty.fmt(pt)}),
1045110449
1045210450 .@"enum" => {
1045310451 const msg = msg: {
10454 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)});
10452 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{f}'", .{operand_ty.fmt(pt)});
1045510453 errdefer msg.destroy(sema.gpa);
1045610454 switch (dest_ty.zigTypeTag(zcu)) {
10457 .int, .comptime_int => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(pt)}),
10455 .int, .comptime_int => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{f}'", .{dest_ty.fmt(pt)}),
1045810456 else => {},
1045910457 }
1046010458
......@@ -10464,11 +10462,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1046410462 },
1046510463 .pointer => {
1046610464 const msg = msg: {
10467 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(pt)});
10465 const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{f}'", .{operand_ty.fmt(pt)});
1046810466 errdefer msg.destroy(sema.gpa);
1046910467 switch (dest_ty.zigTypeTag(zcu)) {
10470 .int, .comptime_int => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(pt)}),
10471 .pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(pt)}),
10468 .int, .comptime_int => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{f}'", .{dest_ty.fmt(pt)}),
10469 .pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{f}'", .{dest_ty.fmt(pt)}),
1047210470 else => {},
1047310471 }
1047410472
......@@ -10482,7 +10480,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1048210480 .@"union" => "union",
1048310481 else => unreachable,
1048410482 };
10485 return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{
10483 return sema.fail(block, operand_src, "cannot @bitCast from '{f}'; {s} does not have a guaranteed in-memory layout", .{
1048610484 operand_ty.fmt(pt), container,
1048710485 });
1048810486 },
......@@ -10525,7 +10523,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1052510523 else => return sema.fail(
1052610524 block,
1052710525 src,
10528 "expected float or vector type, found '{}'",
10526 "expected float or vector type, found '{f}'",
1052910527 .{dest_ty.fmt(pt)},
1053010528 ),
1053110529 };
......@@ -10535,7 +10533,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1053510533 else => return sema.fail(
1053610534 block,
1053710535 operand_src,
10538 "expected float or vector type, found '{}'",
10536 "expected float or vector type, found '{f}'",
1053910537 .{operand_ty.fmt(pt)},
1054010538 ),
1054110539 }
......@@ -10619,7 +10617,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1061910617 if (indexable_ty.zigTypeTag(zcu) != .pointer) {
1062010618 const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });
1062110619 const msg = msg: {
10622 const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{
10620 const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{f}'", .{
1062310621 indexable_ty.fmt(pt),
1062410622 });
1062510623 errdefer msg.destroy(sema.gpa);
......@@ -10761,7 +10759,7 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1076110759 const lhs_ptr_ty = sema.typeOf(try sema.resolveInst(inst_data.operand));
1076210760 const lhs_ty = switch (lhs_ptr_ty.zigTypeTag(zcu)) {
1076310761 .pointer => lhs_ptr_ty.childType(zcu),
10764 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{lhs_ptr_ty.fmt(pt)}),
10762 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{lhs_ptr_ty.fmt(pt)}),
1076510763 };
1076610764
1076710765 const sentinel_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) {
......@@ -10776,7 +10774,7 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1077610774 };
1077710775 },
1077810776 },
10779 else => return sema.fail(block, src, "slice of non-array type '{}'", .{lhs_ty.fmt(pt)}),
10777 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{lhs_ty.fmt(pt)}),
1078010778 };
1078110779
1078210780 return Air.internedToRef(sentinel_ty.toIntern());
......@@ -10971,7 +10969,7 @@ const SwitchProngAnalysis = struct {
1097110969 .base_node_inst = capture_src.base_node_inst,
1097210970 .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },
1097310971 };
10974 return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{
10972 return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{f}'", .{
1097510973 operand_ty.fmt(pt),
1097610974 });
1097710975 }
......@@ -11403,7 +11401,7 @@ fn switchCond(
1140311401 .@"enum",
1140411402 => {
1140511403 if (operand_ty.isSlice(zcu)) {
11406 return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)});
11404 return sema.fail(block, src, "switch on type '{f}'", .{operand_ty.fmt(pt)});
1140711405 }
1140811406 if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| {
1140911407 return Air.internedToRef(opv.toIntern());
......@@ -11438,7 +11436,7 @@ fn switchCond(
1143811436 .vector,
1143911437 .frame,
1144011438 .@"anyframe",
11441 => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(pt)}),
11439 => return sema.fail(block, src, "switch on type '{f}'", .{operand_ty.fmt(pt)}),
1144211440 }
1144311441}
1144411442
......@@ -11539,7 +11537,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1153911537 operand_ty;
1154011538
1154111539 if (operand_err_set.zigTypeTag(zcu) != .error_union) {
11542 return sema.fail(block, switch_src, "expected error union type, found '{}'", .{
11540 return sema.fail(block, switch_src, "expected error union type, found '{f}'", .{
1154311541 operand_ty.fmt(pt),
1154411542 });
1154511543 }
......@@ -11793,7 +11791,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1179311791 // Even if the operand is comptime-known, this `switch` is runtime.
1179411792 if (try operand_ty.comptimeOnlySema(pt)) {
1179511793 return sema.failWithOwnedErrorMsg(block, msg: {
11796 const msg = try sema.errMsg(operand_src, "operand of switch loop has comptime-only type '{}'", .{operand_ty.fmt(pt)});
11794 const msg = try sema.errMsg(operand_src, "operand of switch loop has comptime-only type '{f}'", .{operand_ty.fmt(pt)});
1179711795 errdefer msg.destroy(gpa);
1179811796 try sema.errNote(operand_src, msg, "switch loops are evaluated at runtime outside of comptime scopes", .{});
1179911797 break :msg msg;
......@@ -12017,14 +12015,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1201712015 cond_ty,
1201812016 i,
1201912017 msg,
12020 "unhandled enumeration value: '{}'",
12018 "unhandled enumeration value: '{f}'",
1202112019 .{field_name.fmt(&zcu.intern_pool)},
1202212020 );
1202312021 }
1202412022 try sema.errNote(
1202512023 cond_ty.srcLoc(zcu),
1202612024 msg,
12027 "enum '{}' declared here",
12025 "enum '{f}' declared here",
1202812026 .{cond_ty.fmt(pt)},
1202912027 );
1203012028 break :msg msg;
......@@ -12236,7 +12234,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1223612234 return sema.fail(
1223712235 block,
1223812236 src,
12239 "else prong required when switching on type '{}'",
12237 "else prong required when switching on type '{f}'",
1224012238 .{cond_ty.fmt(pt)},
1224112239 );
1224212240 }
......@@ -12312,7 +12310,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
1231212310 .@"anyframe",
1231312311 .comptime_float,
1231412312 .float,
12315 => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{
12313 => return sema.fail(block, operand_src, "invalid switch operand type '{f}'", .{
1231612314 raw_operand_ty.fmt(pt),
1231712315 }),
1231812316 }
......@@ -12841,7 +12839,7 @@ fn analyzeSwitchRuntimeBlock(
1284112839 if (special.is_inline) switch (operand_ty.zigTypeTag(zcu)) {
1284212840 .@"enum" => {
1284312841 if (operand_ty.isNonexhaustiveEnum(zcu) and !union_originally) {
12844 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12842 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{f}' for 'inline else'", .{
1284512843 operand_ty.fmt(pt),
1284612844 });
1284712845 }
......@@ -12897,7 +12895,7 @@ fn analyzeSwitchRuntimeBlock(
1289712895 },
1289812896 .error_set => {
1289912897 if (operand_ty.isAnyError(zcu)) {
12900 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
12898 return sema.fail(block, special_prong_src, "cannot enumerate values of type '{f}' for 'inline else'", .{
1290112899 operand_ty.fmt(pt),
1290212900 });
1290312901 }
......@@ -13058,7 +13056,7 @@ fn analyzeSwitchRuntimeBlock(
1305813056 cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items));
1305913057 }
1306013058 },
13061 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{}' for 'inline else'", .{
13059 else => return sema.fail(block, special_prong_src, "cannot enumerate values of type '{f}' for 'inline else'", .{
1306213060 operand_ty.fmt(pt),
1306313061 }),
1306413062 };
......@@ -13572,7 +13570,7 @@ fn validateErrSetSwitch(
1357213570 try sema.errNote(
1357313571 src,
1357413572 msg,
13575 "unhandled error value: 'error.{}'",
13573 "unhandled error value: 'error.{f}'",
1357613574 .{error_name.fmt(ip)},
1357713575 );
1357813576 }
......@@ -13798,7 +13796,7 @@ fn validateSwitchNoRange(
1379813796 const msg = msg: {
1379913797 const msg = try sema.errMsg(
1380013798 operand_src,
13801 "ranges not allowed when switching on type '{}'",
13799 "ranges not allowed when switching on type '{f}'",
1380213800 .{operand_ty.fmt(sema.pt)},
1380313801 );
1380413802 errdefer msg.destroy(sema.gpa);
......@@ -13956,7 +13954,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1395613954 .array_type => break :hf field_name.eqlSlice("len", ip),
1395713955 else => {},
1395813956 }
13959 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
13957 return sema.fail(block, ty_src, "type '{f}' does not support '@hasField'", .{
1396013958 ty.fmt(pt),
1396113959 });
1396213960 };
......@@ -14145,7 +14143,7 @@ fn zirShl(
1414514143 while (i < rhs_ty.vectorLen(zcu)) : (i += 1) {
1414614144 const rhs_elem = try rhs_val.elemValue(pt, i);
1414714145 if (rhs_elem.compareHetero(.gte, bit_value, zcu)) {
14148 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
14146 return sema.fail(block, rhs_src, "shift amount '{f}' at index '{d}' is too large for operand type '{f}'", .{
1414914147 rhs_elem.fmtValueSema(pt, sema),
1415014148 i,
1415114149 scalar_ty.fmt(pt),
......@@ -14153,7 +14151,7 @@ fn zirShl(
1415314151 }
1415414152 }
1415514153 } else if (rhs_val.compareHetero(.gte, bit_value, zcu)) {
14156 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
14154 return sema.fail(block, rhs_src, "shift amount '{f}' is too large for operand type '{f}'", .{
1415714155 rhs_val.fmtValueSema(pt, sema),
1415814156 scalar_ty.fmt(pt),
1415914157 });
......@@ -14164,14 +14162,14 @@ fn zirShl(
1416414162 while (i < rhs_ty.vectorLen(zcu)) : (i += 1) {
1416514163 const rhs_elem = try rhs_val.elemValue(pt, i);
1416614164 if (rhs_elem.compareHetero(.lt, try pt.intValue(scalar_rhs_ty, 0), zcu)) {
14167 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
14165 return sema.fail(block, rhs_src, "shift by negative amount '{f}' at index '{d}'", .{
1416814166 rhs_elem.fmtValueSema(pt, sema),
1416914167 i,
1417014168 });
1417114169 }
1417214170 }
1417314171 } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), zcu)) {
14174 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
14172 return sema.fail(block, rhs_src, "shift by negative amount '{f}'", .{
1417514173 rhs_val.fmtValueSema(pt, sema),
1417614174 });
1417714175 }
......@@ -14326,7 +14324,7 @@ fn zirShr(
1432614324 while (i < rhs_ty.vectorLen(zcu)) : (i += 1) {
1432714325 const rhs_elem = try rhs_val.elemValue(pt, i);
1432814326 if (rhs_elem.compareHetero(.gte, bit_value, zcu)) {
14329 return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{
14327 return sema.fail(block, rhs_src, "shift amount '{f}' at index '{d}' is too large for operand type '{f}'", .{
1433014328 rhs_elem.fmtValueSema(pt, sema),
1433114329 i,
1433214330 scalar_ty.fmt(pt),
......@@ -14334,7 +14332,7 @@ fn zirShr(
1433414332 }
1433514333 }
1433614334 } else if (rhs_val.compareHetero(.gte, bit_value, zcu)) {
14337 return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{
14335 return sema.fail(block, rhs_src, "shift amount '{f}' is too large for operand type '{f}'", .{
1433814336 rhs_val.fmtValueSema(pt, sema),
1433914337 scalar_ty.fmt(pt),
1434014338 });
......@@ -14345,14 +14343,14 @@ fn zirShr(
1434514343 while (i < rhs_ty.vectorLen(zcu)) : (i += 1) {
1434614344 const rhs_elem = try rhs_val.elemValue(pt, i);
1434714345 if (rhs_elem.compareHetero(.lt, try pt.intValue(rhs_ty.childType(zcu), 0), zcu)) {
14348 return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{
14346 return sema.fail(block, rhs_src, "shift by negative amount '{f}' at index '{d}'", .{
1434914347 rhs_elem.fmtValueSema(pt, sema),
1435014348 i,
1435114349 });
1435214350 }
1435314351 }
1435414352 } else if (rhs_val.compareHetero(.lt, try pt.intValue(rhs_ty, 0), zcu)) {
14355 return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{
14353 return sema.fail(block, rhs_src, "shift by negative amount '{f}'", .{
1435614354 rhs_val.fmtValueSema(pt, sema),
1435714355 });
1435814356 }
......@@ -14638,11 +14636,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1463814636
1463914637 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {
1464014638 if (lhs_is_tuple) break :lhs_info undefined;
14641 return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
14639 return sema.fail(block, lhs_src, "expected indexable; found '{f}'", .{lhs_ty.fmt(pt)});
1464214640 };
1464314641 const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse {
1464414642 assert(!rhs_is_tuple);
14645 return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(pt)});
14643 return sema.fail(block, rhs_src, "expected indexable; found '{f}'", .{rhs_ty.fmt(pt)});
1464614644 };
1464714645
1464814646 const resolved_elem_ty = t: {
......@@ -15095,7 +15093,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1509515093 // Analyze the lhs first, to catch the case that someone tried to do exponentiation
1509615094 const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
1509715095 const msg = msg: {
15098 const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(pt)});
15096 const msg = try sema.errMsg(lhs_src, "expected indexable; found '{f}'", .{lhs_ty.fmt(pt)});
1509915097 errdefer msg.destroy(sema.gpa);
1510015098 switch (lhs_ty.zigTypeTag(zcu)) {
1510115099 .int, .float, .comptime_float, .comptime_int, .vector => {
......@@ -15227,7 +15225,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1522715225 .int, .comptime_int, .float, .comptime_float => false,
1522815226 else => true,
1522915227 }) {
15230 return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)});
15228 return sema.fail(block, src, "negation of type '{f}'", .{rhs_ty.fmt(pt)});
1523115229 }
1523215230
1523315231 if (rhs_scalar_ty.isAnyFloat()) {
......@@ -15258,7 +15256,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1525815256
1525915257 switch (rhs_scalar_ty.zigTypeTag(zcu)) {
1526015258 .int, .comptime_int, .float, .comptime_float => {},
15261 else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(pt)}),
15259 else => return sema.fail(block, src, "negation of type '{f}'", .{rhs_ty.fmt(pt)}),
1526215260 }
1526315261
1526415262 const lhs = Air.internedToRef((try sema.splat(rhs_ty, try pt.intValue(rhs_scalar_ty, 0))).toIntern());
......@@ -15332,7 +15330,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1533215330 return sema.fail(
1533315331 block,
1533415332 src,
15335 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
15333 "ambiguous coercion of division operands '{f}' and '{f}'; non-zero remainder '{f}'",
1533615334 .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValueSema(pt, sema) },
1533715335 );
1533815336 }
......@@ -15384,7 +15382,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1538415382 return sema.fail(
1538515383 block,
1538615384 src,
15387 "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact",
15385 "division with '{f}' and '{f}': signed integers must use @divTrunc, @divFloor, or @divExact",
1538815386 .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt) },
1538915387 );
1539015388 }
......@@ -16046,7 +16044,7 @@ fn zirOverflowArithmetic(
1604616044 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);
1604716045
1604816046 if (dest_ty.scalarType(zcu).zigTypeTag(zcu) != .int) {
16049 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(pt)});
16047 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{f}'", .{dest_ty.fmt(pt)});
1605016048 }
1605116049
1605216050 const maybe_lhs_val = try sema.resolveValue(lhs);
......@@ -16252,14 +16250,14 @@ fn analyzeArithmetic(
1625216250 return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction");
1625316251 }
1625416252 if (!lhs_ty.elemType2(zcu).eql(rhs_ty.elemType2(zcu), zcu)) {
16255 return sema.fail(block, src, "incompatible pointer arithmetic operands '{}' and '{}'", .{
16253 return sema.fail(block, src, "incompatible pointer arithmetic operands '{f}' and '{f}'", .{
1625616254 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
1625716255 });
1625816256 }
1625916257
1626016258 const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu);
1626116259 if (elem_size == 0) {
16262 return sema.fail(block, src, "pointer arithmetic requires element type '{}' to have runtime bits", .{
16260 return sema.fail(block, src, "pointer arithmetic requires element type '{f}' to have runtime bits", .{
1626316261 lhs_ty.elemType2(zcu).fmt(pt),
1626416262 });
1626516263 }
......@@ -16310,7 +16308,7 @@ fn analyzeArithmetic(
1631016308 };
1631116309
1631216310 if (!try lhs_ty.elemType2(zcu).hasRuntimeBitsSema(pt)) {
16313 return sema.fail(block, src, "pointer arithmetic requires element type '{}' to have runtime bits", .{
16311 return sema.fail(block, src, "pointer arithmetic requires element type '{f}' to have runtime bits", .{
1631416312 lhs_ty.elemType2(zcu).fmt(pt),
1631516313 });
1631616314 }
......@@ -16714,7 +16712,7 @@ fn zirCmpEq(
1671416712
1671516713 if (lhs_ty_tag == .null or rhs_ty_tag == .null) {
1671616714 const non_null_type = if (lhs_ty_tag == .null) rhs_ty else lhs_ty;
16717 return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(pt)});
16715 return sema.fail(block, src, "comparison of '{f}' with null", .{non_null_type.fmt(pt)});
1671816716 }
1671916717
1672016718 if (lhs_ty_tag == .@"union" and (rhs_ty_tag == .enum_literal or rhs_ty_tag == .@"enum")) {
......@@ -16771,7 +16769,7 @@ fn analyzeCmpUnionTag(
1677116769 const msg = msg: {
1677216770 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
1677316771 errdefer msg.destroy(sema.gpa);
16774 try sema.errNote(union_ty.srcLoc(zcu), msg, "union '{}' is not a tagged union", .{union_ty.fmt(pt)});
16772 try sema.errNote(union_ty.srcLoc(zcu), msg, "union '{f}' is not a tagged union", .{union_ty.fmt(pt)});
1677516773 break :msg msg;
1677616774 };
1677716775 return sema.failWithOwnedErrorMsg(block, msg);
......@@ -16857,7 +16855,7 @@ fn analyzeCmp(
1685716855 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1685816856 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } });
1685916857 if (!resolved_type.isSelfComparable(zcu, is_equality_cmp)) {
16860 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
16858 return sema.fail(block, src, "operator {s} not allowed for type '{f}'", .{
1686116859 compareOperatorName(op), resolved_type.fmt(pt),
1686216860 });
1686316861 }
......@@ -16966,7 +16964,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1696616964 .undefined,
1696716965 .null,
1696816966 .@"opaque",
16969 => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(pt)}),
16967 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{ty.fmt(pt)}),
1697016968
1697116969 .type,
1697216970 .enum_literal,
......@@ -17007,7 +17005,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1700717005 .undefined,
1700817006 .null,
1700917007 .@"opaque",
17010 => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(pt)}),
17008 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{operand_ty.fmt(pt)}),
1701117009
1701217010 .type,
1701317011 .enum_literal,
......@@ -18319,7 +18317,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
1831918317 return sema.fail(
1832018318 block,
1832118319 src,
18322 "bit shifting operation expected integer type, found '{}'",
18320 "bit shifting operation expected integer type, found '{f}'",
1832318321 .{operand.fmt(pt)},
1832418322 );
1832518323}
......@@ -18558,7 +18556,7 @@ fn checkSentinelType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !voi
1855818556 const pt = sema.pt;
1855918557 const zcu = pt.zcu;
1856018558 if (!ty.isSelfComparable(zcu, true)) {
18561 return sema.fail(block, src, "non-scalar sentinel type '{}'", .{ty.fmt(pt)});
18559 return sema.fail(block, src, "non-scalar sentinel type '{f}'", .{ty.fmt(pt)});
1856218560 }
1856318561}
1856418562
......@@ -18608,7 +18606,7 @@ fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
1860818606 const zcu = pt.zcu;
1860918607 switch (ty.zigTypeTag(zcu)) {
1861018608 .error_set, .error_union, .undefined => return,
18611 else => return sema.fail(block, src, "expected error union type, found '{}'", .{
18609 else => return sema.fail(block, src, "expected error union type, found '{f}'", .{
1861218610 ty.fmt(pt),
1861318611 }),
1861418612 }
......@@ -18752,7 +18750,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
1875218750 const pt = sema.pt;
1875318751 const zcu = pt.zcu;
1875418752 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
18755 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
18753 return sema.fail(parent_block, operand_src, "expected error union type, found '{f}'", .{
1875618754 err_union_ty.fmt(pt),
1875718755 });
1875818756 }
......@@ -18812,7 +18810,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1881218810 const pt = sema.pt;
1881318811 const zcu = pt.zcu;
1881418812 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
18815 return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{
18813 return sema.fail(parent_block, operand_src, "expected error union type, found '{f}'", .{
1881618814 err_union_ty.fmt(pt),
1881718815 });
1881818816 }
......@@ -19010,7 +19008,7 @@ fn zirRetImplicit(
1901019008 const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu);
1901119009 if (base_tag == .noreturn) {
1901219010 const msg = msg: {
19013 const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{
19011 const msg = try sema.errMsg(ret_ty_src, "function declared '{f}' implicitly returns", .{
1901419012 sema.fn_ret_ty.fmt(pt),
1901519013 });
1901619014 errdefer msg.destroy(sema.gpa);
......@@ -19020,7 +19018,7 @@ fn zirRetImplicit(
1902019018 return sema.failWithOwnedErrorMsg(block, msg);
1902119019 } else if (base_tag != .void) {
1902219020 const msg = msg: {
19023 const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
19021 const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{f}' implicitly returns", .{
1902419022 sema.fn_ret_ty.fmt(pt),
1902519023 });
1902619024 errdefer msg.destroy(sema.gpa);
......@@ -19409,13 +19407,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1940919407
1941019408 if (host_size != 0) {
1941119409 if (bit_offset >= host_size * 8) {
19412 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} starts {} bits after the end of a {} byte host integer", .{
19410 return sema.fail(block, bitoffset_src, "packed type '{f}' at bit offset {} starts {} bits after the end of a {} byte host integer", .{
1941319411 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
1941419412 });
1941519413 }
1941619414 const elem_bit_size = try elem_ty.bitSizeSema(pt);
1941719415 if (elem_bit_size > host_size * 8 - bit_offset) {
19418 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{
19416 return sema.fail(block, bitoffset_src, "packed type '{f}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{
1941919417 elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,
1942019418 });
1942119419 }
......@@ -19430,7 +19428,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1943019428 } else if (inst_data.size == .c) {
1943119429 if (!try sema.validateExternType(elem_ty, .other)) {
1943219430 const msg = msg: {
19433 const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(pt)});
19431 const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)});
1943419432 errdefer msg.destroy(sema.gpa);
1943519433
1943619434 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
......@@ -19447,7 +19445,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1944719445
1944819446 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {
1944919447 return sema.failWithOwnedErrorMsg(block, msg: {
19450 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(pt)});
19448 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{f}'", .{elem_ty.fmt(pt)});
1945119449 errdefer msg.destroy(sema.gpa);
1945219450 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);
1945319451 break :msg msg;
......@@ -19616,7 +19614,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1961619614 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
1961719615 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
1961819616 if (union_ty.zigTypeTag(pt.zcu) != .@"union") {
19619 return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(pt)});
19617 return sema.fail(block, ty_src, "expected union type, found '{f}'", .{union_ty.fmt(pt)});
1962019618 }
1962119619 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .union_field_name });
1962219620 const init = try sema.resolveInst(extra.init);
......@@ -19779,7 +19777,7 @@ fn zirStructInit(
1977919777 const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{});
1978019778 errdefer msg.destroy(sema.gpa);
1978119779
19782 try sema.addFieldErrNote(resolved_ty, field_index, msg, "field '{}' declared here", .{
19780 try sema.addFieldErrNote(resolved_ty, field_index, msg, "field '{f}' declared here", .{
1978319781 field_name.fmt(ip),
1978419782 });
1978519783 try sema.addDeclaredHereNote(msg, resolved_ty);
......@@ -19898,7 +19896,7 @@ fn finishStructInit(
1989819896 const field_init = struct_type.fieldInit(ip, i);
1989919897 if (field_init == .none) {
1990019898 const field_name = struct_type.field_names.get(ip)[i];
19901 const template = "missing struct field: {}";
19899 const template = "missing struct field: {f}";
1990219900 const args = .{field_name.fmt(ip)};
1990319901 if (root_msg) |msg| {
1990419902 try sema.errNote(init_src, msg, template, args);
......@@ -20513,7 +20511,7 @@ fn fieldType(
2051320511 },
2051420512 else => {},
2051520513 }
20516 return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
20514 return sema.fail(block, ty_src, "expected struct or union; found '{f}'", .{
2051720515 cur_ty.fmt(pt),
2051820516 });
2051920517 }
......@@ -20560,7 +20558,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2056020558 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2056120559 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
2056220560 if (ty.isNoReturn(zcu)) {
20563 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.pt)});
20561 return sema.fail(block, operand_src, "no align available for type '{f}'", .{ty.fmt(sema.pt)});
2056420562 }
2056520563 const val = try ty.lazyAbiAlignment(sema.pt);
2056620564 return Air.internedToRef(val.toIntern());
......@@ -20638,7 +20636,7 @@ fn zirAbs(
2063820636 else => return sema.fail(
2063920637 block,
2064020638 operand_src,
20641 "expected integer, float, or vector of either integers or floats, found '{}'",
20639 "expected integer, float, or vector of either integers or floats, found '{f}'",
2064220640 .{operand_ty.fmt(pt)},
2064320641 ),
2064420642 };
......@@ -20707,7 +20705,7 @@ fn zirUnaryMath(
2070720705 else => return sema.fail(
2070820706 block,
2070920707 operand_src,
20710 "expected vector of floats or float type, found '{}'",
20708 "expected vector of floats or float type, found '{f}'",
2071120709 .{operand_ty.fmt(pt)},
2071220710 ),
2071320711 }
......@@ -20736,8 +20734,8 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2073620734 },
2073720735 .@"enum" => operand_ty,
2073820736 .@"union" => operand_ty.unionTagType(zcu) orelse
20739 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),
20740 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
20737 return sema.fail(block, src, "union '{f}' is untagged", .{operand_ty.fmt(pt)}),
20738 else => return sema.fail(block, operand_src, "expected enum or union; found '{f}'", .{
2074120739 operand_ty.fmt(pt),
2074220740 }),
2074320741 };
......@@ -20745,7 +20743,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2074520743 // TODO I don't think this is the correct way to handle this but
2074620744 // it prevents a crash.
2074720745 // https://github.com/ziglang/zig/issues/15909
20748 return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{
20746 return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{f}'", .{
2074920747 enum_ty.fmt(pt),
2075020748 });
2075120749 }
......@@ -20753,7 +20751,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2075320751 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
2075420752 const field_index = enum_ty.enumTagFieldIndex(val, zcu) orelse {
2075520753 const msg = msg: {
20756 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{
20754 const msg = try sema.errMsg(src, "no field with value '{f}' in enum '{f}'", .{
2075720755 val.fmtValueSema(pt, sema), enum_ty.fmt(pt),
2075820756 });
2075920757 errdefer msg.destroy(sema.gpa);
......@@ -20940,7 +20938,7 @@ fn zirReify(
2094020938 } else if (ptr_size == .c) {
2094120939 if (!try sema.validateExternType(elem_ty, .other)) {
2094220940 const msg = msg: {
20943 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(pt)});
20941 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)});
2094420942 errdefer msg.destroy(gpa);
2094520943
2094620944 try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);
......@@ -21053,7 +21051,7 @@ fn zirReify(
2105321051 _ = try pt.getErrorValue(name);
2105421052 const gop = names.getOrPutAssumeCapacity(name);
2105521053 if (gop.found_existing) {
21056 return sema.fail(block, src, "duplicate error '{}'", .{
21054 return sema.fail(block, src, "duplicate error '{f}'", .{
2105721055 name.fmt(ip),
2105821056 });
2105921057 }
......@@ -21401,7 +21399,7 @@ fn reifyEnum(
2140121399
2140221400 if (!try sema.intFitsInType(field_value_val, tag_ty, null)) {
2140321401 // TODO: better source location
21404 return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{
21402 return sema.fail(block, src, "field '{f}' with enumeration value '{f}' is too large for backing int type '{f}'", .{
2140521403 field_name.fmt(ip),
2140621404 field_value_val.fmtValueSema(pt, sema),
2140721405 tag_ty.fmt(pt),
......@@ -21412,14 +21410,14 @@ fn reifyEnum(
2141221410 if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| {
2141321411 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
2141421412 .name => msg: {
21415 const msg = try sema.errMsg(src, "duplicate enum field '{}'", .{field_name.fmt(ip)});
21413 const msg = try sema.errMsg(src, "duplicate enum field '{f}'", .{field_name.fmt(ip)});
2141621414 errdefer msg.destroy(gpa);
2141721415 _ = conflict.prev_field_idx; // TODO: this note is incorrect
2141821416 try sema.errNote(src, msg, "other field here", .{});
2141921417 break :msg msg;
2142021418 },
2142121419 .value => msg: {
21422 const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValueSema(pt, sema)});
21420 const msg = try sema.errMsg(src, "enum tag value {f} already taken", .{field_value_val.fmtValueSema(pt, sema)});
2142321421 errdefer msg.destroy(gpa);
2142421422 _ = conflict.prev_field_idx; // TODO: this note is incorrect
2142521423 try sema.errNote(src, msg, "other enum tag value here", .{});
......@@ -21567,13 +21565,13 @@ fn reifyUnion(
2156721565
2156821566 const enum_index = enum_tag_ty.enumFieldIndex(field_name, zcu) orelse {
2156921567 // TODO: better source location
21570 return sema.fail(block, src, "no field named '{}' in enum '{}'", .{
21568 return sema.fail(block, src, "no field named '{f}' in enum '{f}'", .{
2157121569 field_name.fmt(ip), enum_tag_ty.fmt(pt),
2157221570 });
2157321571 };
2157421572 if (seen_tags.isSet(enum_index)) {
2157521573 // TODO: better source location
21576 return sema.fail(block, src, "duplicate union field {}", .{field_name.fmt(ip)});
21574 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
2157721575 }
2157821576 seen_tags.set(enum_index);
2157921577
......@@ -21594,7 +21592,7 @@ fn reifyUnion(
2159421592 var it = seen_tags.iterator(.{ .kind = .unset });
2159521593 while (it.next()) |enum_index| {
2159621594 const field_name = enum_tag_ty.enumFieldName(enum_index, zcu);
21597 try sema.addFieldErrNote(enum_tag_ty, enum_index, msg, "field '{}' missing, declared here", .{
21595 try sema.addFieldErrNote(enum_tag_ty, enum_index, msg, "field '{f}' missing, declared here", .{
2159821596 field_name.fmt(ip),
2159921597 });
2160021598 }
......@@ -21619,7 +21617,7 @@ fn reifyUnion(
2161921617 const gop = field_names.getOrPutAssumeCapacity(field_name);
2162021618 if (gop.found_existing) {
2162121619 // TODO: better source location
21622 return sema.fail(block, src, "duplicate union field {}", .{field_name.fmt(ip)});
21620 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
2162321621 }
2162421622
2162521623 field_ty.* = field_type_val.toIntern();
......@@ -21651,7 +21649,7 @@ fn reifyUnion(
2165121649 }
2165221650 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {
2165321651 return sema.failWithOwnedErrorMsg(block, msg: {
21654 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21652 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
2165521653 errdefer msg.destroy(gpa);
2165621654
2165721655 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);
......@@ -21661,7 +21659,7 @@ fn reifyUnion(
2166121659 });
2166221660 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
2166321661 return sema.failWithOwnedErrorMsg(block, msg: {
21664 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21662 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
2166521663 errdefer msg.destroy(gpa);
2166621664
2166721665 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
......@@ -21743,7 +21741,7 @@ fn reifyTuple(
2174321741 const field_name_index = field_name.toUnsigned(ip) orelse return sema.fail(
2174421742 block,
2174521743 src,
21746 "tuple cannot have non-numeric field '{}'",
21744 "tuple cannot have non-numeric field '{f}'",
2174721745 .{field_name.fmt(ip)},
2174821746 );
2174921747 if (field_name_index != field_idx) {
......@@ -21921,7 +21919,7 @@ fn reifyStruct(
2192121919 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
2192221920 if (struct_type.addFieldName(ip, field_name)) |prev_index| {
2192321921 _ = prev_index; // TODO: better source location
21924 return sema.fail(block, src, "duplicate struct field name {}", .{field_name.fmt(ip)});
21922 return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)});
2192521923 }
2192621924
2192721925 if (any_aligned_fields) {
......@@ -21990,7 +21988,7 @@ fn reifyStruct(
2199021988 }
2199121989 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {
2199221990 return sema.failWithOwnedErrorMsg(block, msg: {
21993 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
21991 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
2199421992 errdefer msg.destroy(gpa);
2199521993
2199621994 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);
......@@ -22000,7 +21998,7 @@ fn reifyStruct(
2200021998 });
2200121999 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
2200222000 return sema.failWithOwnedErrorMsg(block, msg: {
22003 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
22001 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
2200422002 errdefer msg.destroy(gpa);
2200522003
2200622004 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
......@@ -22077,7 +22075,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2207722075
2207822076 if (!try sema.validateExternType(arg_ty, .param_ty)) {
2207922077 const msg = msg: {
22080 const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.pt)});
22078 const msg = try sema.errMsg(ty_src, "cannot get '{f}' from variadic argument", .{arg_ty.fmt(sema.pt)});
2208122079 errdefer msg.destroy(sema.gpa);
2208222080
2208322081 try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty);
......@@ -22136,7 +22134,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2213622134 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2213722135 const ty = try sema.resolveType(block, ty_src, inst_data.operand);
2213822136
22139 const type_name = try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{}", .{ty.fmt(pt)}, .no_embedded_nulls);
22137 const type_name = try ip.getOrPutStringFmt(sema.gpa, pt.tid, "{f}", .{ty.fmt(pt)}, .no_embedded_nulls);
2214022138 return sema.addNullTerminatedStrLit(type_name);
2214122139}
2214222140
......@@ -22270,7 +22268,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2227022268
2227122269 if (ptr_ty.isSlice(zcu)) {
2227222270 const msg = msg: {
22273 const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(pt)});
22271 const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{f}'", .{ptr_ty.fmt(pt)});
2227422272 errdefer msg.destroy(sema.gpa);
2227522273 try sema.errNote(src, msg, "slice length cannot be inferred from address", .{});
2227622274 break :msg msg;
......@@ -22297,7 +22295,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2229722295 }
2229822296 if (try ptr_ty.comptimeOnlySema(pt)) {
2229922297 return sema.failWithOwnedErrorMsg(block, msg: {
22300 const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(pt)});
22298 const msg = try sema.errMsg(src, "pointer to comptime-only type '{f}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(pt)});
2230122299 errdefer msg.destroy(sema.gpa);
2230222300
2230322301 try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);
......@@ -22354,7 +22352,7 @@ fn ptrFromIntVal(
2235422352 }
2235522353 const addr = try operand_val.toUnsignedIntSema(pt);
2235622354 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
22357 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(pt)});
22355 return sema.fail(block, operand_src, "pointer type '{f}' does not allow address zero", .{ptr_ty.fmt(pt)});
2235822356 if (addr != 0 and ptr_align != .none) {
2235922357 const masked_addr = if (ptr_ty.childType(zcu).fnPtrMaskOrNull(zcu)) |mask|
2236022358 addr & mask
......@@ -22407,8 +22405,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2240722405 errdefer msg.destroy(sema.gpa);
2240822406 const dest_payload_ty = dest_ty.errorUnionPayload(zcu);
2240922407 const operand_payload_ty = operand_ty.errorUnionPayload(zcu);
22410 try sema.errNote(src, msg, "destination payload is '{}'", .{dest_payload_ty.fmt(pt)});
22411 try sema.errNote(src, msg, "operand payload is '{}'", .{operand_payload_ty.fmt(pt)});
22408 try sema.errNote(src, msg, "destination payload is '{f}'", .{dest_payload_ty.fmt(pt)});
22409 try sema.errNote(src, msg, "operand payload is '{f}'", .{operand_payload_ty.fmt(pt)});
2241222410 try addDeclaredHereNote(sema, msg, dest_ty);
2241322411 try addDeclaredHereNote(sema, msg, operand_ty);
2241422412 break :msg msg;
......@@ -22453,7 +22451,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2245322451 break :disjoint true;
2245422452 };
2245522453 if (disjoint and !(operand_tag == .error_union and dest_tag == .error_union)) {
22456 return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{
22454 return sema.fail(block, src, "error sets '{f}' and '{f}' have no common errors", .{
2245722455 operand_err_ty.fmt(pt), dest_err_ty.fmt(pt),
2245822456 });
2245922457 }
......@@ -22473,7 +22471,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2247322471 };
2247422472
2247522473 if (!dest_err_ty.isAnyError(zcu) and !Type.errorSetHasFieldIp(ip, dest_err_ty.toIntern(), err_name)) {
22476 return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{
22474 return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{
2247722475 err_name.fmt(ip), dest_err_ty.fmt(pt),
2247822476 });
2247922477 }
......@@ -22633,13 +22631,15 @@ fn ptrCastFull(
2263322631 const src_elem_size = src_elem_ty.abiSize(zcu);
2263422632 const dest_elem_size = dest_elem_ty.abiSize(zcu);
2263522633 if (dest_elem_size == 0) {
22636 return sema.fail(block, src, "cannot infer length of slice of zero-bit '{}' from '{}'", .{ dest_elem_ty.fmt(pt), operand_ty.fmt(pt) });
22634 return sema.fail(block, src, "cannot infer length of slice of zero-bit '{f}' from '{f}'", .{
22635 dest_elem_ty.fmt(pt), operand_ty.fmt(pt),
22636 });
2263722637 }
2263822638 if (opt_src_len) |src_len| {
2263922639 const bytes = src_len * src_elem_size;
2264022640 const dest_len = std.math.divExact(u64, bytes, dest_elem_size) catch switch (src_info.flags.size) {
2264122641 .slice => return sema.fail(block, src, "slice length '{d}' does not divide exactly into destination elements", .{src_len}),
22642 .one => return sema.fail(block, src, "type '{}' does not divide exactly into destination elements", .{src_elem_ty.fmt(pt)}),
22642 .one => return sema.fail(block, src, "type '{f}' does not divide exactly into destination elements", .{src_elem_ty.fmt(pt)}),
2264322643 else => unreachable,
2264422644 };
2264522645 break :len .{ .constant = dest_len };
......@@ -22657,7 +22657,9 @@ fn ptrCastFull(
2265722657 // The source value has `src_len * src_base_per_elem` values of type `src_base_ty`.
2265822658 // The result value will have `dest_len * dest_base_per_elem` values of type `dest_base_ty`.
2265922659 if (dest_base_ty.toIntern() != src_base_ty.toIntern()) {
22660 return sema.fail(block, src, "cannot infer length of comptime-only '{}' from incompatible '{}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) });
22660 return sema.fail(block, src, "cannot infer length of comptime-only '{f}' from incompatible '{f}'", .{
22661 dest_ty.fmt(pt), operand_ty.fmt(pt),
22662 });
2266122663 }
2266222664 // `src_base_ty` is comptime-only, so `src_elem_ty` is comptime-only, so `operand_ty` is
2266322665 // comptime-only, so `operand` is comptime-known, so `opt_src_len` is non-`null`.
......@@ -22665,7 +22667,7 @@ fn ptrCastFull(
2266522667 const base_len = src_len * src_base_per_elem;
2266622668 const dest_len = std.math.divExact(u64, base_len, dest_base_per_elem) catch switch (src_info.flags.size) {
2266722669 .slice => return sema.fail(block, src, "slice length '{d}' does not divide exactly into destination elements", .{src_len}),
22668 .one => return sema.fail(block, src, "type '{}' does not divide exactly into destination elements", .{src_elem_ty.fmt(pt)}),
22670 .one => return sema.fail(block, src, "type '{f}' does not divide exactly into destination elements", .{src_elem_ty.fmt(pt)}),
2266922671 else => unreachable,
2267022672 };
2267122673 break :len .{ .constant = dest_len };
......@@ -22726,7 +22728,7 @@ fn ptrCastFull(
2272622728 );
2272722729 if (imc_res == .ok) break :check_child;
2272822730 return sema.failWithOwnedErrorMsg(block, msg: {
22729 const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{
22731 const msg = try sema.errMsg(src, "pointer element type '{f}' cannot coerce into element type '{f}'", .{
2273022732 src_child.fmt(pt), dest_child.fmt(pt),
2273122733 });
2273222734 errdefer msg.destroy(sema.gpa);
......@@ -22753,11 +22755,11 @@ fn ptrCastFull(
2275322755 }
2275422756 return sema.failWithOwnedErrorMsg(block, msg: {
2275522757 const msg = if (src_info.sentinel == .none) blk: {
22756 break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{
22758 break :blk try sema.errMsg(src, "destination pointer requires '{f}' sentinel", .{
2275722759 Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema),
2275822760 });
2275922761 } else blk: {
22760 break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
22762 break :blk try sema.errMsg(src, "pointer sentinel '{f}' cannot coerce into pointer sentinel '{f}'", .{
2276122763 Value.fromInterned(src_info.sentinel).fmtValueSema(pt, sema),
2276222764 Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema),
2276322765 });
......@@ -22799,7 +22801,7 @@ fn ptrCastFull(
2279922801 if (dest_allows_zero) break :check_allowzero;
2280022802
2280122803 return sema.failWithOwnedErrorMsg(block, msg: {
22802 const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{
22804 const msg = try sema.errMsg(src, "'{f}' could have null values which are illegal in type '{f}'", .{
2280322805 operand_ty.fmt(pt),
2280422806 dest_ty.fmt(pt),
2280522807 });
......@@ -22827,10 +22829,10 @@ fn ptrCastFull(
2282722829 return sema.failWithOwnedErrorMsg(block, msg: {
2282822830 const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation});
2282922831 errdefer msg.destroy(sema.gpa);
22830 try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{
22832 try sema.errNote(operand_src, msg, "'{f}' has alignment '{d}'", .{
2283122833 operand_ty.fmt(pt), src_align.toByteUnits() orelse 0,
2283222834 });
22833 try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{
22835 try sema.errNote(src, msg, "'{f}' has alignment '{d}'", .{
2283422836 dest_ty.fmt(pt), dest_align.toByteUnits() orelse 0,
2283522837 });
2283622838 try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{});
......@@ -22844,10 +22846,10 @@ fn ptrCastFull(
2284422846 return sema.failWithOwnedErrorMsg(block, msg: {
2284522847 const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation});
2284622848 errdefer msg.destroy(sema.gpa);
22847 try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{
22849 try sema.errNote(operand_src, msg, "'{f}' has address space '{s}'", .{
2284822850 operand_ty.fmt(pt), @tagName(src_info.flags.address_space),
2284922851 });
22850 try sema.errNote(src, msg, "'{}' has address space '{s}'", .{
22852 try sema.errNote(src, msg, "'{f}' has address space '{s}'", .{
2285122853 dest_ty.fmt(pt), @tagName(dest_info.flags.address_space),
2285222854 });
2285322855 try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{});
......@@ -22914,7 +22916,7 @@ fn ptrCastFull(
2291422916
2291522917 if (operand_val.isNull(zcu)) {
2291622918 if (!dest_ty.ptrAllowsZero(zcu)) {
22917 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)});
22919 return sema.fail(block, operand_src, "null pointer casted to type '{f}'", .{dest_ty.fmt(pt)});
2291822920 }
2291922921 if (dest_ty.zigTypeTag(zcu) == .optional) {
2292022922 return Air.internedToRef((try pt.nullValue(dest_ty)).toIntern());
......@@ -23205,7 +23207,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2320523207 const operand_is_vector = operand_ty.zigTypeTag(zcu) == .vector;
2320623208 const dest_is_vector = dest_ty.zigTypeTag(zcu) == .vector;
2320723209 if (operand_is_vector != dest_is_vector) {
23208 return sema.fail(block, operand_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) });
23210 return sema.fail(block, operand_src, "expected type '{f}', found '{f}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) });
2320923211 }
2321023212
2321123213 if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_int) {
......@@ -23225,7 +23227,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2322523227 }
2322623228
2322723229 if (operand_info.signedness != dest_info.signedness) {
23228 return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{
23230 return sema.fail(block, operand_src, "expected {s} integer type, found '{f}'", .{
2322923231 @tagName(dest_info.signedness), operand_ty.fmt(pt),
2323023232 });
2323123233 }
......@@ -23234,7 +23236,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2323423236 const msg = msg: {
2323523237 const msg = try sema.errMsg(
2323623238 src,
23237 "destination type '{}' has more bits than source type '{}'",
23239 "destination type '{f}' has more bits than source type '{f}'",
2323823240 .{ dest_ty.fmt(pt), operand_ty.fmt(pt) },
2323923241 );
2324023242 errdefer msg.destroy(sema.gpa);
......@@ -23352,7 +23354,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2335223354 return sema.fail(
2335323355 block,
2335423356 operand_src,
23355 "@byteSwap requires the number of bits to be evenly divisible by 8, but {} has {} bits",
23357 "@byteSwap requires the number of bits to be evenly divisible by 8, but {f} has {} bits",
2335623358 .{ scalar_ty.fmt(pt), bits },
2335723359 );
2335823360 }
......@@ -23472,7 +23474,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2347223474 try ty.resolveLayout(pt);
2347323475 switch (ty.zigTypeTag(zcu)) {
2347423476 .@"struct" => {},
23475 else => return sema.fail(block, ty_src, "expected struct type, found '{}'", .{ty.fmt(pt)}),
23477 else => return sema.fail(block, ty_src, "expected struct type, found '{f}'", .{ty.fmt(pt)}),
2347623478 }
2347723479
2347823480 const field_index = if (ty.isTuple(zcu)) blk: {
......@@ -23507,7 +23509,7 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com
2350723509 const zcu = pt.zcu;
2350823510 switch (ty.zigTypeTag(zcu)) {
2350923511 .@"struct", .@"enum", .@"union", .@"opaque" => return,
23510 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{}'", .{ty.fmt(pt)}),
23512 else => return sema.fail(block, src, "expected struct, enum, union, or opaque; found '{f}'", .{ty.fmt(pt)}),
2351123513 }
2351223514}
2351323515
......@@ -23518,7 +23520,7 @@ fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileEr
2351823520 switch (ty.zigTypeTag(zcu)) {
2351923521 .comptime_int => return true,
2352023522 .int => return false,
23521 else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty.fmt(pt)}),
23523 else => return sema.fail(block, src, "expected integer type, found '{f}'", .{ty.fmt(pt)}),
2352223524 }
2352323525}
2352423526
......@@ -23572,7 +23574,7 @@ fn checkPtrOperand(
2357223574 const msg = msg: {
2357323575 const msg = try sema.errMsg(
2357423576 ty_src,
23575 "expected pointer, found '{}'",
23577 "expected pointer, found '{f}'",
2357623578 .{ty.fmt(pt)},
2357723579 );
2357823580 errdefer msg.destroy(sema.gpa);
......@@ -23586,7 +23588,7 @@ fn checkPtrOperand(
2358623588 .optional => if (ty.childType(zcu).zigTypeTag(zcu) == .pointer) return,
2358723589 else => {},
2358823590 }
23589 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23591 return sema.fail(block, ty_src, "expected pointer type, found '{f}'", .{ty.fmt(pt)});
2359023592}
2359123593
2359223594fn checkPtrType(
......@@ -23604,7 +23606,7 @@ fn checkPtrType(
2360423606 const msg = msg: {
2360523607 const msg = try sema.errMsg(
2360623608 ty_src,
23607 "expected pointer type, found '{}'",
23609 "expected pointer type, found '{f}'",
2360823610 .{ty.fmt(pt)},
2360923611 );
2361023612 errdefer msg.destroy(sema.gpa);
......@@ -23618,7 +23620,7 @@ fn checkPtrType(
2361823620 .optional => if (ty.childType(zcu).zigTypeTag(zcu) == .pointer) return,
2361923621 else => {},
2362023622 }
23621 return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty.fmt(pt)});
23623 return sema.fail(block, ty_src, "expected pointer type, found '{f}'", .{ty.fmt(pt)});
2362223624}
2362323625
2362423626fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
......@@ -23629,7 +23631,7 @@ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
2362923631 const as = ty.ptrAddressSpace(zcu);
2363023632 if (target_util.arePointersLogical(target, as)) {
2363123633 return sema.failWithOwnedErrorMsg(block, msg: {
23632 const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{}'", .{ty.fmt(pt)});
23634 const msg = try sema.errMsg(src, "illegal operation on logical pointer of type '{f}'", .{ty.fmt(pt)});
2363323635 errdefer msg.destroy(sema.gpa);
2363423636 try sema.errNote(
2363523637 src,
......@@ -23660,7 +23662,7 @@ fn checkVectorElemType(
2366023662 .optional, .pointer => if (ty.isPtrAtRuntime(zcu)) return,
2366123663 else => {},
2366223664 }
23663 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{}'", .{ty.fmt(pt)});
23665 return sema.fail(block, ty_src, "expected integer, float, bool, or pointer for the vector element type; found '{f}'", .{ty.fmt(pt)});
2366423666}
2366523667
2366623668fn checkFloatType(
......@@ -23673,7 +23675,7 @@ fn checkFloatType(
2367323675 const zcu = pt.zcu;
2367423676 switch (ty.zigTypeTag(zcu)) {
2367523677 .comptime_int, .comptime_float, .float => {},
23676 else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ty.fmt(pt)}),
23678 else => return sema.fail(block, ty_src, "expected float type, found '{f}'", .{ty.fmt(pt)}),
2367723679 }
2367823680}
2367923681
......@@ -23691,7 +23693,7 @@ fn checkNumericType(
2369123693 .comptime_float, .float, .comptime_int, .int => {},
2369223694 else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}),
2369323695 },
23694 else => return sema.fail(block, ty_src, "expected number, found '{}'", .{ty.fmt(pt)}),
23696 else => return sema.fail(block, ty_src, "expected number, found '{f}'", .{ty.fmt(pt)}),
2369523697 }
2369623698}
2369723699
......@@ -23725,7 +23727,7 @@ fn checkAtomicPtrOperand(
2372523727 error.BadType => return sema.fail(
2372623728 block,
2372723729 elem_ty_src,
23728 "expected bool, integer, float, enum, packed struct, or pointer type; found '{}'",
23730 "expected bool, integer, float, enum, packed struct, or pointer type; found '{f}'",
2372923731 .{elem_ty.fmt(pt)},
2373023732 ),
2373123733 };
......@@ -23786,12 +23788,12 @@ fn checkIntOrVector(
2378623788 const elem_ty = operand_ty.childType(zcu);
2378723789 switch (elem_ty.zigTypeTag(zcu)) {
2378823790 .int => return elem_ty,
23789 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
23791 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{f}'", .{
2379023792 elem_ty.fmt(pt),
2379123793 }),
2379223794 }
2379323795 },
23794 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
23796 else => return sema.fail(block, operand_src, "expected integer or vector, found '{f}'", .{
2379523797 operand_ty.fmt(pt),
2379623798 }),
2379723799 }
......@@ -23811,12 +23813,12 @@ fn checkIntOrVectorAllowComptime(
2381123813 const elem_ty = operand_ty.childType(zcu);
2381223814 switch (elem_ty.zigTypeTag(zcu)) {
2381323815 .int, .comptime_int => return elem_ty,
23814 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{
23816 else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{f}'", .{
2381523817 elem_ty.fmt(pt),
2381623818 }),
2381723819 }
2381823820 },
23819 else => return sema.fail(block, operand_src, "expected integer or vector, found '{}'", .{
23821 else => return sema.fail(block, operand_src, "expected integer or vector, found '{f}'", .{
2382023822 operand_ty.fmt(pt),
2382123823 }),
2382223824 }
......@@ -23907,7 +23909,7 @@ fn checkVectorizableBinaryOperands(
2390723909 }
2390823910 } else {
2390923911 const msg = msg: {
23910 const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{
23912 const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{f}' and '{f}'", .{
2391123913 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
2391223914 });
2391323915 errdefer msg.destroy(sema.gpa);
......@@ -24041,7 +24043,7 @@ fn zirCmpxchg(
2404124043 return sema.fail(
2404224044 block,
2404324045 elem_ty_src,
24044 "expected bool, integer, enum, packed struct, or pointer type; found '{}'",
24046 "expected bool, integer, enum, packed struct, or pointer type; found '{f}'",
2404524047 .{elem_ty.fmt(pt)},
2404624048 );
2404724049 }
......@@ -24125,7 +24127,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
2412524127
2412624128 switch (dest_ty.zigTypeTag(zcu)) {
2412724129 .array, .vector => {},
24128 else => return sema.fail(block, src, "expected array or vector type, found '{}'", .{dest_ty.fmt(pt)}),
24130 else => return sema.fail(block, src, "expected array or vector type, found '{f}'", .{dest_ty.fmt(pt)}),
2412924131 }
2413024132
2413124133 const operand = try sema.resolveInst(extra.rhs);
......@@ -24201,7 +24203,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2420124203 const zcu = pt.zcu;
2420224204
2420324205 if (operand_ty.zigTypeTag(zcu) != .vector) {
24204 return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(pt)});
24206 return sema.fail(block, operand_src, "expected vector, found '{f}'", .{operand_ty.fmt(pt)});
2420524207 }
2420624208
2420724209 const scalar_ty = operand_ty.childType(zcu);
......@@ -24210,13 +24212,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2421024212 switch (operation) {
2421124213 .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
2421224214 .int, .bool => {},
24213 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{}'", .{
24215 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or boolean operand; found '{f}'", .{
2421424216 @tagName(operation), operand_ty.fmt(pt),
2421524217 }),
2421624218 },
2421724219 .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) {
2421824220 .int, .float => {},
24219 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{}'", .{
24221 else => return sema.fail(block, operand_src, "@reduce operation '{s}' requires integer or float operand; found '{f}'", .{
2422024222 @tagName(operation), operand_ty.fmt(pt),
2422124223 }),
2422224224 },
......@@ -24270,7 +24272,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2427024272
2427124273 const mask_len = switch (sema.typeOf(mask).zigTypeTag(zcu)) {
2427224274 .array, .vector => sema.typeOf(mask).arrayLen(zcu),
24273 else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(pt)}),
24275 else => return sema.fail(block, mask_src, "expected vector or array, found '{f}'", .{sema.typeOf(mask).fmt(pt)}),
2427424276 };
2427524277 mask_ty = try pt.vectorType(.{
2427624278 .len = @intCast(mask_len),
......@@ -24297,11 +24299,14 @@ fn analyzeShuffle(
2429724299 const b_src = block.builtinCallArgSrc(src_node, 2);
2429824300 const mask_src = block.builtinCallArgSrc(src_node, 3);
2429924301
24300 // If the type of `a` is `@Type(.undefined)`, i.e. the argument is untyped, this is 0, because it is an error to index into this vector.
24302 // If the type of `a` is `@Type(.undefined)`, i.e. the argument is untyped,
24303 // this is 0, because it is an error to index into this vector.
2430124304 const a_len: u32 = switch (sema.typeOf(a_uncoerced).zigTypeTag(zcu)) {
2430224305 .array, .vector => @intCast(sema.typeOf(a_uncoerced).arrayLen(zcu)),
2430324306 .undefined => 0,
24304 else => return sema.fail(block, a_src, "expected vector of '{}', found '{}'", .{ elem_ty.fmt(pt), sema.typeOf(a_uncoerced).fmt(pt) }),
24307 else => return sema.fail(block, a_src, "expected vector of '{f}', found '{f}'", .{
24308 elem_ty.fmt(pt), sema.typeOf(a_uncoerced).fmt(pt),
24309 }),
2430524310 };
2430624311 const a_ty = try pt.vectorType(.{ .len = a_len, .child = elem_ty.toIntern() });
2430724312 const a_coerced = try sema.coerce(block, a_ty, a_uncoerced, a_src);
......@@ -24310,7 +24315,9 @@ fn analyzeShuffle(
2431024315 const b_len: u32 = switch (sema.typeOf(b_uncoerced).zigTypeTag(zcu)) {
2431124316 .array, .vector => @intCast(sema.typeOf(b_uncoerced).arrayLen(zcu)),
2431224317 .undefined => 0,
24313 else => return sema.fail(block, b_src, "expected vector of '{}', found '{}'", .{ elem_ty.fmt(pt), sema.typeOf(b_uncoerced).fmt(pt) }),
24318 else => return sema.fail(block, b_src, "expected vector of '{f}', found '{f}'", .{
24319 elem_ty.fmt(pt), sema.typeOf(b_uncoerced).fmt(pt),
24320 }),
2431424321 };
2431524322 const b_ty = try pt.vectorType(.{ .len = b_len, .child = elem_ty.toIntern() });
2431624323 const b_coerced = try sema.coerce(block, b_ty, b_uncoerced, b_src);
......@@ -24348,7 +24355,7 @@ fn analyzeShuffle(
2434824355 if (idx >= a_len) return sema.failWithOwnedErrorMsg(block, msg: {
2434924356 const msg = try sema.errMsg(mask_src, "mask element at index '{d}' selects out-of-bounds index", .{mask_idx});
2435024357 errdefer msg.destroy(sema.gpa);
24351 try sema.errNote(a_src, msg, "index '{d}' exceeds bounds of '{}' given here", .{ idx, a_ty.fmt(pt) });
24358 try sema.errNote(a_src, msg, "index '{d}' exceeds bounds of '{f}' given here", .{ idx, a_ty.fmt(pt) });
2435224359 if (idx < b_len) {
2435324360 try sema.errNote(b_src, msg, "use '~@as(u32, {d})' to index into second vector given here", .{idx});
2435424361 }
......@@ -24464,7 +24471,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2446424471
2446524472 const vec_len_u64 = switch (pred_ty.zigTypeTag(zcu)) {
2446624473 .vector, .array => pred_ty.arrayLen(zcu),
24467 else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(pt)}),
24474 else => return sema.fail(block, pred_src, "expected vector or array, found '{f}'", .{pred_ty.fmt(pt)}),
2446824475 };
2446924476 const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64));
2447024477
......@@ -24724,7 +24731,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2472424731
2472524732 switch (ty.scalarType(zcu).zigTypeTag(zcu)) {
2472624733 .comptime_float, .float => {},
24727 else => return sema.fail(block, src, "expected vector of floats or float type, found '{}'", .{ty.fmt(pt)}),
24734 else => return sema.fail(block, src, "expected vector of floats or float type, found '{f}'", .{ty.fmt(pt)}),
2472824735 }
2472924736
2473024737 const runtime_src = if (maybe_mulend1) |mulend1_val| rs: {
......@@ -24833,7 +24840,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2483324840
2483424841 const args_ty = sema.typeOf(args);
2483524842 if (!args_ty.isTuple(zcu)) {
24836 return sema.fail(block, args_src, "expected a tuple, found '{}'", .{args_ty.fmt(pt)});
24843 return sema.fail(block, args_src, "expected a tuple, found '{f}'", .{args_ty.fmt(pt)});
2483724844 }
2483824845
2483924846 const resolved_args: []Air.Inst.Ref = try sema.arena.alloc(Air.Inst.Ref, args_ty.structFieldCount(zcu));
......@@ -24878,12 +24885,12 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2487824885 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);
2487924886 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
2488024887 if (parent_ptr_info.flags.size != .one) {
24881 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(pt)});
24888 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});
2488224889 }
2488324890 const parent_ty: Type = .fromInterned(parent_ptr_info.child);
2488424891 switch (parent_ty.zigTypeTag(zcu)) {
2488524892 .@"struct", .@"union" => {},
24886 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(pt)}),
24893 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{f}'", .{parent_ptr_ty.fmt(pt)}),
2488724894 }
2488824895 try parent_ty.resolveLayout(pt);
2488924896
......@@ -25033,7 +25040,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2503325040 }
2503425041
2503525042 if (field.index != field_index) {
25036 return sema.fail(block, inst_src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{
25043 return sema.fail(block, inst_src, "field '{f}' has index '{d}' but pointer value is index '{d}' of struct '{f}'", .{
2503725044 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt),
2503825045 });
2503925046 }
......@@ -25492,10 +25499,10 @@ fn zirMemcpy(
2549225499 const msg = msg: {
2549325500 const msg = try sema.errMsg(src, "unknown copy length", .{});
2549425501 errdefer msg.destroy(sema.gpa);
25495 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
25502 try sema.errNote(dest_src, msg, "destination type '{f}' provides no length", .{
2549625503 dest_ty.fmt(pt),
2549725504 });
25498 try sema.errNote(src_src, msg, "source type '{}' provides no length", .{
25505 try sema.errNote(src_src, msg, "source type '{f}' provides no length", .{
2549925506 src_ty.fmt(pt),
2550025507 });
2550125508 break :msg msg;
......@@ -25519,7 +25526,7 @@ fn zirMemcpy(
2551925526 if (imc != .ok) return sema.failWithOwnedErrorMsg(block, msg: {
2552025527 const msg = try sema.errMsg(
2552125528 src,
25522 "pointer element type '{}' cannot coerce into element type '{}'",
25529 "pointer element type '{f}' cannot coerce into element type '{f}'",
2552325530 .{ src_elem_ty.fmt(pt), dest_elem_ty.fmt(pt) },
2552425531 );
2552525532 errdefer msg.destroy(sema.gpa);
......@@ -25538,10 +25545,10 @@ fn zirMemcpy(
2553825545 const msg = msg: {
2553925546 const msg = try sema.errMsg(src, "non-matching copy lengths", .{});
2554025547 errdefer msg.destroy(sema.gpa);
25541 try sema.errNote(dest_src, msg, "length {} here", .{
25548 try sema.errNote(dest_src, msg, "length {f} here", .{
2554225549 dest_len_val.fmtValueSema(pt, sema),
2554325550 });
25544 try sema.errNote(src_src, msg, "length {} here", .{
25551 try sema.errNote(src_src, msg, "length {f} here", .{
2554525552 src_len_val.fmtValueSema(pt, sema),
2554625553 });
2554725554 break :msg msg;
......@@ -25756,7 +25763,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2575625763 return sema.failWithOwnedErrorMsg(block, msg: {
2575725764 const msg = try sema.errMsg(src, "unknown @memset length", .{});
2575825765 errdefer msg.destroy(sema.gpa);
25759 try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
25766 try sema.errNote(dest_src, msg, "destination type '{f}' provides no length", .{
2576025767 dest_ptr_ty.fmt(pt),
2576125768 });
2576225769 break :msg msg;
......@@ -25964,7 +25971,7 @@ fn zirCUndef(
2596425971 const src = block.builtinCallArgSrc(extra.node, 0);
2596525972
2596625973 const name = try sema.resolveConstString(block, src, extra.operand, .{ .simple = .operand_cUndef_macro_name });
25967 try block.c_import_buf.?.writer().print("#undef {s}\n", .{name});
25974 try block.c_import_buf.?.print("#undef {s}\n", .{name});
2596825975 return .void_value;
2596925976}
2597025977
......@@ -25977,7 +25984,7 @@ fn zirCInclude(
2597725984 const src = block.builtinCallArgSrc(extra.node, 0);
2597825985
2597925986 const name = try sema.resolveConstString(block, src, extra.operand, .{ .simple = .operand_cInclude_file_name });
25980 try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name});
25987 try block.c_import_buf.?.print("#include <{s}>\n", .{name});
2598125988 return .void_value;
2598225989}
2598325990
......@@ -25996,9 +26003,9 @@ fn zirCDefine(
2599626003 const rhs = try sema.resolveInst(extra.rhs);
2599726004 if (sema.typeOf(rhs).zigTypeTag(zcu) != .void) {
2599826005 const value = try sema.resolveConstString(block, val_src, extra.rhs, .{ .simple = .operand_cDefine_macro_value });
25999 try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value });
26006 try block.c_import_buf.?.print("#define {s} {s}\n", .{ name, value });
2600026007 } else {
26001 try block.c_import_buf.?.writer().print("#define {s}\n", .{name});
26008 try block.c_import_buf.?.print("#define {s}\n", .{name});
2600226009 }
2600326010 return .void_value;
2600426011}
......@@ -26216,7 +26223,7 @@ fn zirBuiltinExtern(
2621626223 }
2621726224 if (!try sema.validateExternType(ty, .other)) {
2621826225 const msg = msg: {
26219 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(pt)});
26226 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ty.fmt(pt)});
2622026227 errdefer msg.destroy(sema.gpa);
2622126228 try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);
2622226229 break :msg msg;
......@@ -26456,7 +26463,7 @@ pub fn validateVarType(
2645626463 if (is_extern) {
2645726464 if (!try sema.validateExternType(var_ty, .other)) {
2645826465 const msg = msg: {
26459 const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(pt)});
26466 const msg = try sema.errMsg(src, "extern variable cannot have type '{f}'", .{var_ty.fmt(pt)});
2646026467 errdefer msg.destroy(sema.gpa);
2646126468 try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other);
2646226469 break :msg msg;
......@@ -26468,7 +26475,7 @@ pub fn validateVarType(
2646826475 return sema.fail(
2646926476 block,
2647026477 src,
26471 "non-extern variable with opaque type '{}'",
26478 "non-extern variable with opaque type '{f}'",
2647226479 .{var_ty.fmt(pt)},
2647326480 );
2647426481 }
......@@ -26477,7 +26484,7 @@ pub fn validateVarType(
2647726484 if (!try var_ty.comptimeOnlySema(pt)) return;
2647826485
2647926486 const msg = msg: {
26480 const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(pt)});
26487 const msg = try sema.errMsg(src, "variable of type '{f}' must be const or comptime", .{var_ty.fmt(pt)});
2648126488 errdefer msg.destroy(sema.gpa);
2648226489
2648326490 try sema.explainWhyTypeIsComptime(msg, src, var_ty);
......@@ -26527,7 +26534,7 @@ fn explainWhyTypeIsComptimeInner(
2652726534 => return,
2652826535
2652926536 .@"fn" => {
26530 try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{ty.fmt(pt)});
26537 try sema.errNote(src_loc, msg, "use '*const {f}' for a function pointer type", .{ty.fmt(pt)});
2653126538 },
2653226539
2653326540 .type => {
......@@ -26543,7 +26550,7 @@ fn explainWhyTypeIsComptimeInner(
2654326550 => return,
2654426551
2654526552 .@"opaque" => {
26546 try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(pt)});
26553 try sema.errNote(src_loc, msg, "opaque type '{f}' has undefined size", .{ty.fmt(pt)});
2654726554 },
2654826555
2654926556 .array, .vector => {
......@@ -26730,7 +26737,7 @@ fn explainWhyTypeIsNotExtern(
2673026737 if (!ty.isConstPtr(zcu) and pointee_ty.zigTypeTag(zcu) == .@"fn") {
2673126738 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});
2673226739 } else if (try ty.comptimeOnlySema(pt)) {
26733 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(pt)});
26740 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{f}'", .{pointee_ty.fmt(pt)});
2673426741 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
2673526742 }
2673626743 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);
......@@ -26758,7 +26765,7 @@ fn explainWhyTypeIsNotExtern(
2675826765 },
2675926766 .@"enum" => {
2676026767 const tag_ty = ty.intTagType(zcu);
26761 try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(pt)});
26768 try sema.errNote(src_loc, msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)});
2676226769 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
2676326770 },
2676426771 .@"struct" => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),
......@@ -27194,7 +27201,7 @@ fn fieldVal(
2719427201 return sema.fail(
2719527202 block,
2719627203 field_name_src,
27197 "no member named '{}' in '{}'",
27204 "no member named '{f}' in '{f}'",
2719827205 .{ field_name.fmt(ip), object_ty.fmt(pt) },
2719927206 );
2720027207 }
......@@ -27218,7 +27225,7 @@ fn fieldVal(
2721827225 return sema.fail(
2721927226 block,
2722027227 field_name_src,
27221 "no member named '{}' in '{}'",
27228 "no member named '{f}' in '{f}'",
2722227229 .{ field_name.fmt(ip), object_ty.fmt(pt) },
2722327230 );
2722427231 }
......@@ -27238,7 +27245,7 @@ fn fieldVal(
2723827245 switch (ip.indexToKey(child_type.toIntern())) {
2723927246 .error_set_type => |error_set_type| blk: {
2724027247 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
27241 return sema.fail(block, src, "no error named '{}' in '{}'", .{
27248 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{
2724227249 field_name.fmt(ip), child_type.fmt(pt),
2724327250 });
2724427251 },
......@@ -27293,7 +27300,7 @@ fn fieldVal(
2729327300 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
2729427301 },
2729527302 else => return sema.failWithOwnedErrorMsg(block, msg: {
27296 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27303 const msg = try sema.errMsg(src, "type '{f}' has no members", .{child_type.fmt(pt)});
2729727304 errdefer msg.destroy(sema.gpa);
2729827305 if (child_type.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
2729927306 if (child_type.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{});
......@@ -27339,7 +27346,7 @@ fn fieldPtr(
2733927346 const object_ptr_ty = sema.typeOf(object_ptr);
2734027347 const object_ty = switch (object_ptr_ty.zigTypeTag(zcu)) {
2734127348 .pointer => object_ptr_ty.childType(zcu),
27342 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(pt)}),
27349 else => return sema.fail(block, object_ptr_src, "expected pointer, found '{f}'", .{object_ptr_ty.fmt(pt)}),
2734327350 };
2734427351
2734527352 // Zig allows dereferencing a single pointer during field lookup. Note that
......@@ -27392,7 +27399,7 @@ fn fieldPtr(
2739227399 return sema.fail(
2739327400 block,
2739427401 field_name_src,
27395 "no member named '{}' in '{}'",
27402 "no member named '{f}' in '{f}'",
2739627403 .{ field_name.fmt(ip), object_ty.fmt(pt) },
2739727404 );
2739827405 }
......@@ -27447,7 +27454,7 @@ fn fieldPtr(
2744727454 return sema.fail(
2744827455 block,
2744927456 field_name_src,
27450 "no member named '{}' in '{}'",
27457 "no member named '{f}' in '{f}'",
2745127458 .{ field_name.fmt(ip), object_ty.fmt(pt) },
2745227459 );
2745327460 }
......@@ -27470,7 +27477,7 @@ fn fieldPtr(
2747027477 if (error_set_type.nameIndex(ip, field_name) != null) {
2747127478 break :blk;
2747227479 }
27473 return sema.fail(block, src, "no error named '{}' in '{}'", .{
27480 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{
2747427481 field_name.fmt(ip), child_type.fmt(pt),
2747527482 });
2747627483 },
......@@ -27524,7 +27531,7 @@ fn fieldPtr(
2752427531 }
2752527532 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2752627533 },
27527 else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(pt)}),
27534 else => return sema.fail(block, src, "type '{f}' has no members", .{child_type.fmt(pt)}),
2752827535 }
2752927536 },
2753027537 .@"struct" => {
......@@ -27579,7 +27586,7 @@ fn fieldCallBind(
2757927586 const inner_ty = if (raw_ptr_ty.zigTypeTag(zcu) == .pointer and (raw_ptr_ty.ptrSize(zcu) == .one or raw_ptr_ty.ptrSize(zcu) == .c))
2758027587 raw_ptr_ty.childType(zcu)
2758127588 else
27582 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
27589 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{f}'", .{raw_ptr_ty.fmt(pt)});
2758327590
2758427591 // Optionally dereference a second pointer to get the concrete type.
2758527592 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;
......@@ -27698,7 +27705,7 @@ fn fieldCallBind(
2769827705 };
2769927706
2770027707 const msg = msg: {
27701 const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{
27708 const msg = try sema.errMsg(src, "no field or member function named '{f}' in '{f}'", .{
2770227709 field_name.fmt(ip),
2770327710 concrete_ty.fmt(pt),
2770427711 });
......@@ -27708,7 +27715,7 @@ fn fieldCallBind(
2770827715 try sema.errNote(
2770927716 zcu.navSrcLoc(nav_index),
2771027717 msg,
27711 "'{}' is not a member function",
27718 "'{f}' is not a member function",
2771227719 .{field_name.fmt(ip)},
2771327720 );
2771427721 }
......@@ -27776,7 +27783,7 @@ fn namespaceLookup(
2777627783 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
2777727784 if (!lookup.accessible) {
2777827785 return sema.failWithOwnedErrorMsg(block, msg: {
27779 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
27786 const msg = try sema.errMsg(src, "'{f}' is not marked 'pub'", .{
2778027787 decl_name.fmt(&zcu.intern_pool),
2778127788 });
2778227789 errdefer msg.destroy(gpa);
......@@ -28014,12 +28021,12 @@ fn tupleFieldIndex(
2801428021 assert(!field_name.eqlSlice("len", ip));
2801528022 if (field_name.toUnsigned(ip)) |field_index| {
2801628023 if (field_index < tuple_ty.structFieldCount(pt.zcu)) return field_index;
28017 return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{
28024 return sema.fail(block, field_name_src, "index '{f}' out of bounds of tuple '{f}'", .{
2801828025 field_name.fmt(ip), tuple_ty.fmt(pt),
2801928026 });
2802028027 }
2802128028
28022 return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{
28029 return sema.fail(block, field_name_src, "no field named '{f}' in tuple '{f}'", .{
2802328030 field_name.fmt(ip), tuple_ty.fmt(pt),
2802428031 });
2802528032}
......@@ -28106,7 +28113,7 @@ fn unionFieldPtr(
2810628113 const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{});
2810728114 errdefer msg.destroy(sema.gpa);
2810828115
28109 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{
28116 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
2811028117 field_name.fmt(ip),
2811128118 });
2811228119 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -28140,7 +28147,7 @@ fn unionFieldPtr(
2814028147 const msg = msg: {
2814128148 const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
2814228149 const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);
28143 const msg = try sema.errMsg(src, "access of union field '{}' while field '{}' is active", .{
28150 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
2814428151 field_name.fmt(ip),
2814528152 active_field_name.fmt(ip),
2814628153 });
......@@ -28208,7 +28215,7 @@ fn unionFieldVal(
2820828215 const msg = msg: {
2820928216 const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
2821028217 const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);
28211 const msg = try sema.errMsg(src, "access of union field '{}' while field '{}' is active", .{
28218 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
2821228219 field_name.fmt(ip), active_field_name.fmt(ip),
2821328220 });
2821428221 errdefer msg.destroy(sema.gpa);
......@@ -28266,7 +28273,7 @@ fn elemPtr(
2826628273
2826728274 const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(zcu)) {
2826828275 .pointer => indexable_ptr_ty.childType(zcu),
28269 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(pt)}),
28276 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),
2827028277 };
2827128278 try sema.checkIndexable(block, src, indexable_ty);
2827228279
......@@ -28437,7 +28444,7 @@ fn validateRuntimeElemAccess(
2843728444 const msg = msg: {
2843828445 const msg = try sema.errMsg(
2843928446 elem_index_src,
28440 "values of type '{}' must be comptime-known, but index value is runtime-known",
28447 "values of type '{f}' must be comptime-known, but index value is runtime-known",
2844128448 .{parent_ty.fmt(sema.pt)},
2844228449 );
2844328450 errdefer msg.destroy(sema.gpa);
......@@ -28453,7 +28460,7 @@ fn validateRuntimeElemAccess(
2845328460 const target = zcu.getTarget();
2845428461 const as = parent_ty.ptrAddressSpace(zcu);
2845528462 if (target_util.arePointersLogical(target, as)) {
28456 return sema.fail(block, elem_index_src, "cannot access element of logical pointer '{}'", .{parent_ty.fmt(pt)});
28463 return sema.fail(block, elem_index_src, "cannot access element of logical pointer '{f}'", .{parent_ty.fmt(pt)});
2845728464 }
2845828465 }
2845928466}
......@@ -29149,7 +29156,7 @@ fn coerceExtra(
2914929156 return sema.fail(
2915029157 block,
2915129158 inst_src,
29152 "array literal requires address-of operator (&) to coerce to slice type '{}'",
29159 "array literal requires address-of operator (&) to coerce to slice type '{f}'",
2915329160 .{dest_ty.fmt(pt)},
2915429161 );
2915529162 }
......@@ -29176,7 +29183,7 @@ fn coerceExtra(
2917629183 // pointer to tuple to slice
2917729184 if (!dest_info.flags.is_const) {
2917829185 const err_msg = err_msg: {
29179 const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(pt)});
29186 const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{f}'", .{dest_ty.fmt(pt)});
2918029187 errdefer err_msg.destroy(sema.gpa);
2918129188 try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});
2918229189 break :err_msg err_msg;
......@@ -29231,7 +29238,7 @@ fn coerceExtra(
2923129238 // comptime-known integer to other number
2923229239 if (!(try sema.intFitsInType(val, dest_ty, null))) {
2923329240 if (!opts.report_err) return error.NotCoercible;
29234 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) });
29241 return sema.fail(block, inst_src, "type '{f}' cannot represent integer value '{f}'", .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) });
2923529242 }
2923629243 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
2923729244 .undef => try pt.undefRef(dest_ty),
......@@ -29273,7 +29280,7 @@ fn coerceExtra(
2927329280 return sema.fail(
2927429281 block,
2927529282 inst_src,
29276 "type '{}' cannot represent float value '{}'",
29283 "type '{f}' cannot represent float value '{f}'",
2927729284 .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) },
2927829285 );
2927929286 }
......@@ -29306,7 +29313,7 @@ fn coerceExtra(
2930629313 // return sema.fail(
2930729314 // block,
2930829315 // inst_src,
29309 // "type '{}' cannot represent integer value '{}'",
29316 // "type '{f}' cannot represent integer value '{}'",
2931029317 // .{ dest_ty.fmt(pt), val },
2931129318 // );
2931229319 //}
......@@ -29320,7 +29327,7 @@ fn coerceExtra(
2932029327 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
2932129328 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
2932229329 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
29323 return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{
29330 return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{
2932429331 string.fmt(&zcu.intern_pool), dest_ty.fmt(pt),
2932529332 });
2932629333 };
......@@ -29469,11 +29476,11 @@ fn coerceExtra(
2946929476 }
2947029477
2947129478 const msg = msg: {
29472 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
29479 const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
2947329480 errdefer msg.destroy(sema.gpa);
2947429481
2947529482 if (!can_coerce_to) {
29476 try sema.errNote(inst_src, msg, "cannot coerce to '{}'", .{dest_ty.fmt(pt)});
29483 try sema.errNote(inst_src, msg, "cannot coerce to '{f}'", .{dest_ty.fmt(pt)});
2947729484 }
2947829485
2947929486 // E!T to T
......@@ -29662,13 +29669,13 @@ const InMemoryCoercionResult = union(enum) {
2966229669 break;
2966329670 },
2966429671 .comptime_int_not_coercible => |int| {
29665 try sema.errNote(src, msg, "type '{}' cannot represent value '{}'", .{
29672 try sema.errNote(src, msg, "type '{f}' cannot represent value '{f}'", .{
2966629673 int.wanted.fmt(pt), int.actual.fmtValueSema(pt, sema),
2966729674 });
2966829675 break;
2966929676 },
2967029677 .error_union_payload => |pair| {
29671 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
29678 try sema.errNote(src, msg, "error union payload '{f}' cannot cast into error union payload '{f}'", .{
2967229679 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2967329680 });
2967429681 cur = pair.child;
......@@ -29681,18 +29688,18 @@ const InMemoryCoercionResult = union(enum) {
2968129688 },
2968229689 .array_sentinel => |sentinel| {
2968329690 if (sentinel.actual.toIntern() != .unreachable_value) {
29684 try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
29691 try sema.errNote(src, msg, "array sentinel '{f}' cannot cast into array sentinel '{f}'", .{
2968529692 sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema),
2968629693 });
2968729694 } else {
29688 try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{
29695 try sema.errNote(src, msg, "destination array requires '{f}' sentinel", .{
2968929696 sentinel.wanted.fmtValueSema(pt, sema),
2969029697 });
2969129698 }
2969229699 break;
2969329700 },
2969429701 .array_elem => |pair| {
29695 try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{
29702 try sema.errNote(src, msg, "array element type '{f}' cannot cast into array element type '{f}'", .{
2969629703 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2969729704 });
2969829705 cur = pair.child;
......@@ -29704,19 +29711,19 @@ const InMemoryCoercionResult = union(enum) {
2970429711 break;
2970529712 },
2970629713 .vector_elem => |pair| {
29707 try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{
29714 try sema.errNote(src, msg, "vector element type '{f}' cannot cast into vector element type '{f}'", .{
2970829715 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2970929716 });
2971029717 cur = pair.child;
2971129718 },
2971229719 .optional_shape => |pair| {
29713 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
29720 try sema.errNote(src, msg, "optional type child '{f}' cannot cast into optional type child '{f}'", .{
2971429721 pair.actual.optionalChild(pt.zcu).fmt(pt), pair.wanted.optionalChild(pt.zcu).fmt(pt),
2971529722 });
2971629723 break;
2971729724 },
2971829725 .optional_child => |pair| {
29719 try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
29726 try sema.errNote(src, msg, "optional type child '{f}' cannot cast into optional type child '{f}'", .{
2972029727 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2972129728 });
2972229729 cur = pair.child;
......@@ -29727,7 +29734,7 @@ const InMemoryCoercionResult = union(enum) {
2972729734 },
2972829735 .missing_error => |missing_errors| {
2972929736 for (missing_errors) |err| {
29730 try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&pt.zcu.intern_pool)});
29737 try sema.errNote(src, msg, "'error.{f}' not a member of destination error set", .{err.fmt(&pt.zcu.intern_pool)});
2973129738 }
2973229739 break;
2973329740 },
......@@ -29780,7 +29787,7 @@ const InMemoryCoercionResult = union(enum) {
2978029787 break;
2978129788 },
2978229789 .fn_param => |param| {
29783 try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{
29790 try sema.errNote(src, msg, "parameter {d} '{f}' cannot cast into '{f}'", .{
2978429791 param.index, param.actual.fmt(pt), param.wanted.fmt(pt),
2978529792 });
2978629793 cur = param.child;
......@@ -29790,13 +29797,13 @@ const InMemoryCoercionResult = union(enum) {
2979029797 break;
2979129798 },
2979229799 .fn_return_type => |pair| {
29793 try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{
29800 try sema.errNote(src, msg, "return type '{f}' cannot cast into return type '{f}'", .{
2979429801 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2979529802 });
2979629803 cur = pair.child;
2979729804 },
2979829805 .ptr_child => |pair| {
29799 try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{
29806 try sema.errNote(src, msg, "pointer type child '{f}' cannot cast into pointer type child '{f}'", .{
2980029807 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2980129808 });
2980229809 cur = pair.child;
......@@ -29807,11 +29814,11 @@ const InMemoryCoercionResult = union(enum) {
2980729814 },
2980829815 .ptr_sentinel => |sentinel| {
2980929816 if (sentinel.actual.toIntern() != .unreachable_value) {
29810 try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
29817 try sema.errNote(src, msg, "pointer sentinel '{f}' cannot cast into pointer sentinel '{f}'", .{
2981129818 sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema),
2981229819 });
2981329820 } else {
29814 try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{
29821 try sema.errNote(src, msg, "destination pointer requires '{f}' sentinel", .{
2981529822 sentinel.wanted.fmtValueSema(pt, sema),
2981629823 });
2981729824 }
......@@ -29825,11 +29832,11 @@ const InMemoryCoercionResult = union(enum) {
2982529832 const wanted_allow_zero = pair.wanted.ptrAllowsZero(pt.zcu);
2982629833 const actual_allow_zero = pair.actual.ptrAllowsZero(pt.zcu);
2982729834 if (actual_allow_zero and !wanted_allow_zero) {
29828 try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{
29835 try sema.errNote(src, msg, "'{f}' could have null values which are illegal in type '{f}'", .{
2982929836 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2983029837 });
2983129838 } else {
29832 try sema.errNote(src, msg, "mutable '{}' would allow illegal null values stored to type '{}'", .{
29839 try sema.errNote(src, msg, "mutable '{f}' would allow illegal null values stored to type '{f}'", .{
2983329840 pair.wanted.fmt(pt), pair.actual.fmt(pt),
2983429841 });
2983529842 }
......@@ -29841,7 +29848,7 @@ const InMemoryCoercionResult = union(enum) {
2984129848 if (actual_const and !wanted_const) {
2984229849 try sema.errNote(src, msg, "cast discards const qualifier", .{});
2984329850 } else {
29844 try sema.errNote(src, msg, "mutable '{}' would allow illegal const pointers stored to type '{}'", .{
29851 try sema.errNote(src, msg, "mutable '{f}' would allow illegal const pointers stored to type '{f}'", .{
2984529852 pair.wanted.fmt(pt), pair.actual.fmt(pt),
2984629853 });
2984729854 }
......@@ -29853,7 +29860,7 @@ const InMemoryCoercionResult = union(enum) {
2985329860 if (actual_volatile and !wanted_volatile) {
2985429861 try sema.errNote(src, msg, "cast discards volatile qualifier", .{});
2985529862 } else {
29856 try sema.errNote(src, msg, "mutable '{}' would allow illegal volatile pointers stored to type '{}'", .{
29863 try sema.errNote(src, msg, "mutable '{f}' would allow illegal volatile pointers stored to type '{f}'", .{
2985729864 pair.wanted.fmt(pt), pair.actual.fmt(pt),
2985829865 });
2985929866 }
......@@ -29879,13 +29886,13 @@ const InMemoryCoercionResult = union(enum) {
2987929886 break;
2988029887 },
2988129888 .double_ptr_to_anyopaque => |pair| {
29882 try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
29889 try sema.errNote(src, msg, "cannot implicitly cast double pointer '{f}' to anyopaque pointer '{f}'", .{
2988329890 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2988429891 });
2988529892 break;
2988629893 },
2988729894 .slice_to_anyopaque => |pair| {
29888 try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{
29895 try sema.errNote(src, msg, "cannot implicitly cast slice '{f}' to anyopaque pointer '{f}'", .{
2988929896 pair.actual.fmt(pt), pair.wanted.fmt(pt),
2989029897 });
2989129898 try sema.errNote(src, msg, "consider using '.ptr'", .{});
......@@ -30659,7 +30666,7 @@ fn coerceVarArgParam(
3065930666 const coerced_ty = sema.typeOf(coerced);
3066030667 if (!try sema.validateExternType(coerced_ty, .param_ty)) {
3066130668 const msg = msg: {
30662 const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(pt)});
30669 const msg = try sema.errMsg(inst_src, "cannot pass '{f}' to variadic function", .{coerced_ty.fmt(pt)});
3066330670 errdefer msg.destroy(sema.gpa);
3066430671
3066530672 try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty);
......@@ -30762,7 +30769,7 @@ fn storePtr2(
3076230769 // is not comptime-only. We can hit this case with a `@ptrFromInt` pointer.
3076330770 if (try elem_ty.comptimeOnlySema(pt)) {
3076430771 return sema.failWithOwnedErrorMsg(block, msg: {
30765 const msg = try sema.errMsg(src, "cannot store comptime-only type '{}' at runtime", .{elem_ty.fmt(pt)});
30772 const msg = try sema.errMsg(src, "cannot store comptime-only type '{f}' at runtime", .{elem_ty.fmt(pt)});
3076630773 errdefer msg.destroy(sema.gpa);
3076730774 try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{});
3076830775 break :msg msg;
......@@ -30795,7 +30802,7 @@ fn storePtr2(
3079530802 });
3079630803 return;
3079730804 }
30798 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
30805 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{f}'", .{
3079930806 ptr_ty.fmt(pt),
3080030807 });
3080130808 }
......@@ -30964,19 +30971,19 @@ fn storePtrVal(
3096430971 .{},
3096530972 ),
3096630973 .undef => return sema.failWithUseOfUndef(block, src),
30967 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}),
30974 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {f}", .{err_name.fmt(ip)}),
3096830975 .null_payload => return sema.fail(block, src, "attempt to use null value", .{}),
3096930976 .inactive_union_field => return sema.fail(block, src, "access of inactive union field", .{}),
3097030977 .needed_well_defined => |ty| return sema.fail(
3097130978 block,
3097230979 src,
30973 "comptime dereference requires '{}' to have a well-defined layout",
30980 "comptime dereference requires '{f}' to have a well-defined layout",
3097430981 .{ty.fmt(pt)},
3097530982 ),
3097630983 .out_of_bounds => |ty| return sema.fail(
3097730984 block,
3097830985 src,
30979 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
30986 "dereference of '{f}' exceeds bounds of containing decl of type '{f}'",
3098030987 .{ ptr_ty.fmt(pt), ty.fmt(pt) },
3098130988 ),
3098230989 .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}),
......@@ -31002,7 +31009,7 @@ fn bitCast(
3100231009 const old_bits = old_ty.bitSize(zcu);
3100331010
3100431011 if (old_bits != dest_bits) {
31005 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{}' has {d} bits but source type '{}' has {d} bits", .{
31012 return sema.fail(block, inst_src, "@bitCast size mismatch: destination type '{f}' has {d} bits but source type '{f}' has {d} bits", .{
3100631013 dest_ty.fmt(pt),
3100731014 dest_bits,
3100831015 old_ty.fmt(pt),
......@@ -31120,7 +31127,7 @@ fn coerceCompatiblePtrs(
3112031127 const inst_ty = sema.typeOf(inst);
3112131128 if (try sema.resolveValue(inst)) |val| {
3112231129 if (!val.isUndef(zcu) and val.isNull(zcu) and !dest_ty.isAllowzeroPtr(zcu)) {
31123 return sema.fail(block, inst_src, "null pointer casted to type '{}'", .{dest_ty.fmt(pt)});
31130 return sema.fail(block, inst_src, "null pointer casted to type '{f}'", .{dest_ty.fmt(pt)});
3112431131 }
3112531132 // The comptime Value representation is compatible with both types.
3112631133 return Air.internedToRef(
......@@ -31166,7 +31173,7 @@ fn coerceEnumToUnion(
3116631173
3116731174 const tag_ty = union_ty.unionTagType(zcu) orelse {
3116831175 const msg = msg: {
31169 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31176 const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{
3117031177 union_ty.fmt(pt), inst_ty.fmt(pt),
3117131178 });
3117231179 errdefer msg.destroy(sema.gpa);
......@@ -31180,7 +31187,7 @@ fn coerceEnumToUnion(
3118031187 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
3118131188 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
3118231189 const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {
31183 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
31190 return sema.fail(block, inst_src, "union '{f}' has no tag with value '{f}'", .{
3118431191 union_ty.fmt(pt), val.fmtValueSema(pt, sema),
3118531192 });
3118631193 };
......@@ -31194,7 +31201,7 @@ fn coerceEnumToUnion(
3119431201 errdefer msg.destroy(sema.gpa);
3119531202
3119631203 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
31197 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{
31204 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
3119831205 field_name.fmt(ip),
3119931206 });
3120031207 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -31205,13 +31212,13 @@ fn coerceEnumToUnion(
3120531212 const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse {
3120631213 const msg = msg: {
3120731214 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
31208 const msg = try sema.errMsg(inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
31215 const msg = try sema.errMsg(inst_src, "coercion from enum '{f}' to union '{f}' must initialize '{f}' field '{f}'", .{
3120931216 inst_ty.fmt(pt), union_ty.fmt(pt),
3121031217 field_ty.fmt(pt), field_name.fmt(ip),
3121131218 });
3121231219 errdefer msg.destroy(sema.gpa);
3121331220
31214 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{
31221 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
3121531222 field_name.fmt(ip),
3121631223 });
3121731224 try sema.addDeclaredHereNote(msg, union_ty);
......@@ -31227,7 +31234,7 @@ fn coerceEnumToUnion(
3122731234
3122831235 if (tag_ty.isNonexhaustiveEnum(zcu)) {
3122931236 const msg = msg: {
31230 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{
31237 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{f}' from non-exhaustive enum", .{
3123131238 union_ty.fmt(pt),
3123231239 });
3123331240 errdefer msg.destroy(sema.gpa);
......@@ -31246,7 +31253,7 @@ fn coerceEnumToUnion(
3124631253 if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .noreturn) {
3124731254 const err_msg = msg orelse try sema.errMsg(
3124831255 inst_src,
31249 "runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field",
31256 "runtime coercion from enum '{f}' to union '{f}' which has a 'noreturn' field",
3125031257 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
3125131258 );
3125231259 msg = err_msg;
......@@ -31269,7 +31276,7 @@ fn coerceEnumToUnion(
3126931276 const msg = msg: {
3127031277 const msg = try sema.errMsg(
3127131278 inst_src,
31272 "runtime coercion from enum '{}' to union '{}' which has non-void fields",
31279 "runtime coercion from enum '{f}' to union '{f}' which has non-void fields",
3127331280 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
3127431281 );
3127531282 errdefer msg.destroy(sema.gpa);
......@@ -31278,7 +31285,7 @@ fn coerceEnumToUnion(
3127831285 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
3127931286 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
3128031287 if (!(try field_ty.hasRuntimeBitsSema(pt))) continue;
31281 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{
31288 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' has type '{f}'", .{
3128231289 field_name.fmt(ip),
3128331290 field_ty.fmt(pt),
3128431291 });
......@@ -31319,7 +31326,7 @@ fn coerceArrayLike(
3131931326 const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(zcu));
3132031327 if (dest_len != inst_len) {
3132131328 const msg = msg: {
31322 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31329 const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{
3132331330 dest_ty.fmt(pt), inst_ty.fmt(pt),
3132431331 });
3132531332 errdefer msg.destroy(sema.gpa);
......@@ -31407,7 +31414,7 @@ fn coerceTupleToArray(
3140731414
3140831415 if (dest_len != inst_len) {
3140931416 const msg = msg: {
31410 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
31417 const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{
3141131418 dest_ty.fmt(pt), inst_ty.fmt(pt),
3141231419 });
3141331420 errdefer msg.destroy(sema.gpa);
......@@ -31883,10 +31890,10 @@ fn analyzeLoad(
3188331890 const ptr_ty = sema.typeOf(ptr);
3188431891 const elem_ty = switch (ptr_ty.zigTypeTag(zcu)) {
3188531892 .pointer => ptr_ty.childType(zcu),
31886 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(pt)}),
31893 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),
3188731894 };
3188831895 if (elem_ty.zigTypeTag(zcu) == .@"opaque") {
31889 return sema.fail(block, ptr_src, "cannot load opaque type '{}'", .{elem_ty.fmt(pt)});
31896 return sema.fail(block, ptr_src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)});
3189031897 }
3189131898
3189231899 if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| {
......@@ -31907,7 +31914,7 @@ fn analyzeLoad(
3190731914 const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data;
3190831915 return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs);
3190931916 }
31910 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{}'", .{
31917 return sema.fail(block, ptr_src, "unable to determine vector element index of type '{f}'", .{
3191131918 ptr_ty.fmt(pt),
3191231919 });
3191331920 }
......@@ -32195,7 +32202,7 @@ fn analyzeSlice(
3219532202 const ptr_ptr_ty = sema.typeOf(ptr_ptr);
3219632203 const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(zcu)) {
3219732204 .pointer => ptr_ptr_ty.childType(zcu),
32198 else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(pt)}),
32205 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ptr_ty.fmt(pt)}),
3219932206 };
3220032207
3220132208 var array_ty = ptr_ptr_child_ty;
......@@ -32244,7 +32251,7 @@ fn analyzeSlice(
3224432251 try sema.errNote(
3224532252 start_src,
3224632253 msg,
32247 "expected '{}', found '{}'",
32254 "expected '{f}', found '{f}'",
3224832255 .{
3224932256 Value.zero_comptime_int.fmtValueSema(pt, sema),
3225032257 start_value.fmtValueSema(pt, sema),
......@@ -32260,7 +32267,7 @@ fn analyzeSlice(
3226032267 try sema.errNote(
3226132268 end_src,
3226232269 msg,
32263 "expected '{}', found '{}'",
32270 "expected '{f}', found '{f}'",
3226432271 .{
3226532272 Value.one_comptime_int.fmtValueSema(pt, sema),
3226632273 end_value.fmtValueSema(pt, sema),
......@@ -32275,7 +32282,7 @@ fn analyzeSlice(
3227532282 return sema.fail(
3227632283 block,
3227732284 end_src,
32278 "end index {} out of bounds for slice of single-item pointer",
32285 "end index {f} out of bounds for slice of single-item pointer",
3227932286 .{end_value.fmtValueSema(pt, sema)},
3228032287 );
3228132288 }
......@@ -32322,7 +32329,7 @@ fn analyzeSlice(
3232232329 elem_ty = ptr_ptr_child_ty.childType(zcu);
3232332330 },
3232432331 },
32325 else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(pt)}),
32332 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),
3232632333 }
3232732334
3232832335 const ptr = if (slice_ty.isSlice(zcu))
......@@ -32369,7 +32376,7 @@ fn analyzeSlice(
3236932376 return sema.fail(
3237032377 block,
3237132378 end_src,
32372 "end index {} out of bounds for array of length {}{s}",
32379 "end index {f} out of bounds for array of length {f}{s}",
3237332380 .{
3237432381 end_val.fmtValueSema(pt, sema),
3237532382 len_val.fmtValueSema(pt, sema),
......@@ -32414,7 +32421,7 @@ fn analyzeSlice(
3241432421 return sema.fail(
3241532422 block,
3241632423 end_src,
32417 "end index {} out of bounds for slice of length {d}{s}",
32424 "end index {f} out of bounds for slice of length {d}{s}",
3241832425 .{
3241932426 end_val.fmtValueSema(pt, sema),
3242032427 try slice_val.sliceLen(pt),
......@@ -32473,7 +32480,7 @@ fn analyzeSlice(
3247332480 return sema.fail(
3247432481 block,
3247532482 start_src,
32476 "start index {} is larger than end index {}",
32483 "start index {f} is larger than end index {f}",
3247732484 .{
3247832485 start_val.fmtValueSema(pt, sema),
3247932486 end_val.fmtValueSema(pt, sema),
......@@ -32497,13 +32504,13 @@ fn analyzeSlice(
3249732504 .needed_well_defined => |ty| return sema.fail(
3249832505 block,
3249932506 src,
32500 "comptime dereference requires '{}' to have a well-defined layout",
32507 "comptime dereference requires '{f}' to have a well-defined layout",
3250132508 .{ty.fmt(pt)},
3250232509 ),
3250332510 .out_of_bounds => |ty| return sema.fail(
3250432511 block,
3250532512 end_src,
32506 "slice end index {d} exceeds bounds of containing decl of type '{}'",
32513 "slice end index {d} exceeds bounds of containing decl of type '{f}'",
3250732514 .{ end_int, ty.fmt(pt) },
3250832515 ),
3250932516 };
......@@ -32512,7 +32519,7 @@ fn analyzeSlice(
3251232519 const msg = msg: {
3251332520 const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});
3251432521 errdefer msg.destroy(sema.gpa);
32515 try sema.errNote(src, msg, "expected '{}', found '{}'", .{
32522 try sema.errNote(src, msg, "expected '{f}', found '{f}'", .{
3251632523 expected_sentinel.fmtValueSema(pt, sema),
3251732524 actual_sentinel.fmtValueSema(pt, sema),
3251832525 });
......@@ -33400,7 +33407,7 @@ const PeerResolveResult = union(enum) {
3340033407 };
3340133408 },
3340233409 .field_error => |field_error| {
33403 const fmt = "struct field '{}' has conflicting types";
33410 const fmt = "struct field '{f}' has conflicting types";
3340433411 const args = .{field_error.field_name.fmt(&pt.zcu.intern_pool)};
3340533412 if (opt_msg) |msg| {
3340633413 try sema.errNote(src, msg, fmt, args);
......@@ -33431,7 +33438,7 @@ const PeerResolveResult = union(enum) {
3343133438 candidate_srcs.resolve(block, conflict_idx[1]),
3343233439 };
3343333440
33434 const fmt = "incompatible types: '{}' and '{}'";
33441 const fmt = "incompatible types: '{f}' and '{f}'";
3343533442 const args = .{
3343633443 conflict_tys[0].fmt(pt),
3343733444 conflict_tys[1].fmt(pt),
......@@ -33445,8 +33452,8 @@ const PeerResolveResult = union(enum) {
3344533452 break :msg msg;
3344633453 };
3344733454
33448 if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(pt)});
33449 if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(pt)});
33455 if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{f}' here", .{conflict_tys[0].fmt(pt)});
33456 if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{f}' here", .{conflict_tys[1].fmt(pt)});
3345033457
3345133458 // No child error
3345233459 break;
......@@ -34758,7 +34765,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3475834765 if (struct_type.setLayoutWip(ip)) {
3475934766 const msg = try sema.errMsg(
3476034767 ty.srcLoc(zcu),
34761 "struct '{}' depends on itself",
34768 "struct '{f}' depends on itself",
3476234769 .{ty.fmt(pt)},
3476334770 );
3476434771 return sema.failWithOwnedErrorMsg(null, msg);
......@@ -34977,13 +34984,13 @@ fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_
3497734984 const zcu = pt.zcu;
3497834985
3497934986 if (!backing_int_ty.isInt(zcu)) {
34980 return sema.fail(block, src, "expected backing integer type, found '{}'", .{backing_int_ty.fmt(pt)});
34987 return sema.fail(block, src, "expected backing integer type, found '{f}'", .{backing_int_ty.fmt(pt)});
3498134988 }
3498234989 if (backing_int_ty.bitSize(zcu) != fields_bit_sum) {
3498334990 return sema.fail(
3498434991 block,
3498534992 src,
34986 "backing integer type '{}' has bit size {} but the struct fields have a total bit size of {}",
34993 "backing integer type '{f}' has bit size {} but the struct fields have a total bit size of {}",
3498734994 .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(zcu), fields_bit_sum },
3498834995 );
3498934996 }
......@@ -34993,7 +35000,7 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
3499335000 const pt = sema.pt;
3499435001 if (!ty.isIndexable(pt.zcu)) {
3499535002 const msg = msg: {
34996 const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(pt)});
35003 const msg = try sema.errMsg(src, "type '{f}' does not support indexing", .{ty.fmt(pt)});
3499735004 errdefer msg.destroy(sema.gpa);
3499835005 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
3499935006 break :msg msg;
......@@ -35017,7 +35024,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
3501735024 }
3501835025 }
3501935026 const msg = msg: {
35020 const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(pt)});
35027 const msg = try sema.errMsg(src, "type '{f}' is not an indexable pointer", .{ty.fmt(pt)});
3502135028 errdefer msg.destroy(sema.gpa);
3502235029 try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
3502335030 break :msg msg;
......@@ -35085,7 +35092,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3508535092 .field_types_wip, .layout_wip => {
3508635093 const msg = try sema.errMsg(
3508735094 ty.srcLoc(pt.zcu),
35088 "union '{}' depends on itself",
35095 "union '{f}' depends on itself",
3508935096 .{ty.fmt(pt)},
3509035097 );
3509135098 return sema.failWithOwnedErrorMsg(null, msg);
......@@ -35273,7 +35280,7 @@ pub fn resolveStructFieldTypes(
3527335280 if (struct_type.setFieldTypesWip(ip)) {
3527435281 const msg = try sema.errMsg(
3527535282 Type.fromInterned(ty).srcLoc(zcu),
35276 "struct '{}' depends on itself",
35283 "struct '{f}' depends on itself",
3527735284 .{Type.fromInterned(ty).fmt(pt)},
3527835285 );
3527935286 return sema.failWithOwnedErrorMsg(null, msg);
......@@ -35302,7 +35309,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3530235309 if (struct_type.setInitsWip(ip)) {
3530335310 const msg = try sema.errMsg(
3530435311 ty.srcLoc(zcu),
35305 "struct '{}' depends on itself",
35312 "struct '{f}' depends on itself",
3530635313 .{ty.fmt(pt)},
3530735314 );
3530835315 return sema.failWithOwnedErrorMsg(null, msg);
......@@ -35328,7 +35335,7 @@ pub fn resolveUnionFieldTypes(sema: *Sema, ty: Type, union_type: InternPool.Load
3532835335 .field_types_wip => {
3532935336 const msg = try sema.errMsg(
3533035337 ty.srcLoc(zcu),
35331 "union '{}' depends on itself",
35338 "union '{f}' depends on itself",
3533235339 .{ty.fmt(pt)},
3533335340 );
3533435341 return sema.failWithOwnedErrorMsg(null, msg);
......@@ -35698,7 +35705,7 @@ fn structFields(
3569835705 switch (struct_type.layout) {
3569935706 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
3570035707 const msg = msg: {
35701 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
35708 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
3570235709 errdefer msg.destroy(sema.gpa);
3570335710
3570435711 try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);
......@@ -35710,7 +35717,7 @@ fn structFields(
3571035717 },
3571135718 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
3571235719 const msg = msg: {
35713 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
35720 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
3571435721 errdefer msg.destroy(sema.gpa);
3571535722
3571635723 try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);
......@@ -35957,7 +35964,7 @@ fn unionFields(
3595735964 // The provided type is an integer type and we must construct the enum tag type here.
3595835965 int_tag_ty = provided_ty;
3595935966 if (int_tag_ty.zigTypeTag(zcu) != .int and int_tag_ty.zigTypeTag(zcu) != .comptime_int) {
35960 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(pt)});
35967 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{f}'", .{int_tag_ty.fmt(pt)});
3596135968 }
3596235969
3596335970 if (fields_len > 0) {
......@@ -35966,7 +35973,7 @@ fn unionFields(
3596635973 const msg = msg: {
3596735974 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});
3596835975 errdefer msg.destroy(sema.gpa);
35969 try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{
35976 try sema.errNote(tag_ty_src, msg, "type '{f}' cannot fit values in range 0...{d}", .{
3597035977 int_tag_ty.fmt(pt),
3597135978 fields_len - 1,
3597235979 });
......@@ -35981,7 +35988,7 @@ fn unionFields(
3598135988 // The provided type is the enum tag type.
3598235989 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {
3598335990 .enum_type => ip.loadEnumType(provided_ty.toIntern()),
35984 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(pt)}),
35991 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{f}'", .{provided_ty.fmt(pt)}),
3598535992 };
3598635993 union_type.setTagType(ip, provided_ty.toIntern());
3598735994 // The fields of the union must match the enum exactly.
......@@ -36078,7 +36085,7 @@ fn unionFields(
3607836085 if (result.overflow) return sema.fail(
3607936086 &block_scope,
3608036087 value_src,
36081 "enumeration value '{}' too large for type '{}'",
36088 "enumeration value '{f}' too large for type '{f}'",
3608236089 .{ result.val.fmtValueSema(pt, sema), int_tag_ty.fmt(pt) },
3608336090 );
3608436091 last_tag_val = result.val;
......@@ -36096,7 +36103,7 @@ fn unionFields(
3609636103 const msg = msg: {
3609736104 const msg = try sema.errMsg(
3609836105 value_src,
36099 "enum tag value {} already taken",
36106 "enum tag value {f} already taken",
3610036107 .{enum_tag_val.fmtValueSema(pt, sema)},
3610136108 );
3610236109 errdefer msg.destroy(gpa);
......@@ -36124,7 +36131,7 @@ fn unionFields(
3612436131 const tag_ty = union_type.tagTypeUnordered(ip);
3612536132 const tag_info = ip.loadEnumType(tag_ty);
3612636133 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
36127 return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{
36134 return sema.fail(&block_scope, name_src, "no field named '{f}' in enum '{f}'", .{
3612836135 field_name.fmt(ip), Type.fromInterned(tag_ty).fmt(pt),
3612936136 });
3613036137 };
......@@ -36141,7 +36148,7 @@ fn unionFields(
3614136148 .base_node_inst = Type.fromInterned(tag_ty).typeDeclInstAllowGeneratedTag(zcu).?,
3614236149 .offset = .{ .container_field_name = enum_index },
3614336150 };
36144 const msg = try sema.errMsg(name_src, "union field '{}' ordered differently than corresponding enum field", .{
36151 const msg = try sema.errMsg(name_src, "union field '{f}' ordered differently than corresponding enum field", .{
3614536152 field_name.fmt(ip),
3614636153 });
3614736154 errdefer msg.destroy(sema.gpa);
......@@ -36167,7 +36174,7 @@ fn unionFields(
3616736174 !try sema.validateExternType(field_ty, .union_field))
3616836175 {
3616936176 const msg = msg: {
36170 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
36177 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
3617136178 errdefer msg.destroy(sema.gpa);
3617236179
3617336180 try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);
......@@ -36178,7 +36185,7 @@ fn unionFields(
3617836185 return sema.failWithOwnedErrorMsg(&block_scope, msg);
3617936186 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
3618036187 const msg = msg: {
36181 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(pt)});
36188 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
3618236189 errdefer msg.destroy(sema.gpa);
3618336190
3618436191 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);
......@@ -36214,7 +36221,7 @@ fn unionFields(
3621436221
3621536222 for (tag_info.names.get(ip), 0..) |field_name, field_index| {
3621636223 if (explicit_tags_seen[field_index]) continue;
36217 try sema.addFieldErrNote(.fromInterned(tag_ty), field_index, msg, "field '{}' missing, declared here", .{
36224 try sema.addFieldErrNote(.fromInterned(tag_ty), field_index, msg, "field '{f}' missing, declared here", .{
3621836225 field_name.fmt(ip),
3621936226 });
3622036227 }
......@@ -36250,7 +36257,7 @@ fn generateUnionTagTypeNumbered(
3625036257 const name = try ip.getOrPutStringFmt(
3625136258 gpa,
3625236259 pt.tid,
36253 "@typeInfo({}).@\"union\".tag_type.?",
36260 "@typeInfo({f}).@\"union\".tag_type.?",
3625436261 .{union_name.fmt(ip)},
3625536262 .no_embedded_nulls,
3625636263 );
......@@ -36286,7 +36293,7 @@ fn generateUnionTagTypeSimple(
3628636293 const name = try ip.getOrPutStringFmt(
3628736294 gpa,
3628836295 pt.tid,
36289 "@typeInfo({}).@\"union\".tag_type.?",
36296 "@typeInfo({f}).@\"union\".tag_type.?",
3629036297 .{union_name.fmt(ip)},
3629136298 .no_embedded_nulls,
3629236299 );
......@@ -36820,13 +36827,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
3682036827 .needed_well_defined => |ty| return sema.fail(
3682136828 block,
3682236829 src,
36823 "comptime dereference requires '{}' to have a well-defined layout",
36830 "comptime dereference requires '{f}' to have a well-defined layout",
3682436831 .{ty.fmt(pt)},
3682536832 ),
3682636833 .out_of_bounds => |ty| return sema.fail(
3682736834 block,
3682836835 src,
36829 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
36836 "dereference of '{f}' exceeds bounds of containing decl of type '{f}'",
3683036837 .{ ptr_ty.fmt(pt), ty.fmt(pt) },
3683136838 ),
3683236839 }
......@@ -36846,7 +36853,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value
3684636853 .success => |mv| return .{ .val = try mv.intern(pt, sema.arena) },
3684736854 .runtime_load => return .runtime_load,
3684836855 .undef => return sema.failWithUseOfUndef(block, src),
36849 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {}", .{err_name.fmt(ip)}),
36856 .err_payload => |err_name| return sema.fail(block, src, "attempt to unwrap error: {f}", .{err_name.fmt(ip)}),
3685036857 .null_payload => return sema.fail(block, src, "attempt to use null value", .{}),
3685136858 .inactive_union_field => return sema.fail(block, src, "access of inactive union field", .{}),
3685236859 .needed_well_defined => |ty| return .{ .needed_well_defined = ty },
......@@ -36971,12 +36978,12 @@ fn intFromFloatScalar(
3697136978
3697236979 const float = val.toFloat(f128, zcu);
3697336980 if (std.math.isNan(float)) {
36974 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{
36981 return sema.fail(block, src, "float value NaN cannot be stored in integer type '{f}'", .{
3697536982 int_ty.fmt(pt),
3697636983 });
3697736984 }
3697836985 if (std.math.isInf(float)) {
36979 return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{
36986 return sema.fail(block, src, "float value Inf cannot be stored in integer type '{f}'", .{
3698036987 int_ty.fmt(pt),
3698136988 });
3698236989 }
......@@ -36991,7 +36998,7 @@ fn intFromFloatScalar(
3699136998 .exact => return sema.fail(
3699236999 block,
3699337000 src,
36994 "fractional component prevents float value '{}' from coercion to type '{}'",
37001 "fractional component prevents float value '{f}' from coercion to type '{f}'",
3699537002 .{ val.fmtValueSema(pt, sema), int_ty.fmt(pt) },
3699637003 ),
3699737004 .truncate => {},
......@@ -37003,7 +37010,7 @@ fn intFromFloatScalar(
3700337010
3700437011 const int_info = int_ty.intInfo(zcu);
3700537012 if (!big_int.toConst().fitsInTwosComp(int_info.signedness, int_info.bits)) {
37006 return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{
37013 return sema.fail(block, src, "float value '{f}' cannot be stored in integer type '{f}'", .{
3700737014 val.fmtValueSema(pt, sema), int_ty.fmt(pt),
3700837015 });
3700937016 }
......@@ -37335,9 +37342,9 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc,
3733537342
3733637343 var first_path: std.ArrayListUnmanaged(u8) = .empty;
3733737344 if (intermediate_value_count == 0) {
37338 try first_path.writer(arena).print("{i}", .{start_value_name.fmt(ip)});
37345 try first_path.print(arena, "{fi}", .{start_value_name.fmt(ip)});
3733937346 } else {
37340 try first_path.writer(arena).print("v{}", .{intermediate_value_count - 1});
37347 try first_path.print(arena, "v{}", .{intermediate_value_count - 1});
3734137348 }
3734237349
3734337350 const comptime_ptr = try sema.notePathToComptimeAllocPtrInner(val, &first_path);
......@@ -37362,30 +37369,26 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc,
3736237369 error.AnalysisFail => unreachable,
3736337370 };
3736437371
37365 var second_path: std.ArrayListUnmanaged(u8) = .empty;
37372 var second_path_aw: std.io.AllocatingWriter = undefined;
37373 second_path_aw.init(arena);
3736637374 const inter_name = try std.fmt.allocPrint(arena, "v{d}", .{intermediate_value_count});
3736737375 const deriv_start = @import("print_value.zig").printPtrDerivation(
3736837376 derivation,
37369 second_path.writer(arena),
37377 &second_path_aw.buffered_writer,
3737037378 pt,
3737137379 .lvalue,
3737237380 .{ .str = inter_name },
3737337381 20,
37374 ) catch |err| switch (err) {
37375 error.OutOfMemory => |e| return e,
37376 error.AnalysisFail => unreachable,
37377 error.ComptimeReturn => unreachable,
37378 error.ComptimeBreak => unreachable,
37379 };
37382 ) catch |err| return @errorCast(err);
3738037383
3738137384 switch (deriv_start) {
3738237385 .int, .nav_ptr => unreachable,
3738337386 .uav_ptr => |uav| {
37384 try sema.errNote(src, msg, "'{s}' points to '{s}', where", .{ first_path.items, second_path.items });
37387 try sema.errNote(src, msg, "'{s}' points to '{s}', where", .{ first_path.items, second_path_aw.getWritten() });
3738537388 return .{ .new_val = .fromInterned(uav.val) };
3738637389 },
3738737390 .comptime_alloc_ptr => |cta_info| {
37388 try sema.errNote(src, msg, "'{s}' points to '{s}', where", .{ first_path.items, second_path.items });
37391 try sema.errNote(src, msg, "'{s}' points to '{s}', where", .{ first_path.items, second_path_aw.getWritten() });
3738937392 const cta = sema.getComptimeAlloc(cta_info.idx);
3739037393 if (cta.is_const) {
3739137394 return .{ .new_val = cta_info.val };
......@@ -37395,7 +37398,7 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc,
3739537398 }
3739637399 },
3739737400 .comptime_field_ptr => {
37398 try sema.errNote(src, msg, "'{s}' points to '{s}', where", .{ first_path.items, second_path.items });
37401 try sema.errNote(src, msg, "'{s}' points to '{s}', where", .{ first_path.items, second_path_aw.getWritten() });
3739937402 try sema.errNote(src, msg, "'{s}' is a comptime field", .{inter_name});
3740037403 return .done;
3740137404 },
......@@ -37435,7 +37438,7 @@ fn notePathToComptimeAllocPtrInner(sema: *Sema, val: Value, path: *std.ArrayList
3743537438 const backing_enum = union_ty.unionTagTypeHypothetical(zcu);
3743637439 const field_idx = backing_enum.enumTagFieldIndex(.fromInterned(un.tag), zcu).?;
3743737440 const field_name = backing_enum.enumFieldName(field_idx, zcu);
37438 try path.writer(arena).print(".{i}", .{field_name.fmt(ip)});
37441 try path.print(arena, ".{fi}", .{field_name.fmt(ip)});
3743937442 return sema.notePathToComptimeAllocPtrInner(.fromInterned(un.val), path);
3744037443 },
3744137444 .aggregate => |agg| {
......@@ -37450,17 +37453,17 @@ fn notePathToComptimeAllocPtrInner(sema: *Sema, val: Value, path: *std.ArrayList
3745037453 };
3745137454 const agg_ty: Type = .fromInterned(agg.ty);
3745237455 switch (agg_ty.zigTypeTag(zcu)) {
37453 .array, .vector => try path.writer(arena).print("[{d}]", .{elem_idx}),
37456 .array, .vector => try path.print(arena, "[{d}]", .{elem_idx}),
3745437457 .pointer => switch (elem_idx) {
3745537458 Value.slice_ptr_index => try path.appendSlice(arena, ".ptr"),
3745637459 Value.slice_len_index => try path.appendSlice(arena, ".len"),
3745737460 else => unreachable,
3745837461 },
3745937462 .@"struct" => if (agg_ty.isTuple(zcu)) {
37460 try path.writer(arena).print("[{d}]", .{elem_idx});
37463 try path.print(arena, "[{d}]", .{elem_idx});
3746137464 } else {
3746237465 const name = agg_ty.structFieldName(elem_idx, zcu).unwrap().?;
37463 try path.writer(arena).print(".{i}", .{name.fmt(ip)});
37466 try path.print(arena, ".{fi}", .{name.fmt(ip)});
3746437467 },
3746537468 else => unreachable,
3746637469 }
......@@ -37737,7 +37740,7 @@ fn resolveDeclaredEnumInner(
3773737740 if (tag_type_ref != .none) {
3773837741 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
3773937742 if (ty.zigTypeTag(zcu) != .int and ty.zigTypeTag(zcu) != .comptime_int) {
37740 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(pt)});
37743 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{f}'", .{ty.fmt(pt)});
3774137744 }
3774237745 break :ty ty;
3774337746 } else if (fields_len == 0) {
......@@ -37791,7 +37794,7 @@ fn resolveDeclaredEnumInner(
3779137794 .offset = .{ .container_field_value = conflict.prev_field_idx },
3779237795 };
3779337796 const msg = msg: {
37794 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
37797 const msg = try sema.errMsg(value_src, "enum tag value {f} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
3779537798 errdefer msg.destroy(gpa);
3779637799 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3779737800 break :msg msg;
......@@ -37814,7 +37817,7 @@ fn resolveDeclaredEnumInner(
3781437817 .offset = .{ .container_field_value = conflict.prev_field_idx },
3781537818 };
3781637819 const msg = msg: {
37817 const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
37820 const msg = try sema.errMsg(value_src, "enum tag value {f} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
3781837821 errdefer msg.destroy(gpa);
3781937822 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
3782037823 break :msg msg;
......@@ -37831,7 +37834,7 @@ fn resolveDeclaredEnumInner(
3783137834 };
3783237835
3783337836 if (tag_overflow) {
37834 const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{
37837 const msg = try sema.errMsg(value_src, "enumeration value '{f}' too large for type '{f}'", .{
3783537838 last_tag_val.?.fmtValueSema(pt, sema), int_tag_ty.fmt(pt),
3783637839 });
3783737840 return sema.failWithOwnedErrorMsg(block, msg);
src/Sema/LowerZon.zig+16-16
......@@ -338,7 +338,7 @@ fn failUnsupportedResultType(
338338 const gpa = sema.gpa;
339339 const pt = sema.pt;
340340 return sema.failWithOwnedErrorMsg(self.block, msg: {
341 const msg = try sema.errMsg(self.import_loc, "type '{}' is not available in ZON", .{ty.fmt(pt)});
341 const msg = try sema.errMsg(self.import_loc, "type '{f}' is not available in ZON", .{ty.fmt(pt)});
342342 errdefer msg.destroy(gpa);
343343 if (opt_note) |n| try sema.errNote(self.import_loc, msg, "{s}", .{n});
344344 break :msg msg;
......@@ -362,7 +362,7 @@ fn lowerExprKnownResTy(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) Com
362362 return self.lowerExprKnownResTyInner(node, res_ty) catch |err| switch (err) {
363363 error.WrongType => return self.fail(
364364 node,
365 "expected type '{}'",
365 "expected type '{f}'",
366366 .{res_ty.fmt(pt)},
367367 ),
368368 else => |e| return e,
......@@ -428,7 +428,7 @@ fn lowerExprKnownResTyInner(
428428 .frame,
429429 .@"anyframe",
430430 .void,
431 => return self.fail(node, "type '{}' not available in ZON", .{res_ty.fmt(pt)}),
431 => return self.fail(node, "type '{f}' not available in ZON", .{res_ty.fmt(pt)}),
432432 }
433433}
434434
......@@ -458,7 +458,7 @@ fn lowerInt(
458458 // If lhs is unsigned and rhs is less than 0, we're out of bounds
459459 if (lhs_info.signedness == .unsigned and rhs < 0) return self.fail(
460460 node,
461 "type '{}' cannot represent integer value '{}'",
461 "type '{f}' cannot represent integer value '{}'",
462462 .{ res_ty.fmt(self.sema.pt), rhs },
463463 );
464464
......@@ -478,7 +478,7 @@ fn lowerInt(
478478 if (rhs < min_int or rhs > max_int) {
479479 return self.fail(
480480 node,
481 "type '{}' cannot represent integer value '{}'",
481 "type '{f}' cannot represent integer value '{}'",
482482 .{ res_ty.fmt(self.sema.pt), rhs },
483483 );
484484 }
......@@ -496,7 +496,7 @@ fn lowerInt(
496496 if (!val.fitsInTwosComp(int_info.signedness, int_info.bits)) {
497497 return self.fail(
498498 node,
499 "type '{}' cannot represent integer value '{}'",
499 "type '{f}' cannot represent integer value '{f}'",
500500 .{ res_ty.fmt(self.sema.pt), val },
501501 );
502502 }
......@@ -517,7 +517,7 @@ fn lowerInt(
517517 switch (big_int.setFloat(val, .trunc)) {
518518 .inexact => return self.fail(
519519 node,
520 "fractional component prevents float value '{}' from coercion to type '{}'",
520 "fractional component prevents float value '{}' from coercion to type '{f}'",
521521 .{ val, res_ty.fmt(self.sema.pt) },
522522 ),
523523 .exact => {},
......@@ -528,7 +528,7 @@ fn lowerInt(
528528 if (!big_int.toConst().fitsInTwosComp(int_info.signedness, int_info.bits)) {
529529 return self.fail(
530530 node,
531 "type '{}' cannot represent integer value '{}'",
531 "type '{}' cannot represent integer value '{f}'",
532532 .{ val, res_ty.fmt(self.sema.pt) },
533533 );
534534 }
......@@ -550,7 +550,7 @@ fn lowerInt(
550550 if (val >= out_of_range) {
551551 return self.fail(
552552 node,
553 "type '{}' cannot represent integer value '{}'",
553 "type '{f}' cannot represent integer value '{}'",
554554 .{ res_ty.fmt(self.sema.pt), val },
555555 );
556556 }
......@@ -584,7 +584,7 @@ fn lowerFloat(
584584 .pos_inf => b: {
585585 if (res_ty.toIntern() == .comptime_float_type) return self.fail(
586586 node,
587 "expected type '{}'",
587 "expected type '{f}'",
588588 .{res_ty.fmt(self.sema.pt)},
589589 );
590590 break :b try self.sema.pt.floatValue(res_ty, std.math.inf(f128));
......@@ -592,7 +592,7 @@ fn lowerFloat(
592592 .neg_inf => b: {
593593 if (res_ty.toIntern() == .comptime_float_type) return self.fail(
594594 node,
595 "expected type '{}'",
595 "expected type '{f}'",
596596 .{res_ty.fmt(self.sema.pt)},
597597 );
598598 break :b try self.sema.pt.floatValue(res_ty, -std.math.inf(f128));
......@@ -600,7 +600,7 @@ fn lowerFloat(
600600 .nan => b: {
601601 if (res_ty.toIntern() == .comptime_float_type) return self.fail(
602602 node,
603 "expected type '{}'",
603 "expected type '{f}'",
604604 .{res_ty.fmt(self.sema.pt)},
605605 );
606606 break :b try self.sema.pt.floatValue(res_ty, std.math.nan(f128));
......@@ -661,7 +661,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
661661 const field_index = res_ty.enumFieldIndex(field_name_interned, self.sema.pt.zcu) orelse {
662662 return self.fail(
663663 node,
664 "enum {} has no member named '{}'",
664 "enum {f} has no member named '{f}'",
665665 .{
666666 res_ty.fmt(self.sema.pt),
667667 std.zig.fmtId(field_name.get(self.file.zoir.?)),
......@@ -795,7 +795,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
795795 const field_node = fields.vals.at(@intCast(i));
796796
797797 const name_index = struct_info.nameIndex(ip, field_name) orelse {
798 return self.fail(field_node, "unexpected field '{}'", .{field_name.fmt(ip)});
798 return self.fail(field_node, "unexpected field '{f}'", .{field_name.fmt(ip)});
799799 };
800800
801801 const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);
......@@ -816,7 +816,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
816816
817817 const field_names = struct_info.field_names.get(ip);
818818 for (field_values, field_names) |*value, name| {
819 if (value.* == .none) return self.fail(node, "missing field '{}'", .{name.fmt(ip)});
819 if (value.* == .none) return self.fail(node, "missing field '{f}'", .{name.fmt(ip)});
820820 }
821821
822822 return self.sema.pt.intern(.{ .aggregate = .{
......@@ -934,7 +934,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
934934 .struct_literal => b: {
935935 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {
936936 .struct_literal => |fields| fields,
937 else => return self.fail(node, "expected type '{}'", .{res_ty.fmt(self.sema.pt)}),
937 else => return self.fail(node, "expected type '{f}'", .{res_ty.fmt(self.sema.pt)}),
938938 };
939939 if (fields.names.len != 1) {
940940 return error.WrongType;
src/Type.zig+67-91
......@@ -142,9 +142,9 @@ const FormatContext = struct {
142142 pt: Zcu.PerThread,
143143};
144144
145fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) anyerror!usize {
145fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) anyerror!void {
146146 comptime assert(f.len == 0);
147 return print(ctx.ty, bw, ctx.pt);
147 try print(ctx.ty, bw, ctx.pt);
148148}
149149
150150pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
......@@ -153,20 +153,14 @@ pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
153153
154154/// This is a debug function. In order to print types in a meaningful way
155155/// we also need access to the module.
156pub fn dump(
157 start_type: Type,
158 comptime unused_format_string: []const u8,
159 options: std.fmt.FormatOptions,
160 writer: anytype,
161) @TypeOf(writer).Error!void {
162 _ = options;
156pub fn dump(start_type: Type, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
163157 comptime assert(unused_format_string.len == 0);
164 return writer.print("{any}", .{start_type.ip_index});
158 return bw.print("{any}", .{start_type.ip_index});
165159}
166160
167161/// Prints a name suitable for `@typeName`.
168162/// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels.
169pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!usize {
163pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!void {
170164 const zcu = pt.zcu;
171165 const ip = &zcu.intern_pool;
172166 switch (ip.indexToKey(ty.toIntern())) {
......@@ -176,23 +170,22 @@ pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!u
176170 .signed => 'i',
177171 .unsigned => 'u',
178172 };
179 return bw.print("{c}{d}", .{ sign_char, int_type.bits });
173 try bw.print("{c}{d}", .{ sign_char, int_type.bits });
180174 },
181175 .ptr_type => {
182 var n: usize = 0;
183176 const info = ty.ptrInfo(zcu);
184177
185178 if (info.sentinel != .none) switch (info.flags.size) {
186179 .one, .c => unreachable,
187 .many => n += try bw.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}),
188 .slice => n += try bw.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}),
180 .many => try bw.print("[*:{f}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}),
181 .slice => try bw.print("[:{f}]", .{Value.fromInterned(info.sentinel).fmtValue(pt)}),
189182 } else switch (info.flags.size) {
190 .one => n += try bw.writeAll("*"),
191 .many => n += try bw.writeAll("[*]"),
192 .c => n += try bw.writeAll("[*c]"),
193 .slice => n += try bw.writeAll("[]"),
183 .one => try bw.writeAll("*"),
184 .many => try bw.writeAll("[*]"),
185 .c => try bw.writeAll("[*c]"),
186 .slice => try bw.writeAll("[]"),
194187 }
195 if (info.flags.is_allowzero and info.flags.size != .c) n += try bw.writeAll("allowzero ");
188 if (info.flags.is_allowzero and info.flags.size != .c) try bw.writeAll("allowzero ");
196189 if (info.flags.alignment != .none or
197190 info.packed_offset.host_size != 0 or
198191 info.flags.vector_index != .none)
......@@ -201,83 +194,72 @@ pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!u
201194 info.flags.alignment
202195 else
203196 Type.fromInterned(info.child).abiAlignment(pt.zcu);
204 n += try bw.print("align({d}", .{alignment.toByteUnits() orelse 0});
197 try bw.print("align({d}", .{alignment.toByteUnits() orelse 0});
205198
206199 if (info.packed_offset.bit_offset != 0 or info.packed_offset.host_size != 0) {
207 n += try bw.print(":{d}:{d}", .{
200 try bw.print(":{d}:{d}", .{
208201 info.packed_offset.bit_offset, info.packed_offset.host_size,
209202 });
210203 }
211204 if (info.flags.vector_index == .runtime) {
212 n += try bw.writeAll(":?");
205 try bw.writeAll(":?");
213206 } else if (info.flags.vector_index != .none) {
214 n += try bw.print(":{d}", .{@intFromEnum(info.flags.vector_index)});
207 try bw.print(":{d}", .{@intFromEnum(info.flags.vector_index)});
215208 }
216 n += try bw.writeAll(") ");
209 try bw.writeAll(") ");
217210 }
218211 if (info.flags.address_space != .generic) {
219 n += try bw.print("addrspace(.{s}) ", .{@tagName(info.flags.address_space)});
212 try bw.print("addrspace(.{s}) ", .{@tagName(info.flags.address_space)});
220213 }
221 if (info.flags.is_const) n += try bw.writeAll("const ");
222 if (info.flags.is_volatile) n += try bw.writeAll("volatile ");
214 if (info.flags.is_const) try bw.writeAll("const ");
215 if (info.flags.is_volatile) try bw.writeAll("volatile ");
223216
224 n += try print(Type.fromInterned(info.child), bw, pt);
225 return n;
217 try print(Type.fromInterned(info.child), bw, pt);
226218 },
227219 .array_type => |array_type| {
228 var n: usize = 0;
229220 if (array_type.sentinel == .none) {
230 n += try bw.print("[{d}]", .{array_type.len});
231 n += try print(Type.fromInterned(array_type.child), bw, pt);
221 try bw.print("[{d}]", .{array_type.len});
222 try print(Type.fromInterned(array_type.child), bw, pt);
232223 } else {
233 n += try bw.print("[{d}:{}]", .{
224 try bw.print("[{d}:{f}]", .{
234225 array_type.len,
235226 Value.fromInterned(array_type.sentinel).fmtValue(pt),
236227 });
237 n += try print(Type.fromInterned(array_type.child), bw, pt);
228 try print(Type.fromInterned(array_type.child), bw, pt);
238229 }
239 return n;
240230 },
241231 .vector_type => |vector_type| {
242 var n: usize = 0;
243 n += try bw.print("@Vector({d}, ", .{vector_type.len});
244 n += try print(Type.fromInterned(vector_type.child), bw, pt);
245 n += try bw.writeAll(")");
246 return n;
232 try bw.print("@Vector({d}, ", .{vector_type.len});
233 try print(Type.fromInterned(vector_type.child), bw, pt);
234 try bw.writeAll(")");
247235 },
248236 .opt_type => |child| {
249 var n: usize = 0;
250 n += try bw.writeByte('?');
251 n += try print(Type.fromInterned(child), bw, pt);
252 return n;
237 try bw.writeByte('?');
238 try print(Type.fromInterned(child), bw, pt);
253239 },
254240 .error_union_type => |error_union_type| {
255 var n: usize = 0;
256 n += try print(Type.fromInterned(error_union_type.error_set_type), bw, pt);
257 n += try bw.writeByte('!');
241 try print(Type.fromInterned(error_union_type.error_set_type), bw, pt);
242 try bw.writeByte('!');
258243 if (error_union_type.payload_type == .generic_poison_type) {
259 n += try bw.writeAll("anytype");
244 try bw.writeAll("anytype");
260245 } else {
261 n += try print(Type.fromInterned(error_union_type.payload_type), bw, pt);
246 try print(Type.fromInterned(error_union_type.payload_type), bw, pt);
262247 }
263 return n;
264248 },
265249 .inferred_error_set_type => |func_index| {
266250 const func_nav = ip.getNav(zcu.funcInfo(func_index).owner_nav);
267 return bw.print("@typeInfo(@typeInfo(@TypeOf({})).@\"fn\".return_type.?).error_union.error_set", .{
251 return bw.print("@typeInfo(@typeInfo(@TypeOf({f})).@\"fn\".return_type.?).error_union.error_set", .{
268252 func_nav.fqn.fmt(ip),
269253 });
270254 },
271255 .error_set_type => |error_set_type| {
272 var n: usize = 0;
273256 const names = error_set_type.names;
274 n += try bw.writeAll("error{");
257 try bw.writeAll("error{");
275258 for (names.get(ip), 0..) |name, i| {
276 if (i != 0) n += try bw.writeByte(',');
277 n += try bw.print("{}", .{name.fmt(ip)});
259 if (i != 0) try bw.writeByte(',');
260 try bw.print("{f}", .{name.fmt(ip)});
278261 }
279 n += try bw.writeAll("}");
280 return n;
262 try bw.writeAll("}");
281263 },
282264 .simple_type => |s| switch (s) {
283265 .f16,
......@@ -318,91 +300,85 @@ pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!u
318300 },
319301 .struct_type => {
320302 const name = ip.loadStructType(ty.toIntern()).name;
321 return bw.print("{}", .{name.fmt(ip)});
303 return bw.print("{f}", .{name.fmt(ip)});
322304 },
323305 .tuple_type => |tuple| {
324306 if (tuple.types.len == 0) {
325307 return bw.writeAll("@TypeOf(.{})");
326308 }
327 var n: usize = 0;
328 n += try bw.writeAll("struct {");
309 try bw.writeAll("struct {");
329310 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, val, i| {
330 n += try bw.writeAll(if (i == 0) " " else ", ");
331 if (val != .none) n += try bw.writeAll("comptime ");
332 n += try print(Type.fromInterned(field_ty), bw, pt);
333 if (val != .none) n += try bw.print(" = {}", .{Value.fromInterned(val).fmtValue(pt)});
311 try bw.writeAll(if (i == 0) " " else ", ");
312 if (val != .none) try bw.writeAll("comptime ");
313 try print(Type.fromInterned(field_ty), bw, pt);
314 if (val != .none) try bw.print(" = {f}", .{Value.fromInterned(val).fmtValue(pt)});
334315 }
335 n += try bw.writeAll(" }");
336 return n;
316 try bw.writeAll(" }");
337317 },
338318
339319 .union_type => {
340320 const name = ip.loadUnionType(ty.toIntern()).name;
341 return bw.print("{}", .{name.fmt(ip)});
321 return bw.print("{f}", .{name.fmt(ip)});
342322 },
343323 .opaque_type => {
344324 const name = ip.loadOpaqueType(ty.toIntern()).name;
345 return bw.print("{}", .{name.fmt(ip)});
325 return bw.print("{f}", .{name.fmt(ip)});
346326 },
347327 .enum_type => {
348328 const name = ip.loadEnumType(ty.toIntern()).name;
349 return bw.print("{}", .{name.fmt(ip)});
329 return bw.print("{f}", .{name.fmt(ip)});
350330 },
351331 .func_type => |fn_info| {
352 var n: usize = 0;
353332 if (fn_info.is_noinline) {
354 n += try bw.writeAll("noinline ");
333 try bw.writeAll("noinline ");
355334 }
356 n += try bw.writeAll("fn (");
335 try bw.writeAll("fn (");
357336 const param_types = fn_info.param_types.get(&zcu.intern_pool);
358337 for (param_types, 0..) |param_ty, i| {
359 if (i != 0) n += try bw.writeAll(", ");
338 if (i != 0) try bw.writeAll(", ");
360339 if (std.math.cast(u5, i)) |index| {
361340 if (fn_info.paramIsComptime(index)) {
362 n += try bw.writeAll("comptime ");
341 try bw.writeAll("comptime ");
363342 }
364343 if (fn_info.paramIsNoalias(index)) {
365 n += try bw.writeAll("noalias ");
344 try bw.writeAll("noalias ");
366345 }
367346 }
368347 if (param_ty == .generic_poison_type) {
369 n += try bw.writeAll("anytype");
348 try bw.writeAll("anytype");
370349 } else {
371 n += try print(Type.fromInterned(param_ty), bw, pt);
350 try print(Type.fromInterned(param_ty), bw, pt);
372351 }
373352 }
374353 if (fn_info.is_var_args) {
375354 if (param_types.len != 0) {
376 n += try bw.writeAll(", ");
355 try bw.writeAll(", ");
377356 }
378 n += try bw.writeAll("...");
357 try bw.writeAll("...");
379358 }
380 n += try bw.writeAll(") ");
359 try bw.writeAll(") ");
381360 if (fn_info.cc != .auto) print_cc: {
382361 if (zcu.getTarget().cCallingConvention()) |ccc| {
383362 if (fn_info.cc.eql(ccc)) {
384 n += try bw.writeAll("callconv(.c) ");
363 try bw.writeAll("callconv(.c) ");
385364 break :print_cc;
386365 }
387366 }
388367 switch (fn_info.cc) {
389 .auto, .@"async", .naked, .@"inline" => n += try bw.print("callconv(.{}) ", .{std.zig.fmtId(@tagName(fn_info.cc))}),
390 else => n += try bw.print("callconv({any}) ", .{fn_info.cc}),
368 .auto, .@"async", .naked, .@"inline" => try bw.print("callconv(.{f}) ", .{std.zig.fmtId(@tagName(fn_info.cc))}),
369 else => try bw.print("callconv({any}) ", .{fn_info.cc}),
391370 }
392371 }
393372 if (fn_info.return_type == .generic_poison_type) {
394 n += try bw.writeAll("anytype");
373 try bw.writeAll("anytype");
395374 } else {
396 n += try print(Type.fromInterned(fn_info.return_type), bw, pt);
375 try print(Type.fromInterned(fn_info.return_type), bw, pt);
397376 }
398 return n;
399377 },
400378 .anyframe_type => |child| {
401379 if (child == .none) return bw.writeAll("anyframe");
402 var n: usize = 0;
403 n += try bw.writeAll("anyframe->");
404 n += print(Type.fromInterned(child), bw, pt);
405 return n;
380 try bw.writeAll("anyframe->");
381 try print(Type.fromInterned(child), bw, pt);
406382 },
407383
408384 // values, not types
src/Zcu.zig+60-63
......@@ -862,7 +862,7 @@ pub const Namespace = struct {
862862 try ns.fileScope(zcu).renderFullyQualifiedDebugName(writer);
863863 break :sep ':';
864864 };
865 if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) });
865 if (name != .empty) try writer.print("{c}{f}", .{ sep, name.fmt(&zcu.intern_pool) });
866866 }
867867
868868 pub fn internFullyQualifiedName(
......@@ -874,7 +874,7 @@ pub const Namespace = struct {
874874 ) !InternPool.NullTerminatedString {
875875 const ns_name = Type.fromInterned(ns.owner_type).containerTypeName(ip);
876876 if (name == .empty) return ns_name;
877 return ip.getOrPutStringFmt(gpa, tid, "{}.{}", .{ ns_name.fmt(ip), name.fmt(ip) }, .no_embedded_nulls);
877 return ip.getOrPutStringFmt(gpa, tid, "{f}.{f}", .{ ns_name.fmt(ip), name.fmt(ip) }, .no_embedded_nulls);
878878 }
879879};
880880
......@@ -1101,11 +1101,11 @@ pub const File = struct {
11011101 const gpa = pt.zcu.gpa;
11021102 const ip = &pt.zcu.intern_pool;
11031103 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
1104 const slice = try strings.addManyAsSlice(file.fullyQualifiedNameLen());
1105 var fbs = std.io.fixedBufferStream(slice[0]);
1106 file.renderFullyQualifiedName(fbs.writer()) catch unreachable;
1107 assert(fbs.pos == slice[0].len);
1108 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
1104 var bw: std.io.BufferedWriter = undefined;
1105 bw.initFixed((try strings.addManyAsSlice(file.fullyQualifiedNameLen()))[0]);
1106 file.renderFullyQualifiedName(&bw) catch unreachable;
1107 assert(bw.end == bw.buffer.len);
1108 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(bw.end), .no_embedded_nulls);
11091109 }
11101110
11111111 pub const Index = InternPool.FileIndex;
......@@ -1194,13 +1194,8 @@ pub const ErrorMsg = struct {
11941194 gpa.destroy(err_msg);
11951195 }
11961196
1197 pub fn init(
1198 gpa: Allocator,
1199 src_loc: LazySrcLoc,
1200 comptime format: []const u8,
1201 args: anytype,
1202 ) !ErrorMsg {
1203 return ErrorMsg{
1197 pub fn init(gpa: Allocator, src_loc: LazySrcLoc, comptime format: []const u8, args: anytype) !ErrorMsg {
1198 return .{
12041199 .src_loc = src_loc,
12051200 .msg = try std.fmt.allocPrint(gpa, format, args),
12061201 };
......@@ -2822,7 +2817,9 @@ comptime {
28222817}
28232818
28242819pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir {
2825 return loadZirCacheBody(gpa, try cache_file.reader().readStruct(Zir.Header), cache_file);
2820 var header: Zir.Header = undefined;
2821 if (try cache_file.readAll(std.mem.asBytes(&header)) < @sizeOf(Zir.Header)) return error.EndOfStream;
2822 return loadZirCacheBody(gpa, header, cache_file);
28262823}
28272824
28282825pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir {
......@@ -3082,7 +3079,7 @@ pub fn markDependeeOutdated(
30823079 marked_po: enum { not_marked_po, marked_po },
30833080 dependee: InternPool.Dependee,
30843081) !void {
3085 log.debug("outdated dependee: {}", .{zcu.fmtDependee(dependee)});
3082 log.debug("outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
30863083 var it = zcu.intern_pool.dependencyIterator(dependee);
30873084 while (it.next()) |depender| {
30883085 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
......@@ -3090,9 +3087,9 @@ pub fn markDependeeOutdated(
30903087 .not_marked_po => {},
30913088 .marked_po => {
30923089 po_dep_count.* -= 1;
3093 log.debug("outdated {} => already outdated {} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
3090 log.debug("outdated {f} => already outdated {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
30943091 if (po_dep_count.* == 0) {
3095 log.debug("outdated ready: {}", .{zcu.fmtAnalUnit(depender)});
3092 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
30963093 try zcu.outdated_ready.put(zcu.gpa, depender, {});
30973094 }
30983095 },
......@@ -3113,9 +3110,9 @@ pub fn markDependeeOutdated(
31133110 depender,
31143111 new_po_dep_count,
31153112 );
3116 log.debug("outdated {} => new outdated {} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), new_po_dep_count });
3113 log.debug("outdated {f} => new outdated {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), new_po_dep_count });
31173114 if (new_po_dep_count == 0) {
3118 log.debug("outdated ready: {}", .{zcu.fmtAnalUnit(depender)});
3115 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
31193116 try zcu.outdated_ready.put(zcu.gpa, depender, {});
31203117 }
31213118 // If this is a Decl and was not previously PO, we must recursively
......@@ -3128,16 +3125,16 @@ pub fn markDependeeOutdated(
31283125}
31293126
31303127pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3131 log.debug("up-to-date dependee: {}", .{zcu.fmtDependee(dependee)});
3128 log.debug("up-to-date dependee: {f}", .{zcu.fmtDependee(dependee)});
31323129 var it = zcu.intern_pool.dependencyIterator(dependee);
31333130 while (it.next()) |depender| {
31343131 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
31353132 // This depender is already outdated, but it now has one
31363133 // less PO dependency!
31373134 po_dep_count.* -= 1;
3138 log.debug("up-to-date {} => {} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
3135 log.debug("up-to-date {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
31393136 if (po_dep_count.* == 0) {
3140 log.debug("outdated ready: {}", .{zcu.fmtAnalUnit(depender)});
3137 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
31413138 try zcu.outdated_ready.put(zcu.gpa, depender, {});
31423139 }
31433140 continue;
......@@ -3151,11 +3148,11 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
31513148 };
31523149 if (ptr.* > 1) {
31533150 ptr.* -= 1;
3154 log.debug("up-to-date {} => {} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), ptr.* });
3151 log.debug("up-to-date {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), ptr.* });
31553152 continue;
31563153 }
31573154
3158 log.debug("up-to-date {} => {} po_deps=0 (up-to-date)", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender) });
3155 log.debug("up-to-date {f} => {f} po_deps=0 (up-to-date)", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender) });
31593156
31603157 // This dependency is no longer PO, i.e. is known to be up-to-date.
31613158 assert(zcu.potentially_outdated.swapRemove(depender));
......@@ -3184,7 +3181,7 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
31843181 .func => |func_index| .{ .interned = func_index }, // IES
31853182 .memoized_state => |stage| .{ .memoized_state = stage },
31863183 };
3187 log.debug("potentially outdated dependee: {}", .{zcu.fmtDependee(dependee)});
3184 log.debug("potentially outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
31883185 var it = ip.dependencyIterator(dependee);
31893186 while (it.next()) |po| {
31903187 if (zcu.outdated.getPtr(po)) |po_dep_count| {
......@@ -3194,17 +3191,17 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
31943191 _ = zcu.outdated_ready.swapRemove(po);
31953192 }
31963193 po_dep_count.* += 1;
3197 log.debug("po {} => {} [outdated] po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), po_dep_count.* });
3194 log.debug("po {f} => {f} [outdated] po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), po_dep_count.* });
31983195 continue;
31993196 }
32003197 if (zcu.potentially_outdated.getPtr(po)) |n| {
32013198 // There is now one more PO dependency.
32023199 n.* += 1;
3203 log.debug("po {} => {} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), n.* });
3200 log.debug("po {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), n.* });
32043201 continue;
32053202 }
32063203 try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1);
3207 log.debug("po {} => {} po_deps=1", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po) });
3204 log.debug("po {f} => {f} po_deps=1", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po) });
32083205 // This AnalUnit was not already PO, so we must recursively mark its dependers as also PO.
32093206 try zcu.markTransitiveDependersPotentiallyOutdated(po);
32103207 }
......@@ -3233,7 +3230,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
32333230
32343231 if (zcu.outdated_ready.count() > 0) {
32353232 const unit = zcu.outdated_ready.keys()[0];
3236 log.debug("findOutdatedToAnalyze: trivial {}", .{zcu.fmtAnalUnit(unit)});
3233 log.debug("findOutdatedToAnalyze: trivial {f}", .{zcu.fmtAnalUnit(unit)});
32373234 return unit;
32383235 }
32393236
......@@ -3284,7 +3281,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
32843281 }
32853282 }
32863283
3287 log.debug("findOutdatedToAnalyze: heuristic returned '{}' ({d} dependers)", .{
3284 log.debug("findOutdatedToAnalyze: heuristic returned '{f}' ({d} dependers)", .{
32883285 zcu.fmtAnalUnit(chosen_unit.?),
32893286 chosen_unit_dependers,
32903287 });
......@@ -4094,7 +4091,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
40944091 const referencer = kv.value;
40954092 try checked_types.putNoClobber(gpa, ty, {});
40964093
4097 log.debug("handle type '{}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});
4094 log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});
40984095
40994096 // If this type undergoes type resolution, the corresponding `AnalUnit` is automatically referenced.
41004097 const has_resolution: bool = switch (ip.indexToKey(ty)) {
......@@ -4130,7 +4127,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
41304127 // `comptime` decls are always analyzed.
41314128 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });
41324129 if (!result.contains(unit)) {
4133 log.debug("type '{}': ref comptime %{}", .{
4130 log.debug("type '{f}': ref comptime %{}", .{
41344131 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
41354132 @intFromEnum(ip.getComptimeUnit(cu).zir_index.resolve(ip) orelse continue),
41364133 });
......@@ -4162,7 +4159,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
41624159 },
41634160 };
41644161 if (want_analysis) {
4165 log.debug("type '{}': ref test %{}", .{
4162 log.debug("type '{f}': ref test %{}", .{
41664163 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
41674164 @intFromEnum(inst_info.inst),
41684165 });
......@@ -4181,7 +4178,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
41814178 if (decl.linkage == .@"export") {
41824179 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
41834180 if (!result.contains(unit)) {
4184 log.debug("type '{}': ref named %{}", .{
4181 log.debug("type '{f}': ref named %{}", .{
41854182 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
41864183 @intFromEnum(inst_info.inst),
41874184 });
......@@ -4197,7 +4194,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
41974194 if (decl.linkage == .@"export") {
41984195 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
41994196 if (!result.contains(unit)) {
4200 log.debug("type '{}': ref named %{}", .{
4197 log.debug("type '{f}': ref named %{}", .{
42014198 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
42024199 @intFromEnum(inst_info.inst),
42034200 });
......@@ -4232,7 +4229,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
42324229 try unit_queue.put(gpa, other, kv.value); // same reference location
42334230 }
42344231
4235 log.debug("handle unit '{}'", .{zcu.fmtAnalUnit(unit)});
4232 log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});
42364233
42374234 if (zcu.reference_table.get(unit)) |first_ref_idx| {
42384235 assert(first_ref_idx != std.math.maxInt(u32));
......@@ -4240,7 +4237,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
42404237 while (ref_idx != std.math.maxInt(u32)) {
42414238 const ref = zcu.all_references.items[ref_idx];
42424239 if (!result.contains(ref.referenced)) {
4243 log.debug("unit '{}': ref unit '{}'", .{
4240 log.debug("unit '{f}': ref unit '{f}'", .{
42444241 zcu.fmtAnalUnit(unit),
42454242 zcu.fmtAnalUnit(ref.referenced),
42464243 });
......@@ -4259,7 +4256,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
42594256 while (ref_idx != std.math.maxInt(u32)) {
42604257 const ref = zcu.all_type_references.items[ref_idx];
42614258 if (!checked_types.contains(ref.referenced)) {
4262 log.debug("unit '{}': ref type '{}'", .{
4259 log.debug("unit '{f}': ref type '{f}'", .{
42634260 zcu.fmtAnalUnit(unit),
42644261 Type.fromInterned(ref.referenced).containerTypeName(ip).fmt(ip),
42654262 });
......@@ -4347,8 +4344,8 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Formatter(formatDe
43474344 return .{ .data = .{ .dependee = d, .zcu = zcu } };
43484345}
43494346
4350fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
4351 _ = .{ fmt, options };
4347fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
4348 _ = fmt;
43524349 const zcu = data.zcu;
43534350 const ip = &zcu.intern_pool;
43544351 switch (data.unit.unwrap()) {
......@@ -4356,69 +4353,69 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co
43564353 const cu = ip.getComptimeUnit(cu_id);
43574354 if (cu.zir_index.resolveFull(ip)) |resolved| {
43584355 const file_path = zcu.fileByIndex(resolved.file).path;
4359 return writer.print("comptime(inst=('{}', %{}) [{}])", .{ file_path.fmt(zcu.comp), @intFromEnum(resolved.inst), @intFromEnum(cu_id) });
4356 return bw.print("comptime(inst=('{f}', %{}) [{}])", .{ file_path.fmt(zcu.comp), @intFromEnum(resolved.inst), @intFromEnum(cu_id) });
43604357 } else {
4361 return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)});
4358 return bw.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)});
43624359 }
43634360 },
4364 .nav_val => |nav| return writer.print("nav_val('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4365 .nav_ty => |nav| return writer.print("nav_ty('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4366 .type => |ty| return writer.print("ty('{}' [{}])", .{ Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
4361 .nav_val => |nav| return bw.print("nav_val('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4362 .nav_ty => |nav| return bw.print("nav_ty('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4363 .type => |ty| return bw.print("ty('{f}' [{}])", .{ Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
43674364 .func => |func| {
43684365 const nav = zcu.funcInfo(func).owner_nav;
4369 return writer.print("func('{}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
4366 return bw.print("func('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
43704367 },
4371 .memoized_state => return writer.writeAll("memoized_state"),
4368 .memoized_state => return bw.writeAll("memoized_state"),
43724369 }
43734370}
4374fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
4375 _ = .{ fmt, options };
4371fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
4372 _ = fmt;
43764373 const zcu = data.zcu;
43774374 const ip = &zcu.intern_pool;
43784375 switch (data.dependee) {
43794376 .src_hash => |ti| {
43804377 const info = ti.resolveFull(ip) orelse {
4381 return writer.writeAll("inst(<lost>)");
4378 return bw.writeAll("inst(<lost>)");
43824379 };
43834380 const file_path = zcu.fileByIndex(info.file).path;
4384 return writer.print("inst('{}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });
4381 return bw.print("inst('{f}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });
43854382 },
43864383 .nav_val => |nav| {
43874384 const fqn = ip.getNav(nav).fqn;
4388 return writer.print("nav_val('{}')", .{fqn.fmt(ip)});
4385 return bw.print("nav_val('{f}')", .{fqn.fmt(ip)});
43894386 },
43904387 .nav_ty => |nav| {
43914388 const fqn = ip.getNav(nav).fqn;
4392 return writer.print("nav_ty('{}')", .{fqn.fmt(ip)});
4389 return bw.print("nav_ty('{f}')", .{fqn.fmt(ip)});
43934390 },
43944391 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
4395 .struct_type, .union_type, .enum_type => return writer.print("type('{}')", .{Type.fromInterned(ip_index).containerTypeName(ip).fmt(ip)}),
4396 .func => |f| return writer.print("ies('{}')", .{ip.getNav(f.owner_nav).fqn.fmt(ip)}),
4392 .struct_type, .union_type, .enum_type => return bw.print("type('{f}')", .{Type.fromInterned(ip_index).containerTypeName(ip).fmt(ip)}),
4393 .func => |f| return bw.print("ies('{f}')", .{ip.getNav(f.owner_nav).fqn.fmt(ip)}),
43974394 else => unreachable,
43984395 },
43994396 .zon_file => |file| {
44004397 const file_path = zcu.fileByIndex(file).path;
4401 return writer.print("zon_file('{}')", .{file_path.fmt(zcu.comp)});
4398 return bw.print("zon_file('{f}')", .{file_path.fmt(zcu.comp)});
44024399 },
44034400 .embed_file => |ef_idx| {
44044401 const ef = ef_idx.get(zcu);
4405 return writer.print("embed_file('{}')", .{ef.path.fmt(zcu.comp)});
4402 return bw.print("embed_file('{f}')", .{ef.path.fmt(zcu.comp)});
44064403 },
44074404 .namespace => |ti| {
44084405 const info = ti.resolveFull(ip) orelse {
4409 return writer.writeAll("namespace(<lost>)");
4406 return bw.writeAll("namespace(<lost>)");
44104407 };
44114408 const file_path = zcu.fileByIndex(info.file).path;
4412 return writer.print("namespace('{}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });
4409 return bw.print("namespace('{f}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });
44134410 },
44144411 .namespace_name => |k| {
44154412 const info = k.namespace.resolveFull(ip) orelse {
4416 return writer.print("namespace(<lost>, '{}')", .{k.name.fmt(ip)});
4413 return bw.print("namespace(<lost>, '{f}')", .{k.name.fmt(ip)});
44174414 };
44184415 const file_path = zcu.fileByIndex(info.file).path;
4419 return writer.print("namespace('{}', %{d}, '{}')", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst), k.name.fmt(ip) });
4416 return bw.print("namespace('{f}', %{d}, '{f}')", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst), k.name.fmt(ip) });
44204417 },
4421 .memoized_state => return writer.writeAll("memoized_state"),
4418 .memoized_state => return bw.writeAll("memoized_state"),
44224419 }
44234420}
44244421
src/Zcu/PerThread.zig+21-21
......@@ -190,7 +190,7 @@ pub fn updateFile(
190190 // failure was a race, or ENOENT, indicating deletion of the
191191 // directory of our open handle.
192192 if (builtin.os.tag != .macos) {
193 std.process.fatal("cache directory '{}' unexpectedly removed during compiler execution", .{
193 std.process.fatal("cache directory '{f}' unexpectedly removed during compiler execution", .{
194194 cache_directory,
195195 });
196196 }
......@@ -202,7 +202,7 @@ pub fn updateFile(
202202 }) catch |excl_err| switch (excl_err) {
203203 error.PathAlreadyExists => continue,
204204 error.FileNotFound => {
205 std.process.fatal("cache directory '{}' unexpectedly removed during compiler execution", .{
205 std.process.fatal("cache directory '{f}' unexpectedly removed during compiler execution", .{
206206 cache_directory,
207207 });
208208 },
......@@ -646,7 +646,7 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
646646 // If this unit caused the error, it would have an entry in `failed_analysis`.
647647 // Since it does not, this must be a transitive failure.
648648 try zcu.transitive_failed_analysis.put(gpa, unit, {});
649 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(unit)});
649 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(unit)});
650650 }
651651 break :res .{ !prev_failed, true };
652652 },
......@@ -751,7 +751,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
751751
752752 const anal_unit: AnalUnit = .wrap(.{ .@"comptime" = cu_id });
753753
754 log.debug("ensureComptimeUnitUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
754 log.debug("ensureComptimeUnitUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
755755
756756 assert(!zcu.analysis_in_progress.contains(anal_unit));
757757
......@@ -802,7 +802,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
802802 // If this unit caused the error, it would have an entry in `failed_analysis`.
803803 // Since it does not, this must be a transitive failure.
804804 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
805 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
805 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
806806 }
807807 return error.AnalysisFail;
808808 },
......@@ -832,7 +832,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
832832 const anal_unit: AnalUnit = .wrap(.{ .@"comptime" = cu_id });
833833 const comptime_unit = ip.getComptimeUnit(cu_id);
834834
835 log.debug("analyzeComptimeUnit {}", .{zcu.fmtAnalUnit(anal_unit)});
835 log.debug("analyzeComptimeUnit {f}", .{zcu.fmtAnalUnit(anal_unit)});
836836
837837 const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
838838 const file = zcu.fileByIndex(inst_resolved.file);
......@@ -878,7 +878,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
878878 .r = .{ .simple = .comptime_keyword },
879879 } },
880880 .src_base_inst = comptime_unit.zir_index,
881 .type_name_ctx = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.comptime", .{
881 .type_name_ctx = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}.comptime", .{
882882 Type.fromInterned(zcu.namespacePtr(comptime_unit.namespace).owner_type).containerTypeName(ip).fmt(ip),
883883 }, .no_embedded_nulls),
884884 };
......@@ -930,7 +930,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
930930 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
931931 const nav = ip.getNav(nav_id);
932932
933 log.debug("ensureNavValUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
933 log.debug("ensureNavValUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
934934
935935 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
936936 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
......@@ -988,7 +988,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
988988 // If this unit caused the error, it would have an entry in `failed_analysis`.
989989 // Since it does not, this must be a transitive failure.
990990 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
991 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
991 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
992992 }
993993 break :res .{ !prev_failed, true };
994994 },
......@@ -1059,7 +1059,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
10591059 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
10601060 const old_nav = ip.getNav(nav_id);
10611061
1062 log.debug("analyzeNavVal {}", .{zcu.fmtAnalUnit(anal_unit)});
1062 log.debug("analyzeNavVal {f}", .{zcu.fmtAnalUnit(anal_unit)});
10631063
10641064 const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
10651065 const file = zcu.fileByIndex(inst_resolved.file);
......@@ -1240,10 +1240,10 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
12401240 // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`.
12411241 if (zir_decl.kind == .@"usingnamespace") {
12421242 if (nav_ty.toIntern() != .type_type) {
1243 return sema.fail(&block, ty_src, "expected type, found {}", .{nav_ty.fmt(pt)});
1243 return sema.fail(&block, ty_src, "expected type, found {f}", .{nav_ty.fmt(pt)});
12441244 }
12451245 if (nav_val.toType().getNamespace(zcu) == .none) {
1246 return sema.fail(&block, ty_src, "type {} has no namespace", .{nav_val.toType().fmt(pt)});
1246 return sema.fail(&block, ty_src, "type {f} has no namespace", .{nav_val.toType().fmt(pt)});
12471247 }
12481248 ip.resolveNavValue(nav_id, .{
12491249 .val = nav_val.toIntern(),
......@@ -1339,7 +1339,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
13391339 const anal_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id });
13401340 const nav = ip.getNav(nav_id);
13411341
1342 log.debug("ensureNavTypeUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
1342 log.debug("ensureNavTypeUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
13431343
13441344 const type_resolved_by_value: bool = from_val: {
13451345 const analysis = nav.analysis orelse break :from_val false;
......@@ -1409,7 +1409,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
14091409 // If this unit caused the error, it would have an entry in `failed_analysis`.
14101410 // Since it does not, this must be a transitive failure.
14111411 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
1412 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
1412 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
14131413 }
14141414 break :res .{ !prev_failed, true };
14151415 },
......@@ -1451,7 +1451,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
14511451 const anal_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id });
14521452 const old_nav = ip.getNav(nav_id);
14531453
1454 log.debug("analyzeNavType {}", .{zcu.fmtAnalUnit(anal_unit)});
1454 log.debug("analyzeNavType {f}", .{zcu.fmtAnalUnit(anal_unit)});
14551455
14561456 const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
14571457 const file = zcu.fileByIndex(inst_resolved.file);
......@@ -1582,7 +1582,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
15821582 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
15831583 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });
15841584
1585 log.debug("ensureFuncBodyUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)});
1585 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
15861586
15871587 const func = zcu.funcInfo(maybe_coerced_func_index);
15881588
......@@ -1626,7 +1626,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
16261626 // If this function caused the error, it would have an entry in `failed_analysis`.
16271627 // Since it does not, this must be a transitive failure.
16281628 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
1629 log.debug("mark transitive analysis failure for {}", .{zcu.fmtAnalUnit(anal_unit)});
1629 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
16301630 }
16311631 // We consider the IES to be outdated if the function previously succeeded analysis; in this case,
16321632 // we need to re-analyze dependants to ensure they hit a transitive error here, rather than reporting
......@@ -1696,7 +1696,7 @@ fn analyzeFuncBody(
16961696 else
16971697 .none;
16981698
1699 log.debug("analyze and generate fn body {}", .{zcu.fmtAnalUnit(anal_unit)});
1699 log.debug("analyze and generate fn body {f}", .{zcu.fmtAnalUnit(anal_unit)});
17001700
17011701 var air = try pt.analyzeFnBodyInner(func_index);
17021702 errdefer air.deinit(gpa);
......@@ -2615,7 +2615,7 @@ const ScanDeclIter = struct {
26152615 var gop = try iter.seen_decls.getOrPut(gpa, name);
26162616 var next_suffix: u32 = 0;
26172617 while (gop.found_existing) {
2618 name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
2618 name = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}_{d}", .{ name.fmt(ip), next_suffix }, .no_embedded_nulls);
26192619 gop = try iter.seen_decls.getOrPut(gpa, name);
26202620 next_suffix += 1;
26212621 }
......@@ -2764,7 +2764,7 @@ const ScanDeclIter = struct {
27642764
27652765 if (existing_unit == null and (want_analysis or decl.linkage == .@"export")) {
27662766 log.debug(
2767 "scanDecl queue analyze_comptime_unit file='{s}' unit={}",
2767 "scanDecl queue analyze_comptime_unit file='{s}' unit={f}",
27682768 .{ namespace.fileScope(zcu).sub_file_path, zcu.fmtAnalUnit(unit) },
27692769 );
27702770 try comp.queueJob(.{ .analyze_comptime_unit = unit });
......@@ -3182,7 +3182,7 @@ fn processExportsInner(
31823182 if (gop.found_existing) {
31833183 new_export.status = .failed_retryable;
31843184 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
3185 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {}", .{
3185 const msg = try Zcu.ErrorMsg.create(gpa, new_export.src, "exported symbol collision: {f}", .{
31863186 new_export.opts.name.fmt(ip),
31873187 });
31883188 errdefer msg.destroy(gpa);
src/arch/aarch64/CodeGen.zig+3-3
......@@ -1011,7 +1011,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10111011 }
10121012
10131013 const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse {
1014 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1014 return self.fail("type '{f}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
10151015 };
10161016 // TODO swap this for inst.ty.ptrAlign
10171017 const abi_align = elem_ty.abiAlignment(zcu);
......@@ -1022,7 +1022,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10221022fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
10231023 const pt = self.pt;
10241024 const abi_size = math.cast(u32, elem_ty.abiSize(pt.zcu)) orelse {
1025 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1025 return self.fail("type '{f}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
10261026 };
10271027 const abi_align = elem_ty.abiAlignment(pt.zcu);
10281028
......@@ -4636,7 +4636,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) InnerError!void {
46364636 const mcv = try self.resolveInst(operand);
46374637 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
46384638
4639 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });
4639 log.debug("airDbgVar: %{f}: {f}, {}", .{ inst, ty.fmtDebug(), mcv });
46404640
46414641 try self.dbg_info_relocs.append(self.gpa, .{
46424642 .tag = tag,
src/arch/aarch64/Emit.zig+15-18
......@@ -70,9 +70,11 @@ const BranchType = enum {
7070 }
7171};
7272
73pub fn emitMir(
74 emit: *Emit,
75) !void {
73pub fn emitMir(emit: *Emit) InnerError!void {
74 return @errorCast(emit.emitMirInner());
75}
76
77fn emitMirInner(emit: *Emit) anyerror!void {
7678 const mir_tags = emit.mir.instructions.items(.tag);
7779
7880 // Find smallest lowerings for branch instructions
......@@ -439,7 +441,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
439441 return error.EmitFail;
440442}
441443
442fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {
444fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) anyerror!void {
443445 const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
444446 const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
445447 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
......@@ -454,25 +456,20 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {
454456 .plan9 => |dbg_out| {
455457 if (delta_pc <= 0) return; // only do this when the pc changes
456458
459 var aw: std.io.AllocatingWriter = undefined;
460 const bw = aw.fromArrayList(emit.bin_file.comp.gpa, &dbg_out.dbg_line);
461 defer dbg_out.dbg_line = aw.toArrayList();
462
457463 // increasing the line number
458 try link.File.Plan9.changeLine(&dbg_out.dbg_line, @intCast(delta_line));
464 try link.File.Plan9.changeLine(bw, @intCast(delta_line));
459465 // increasing the pc
460466 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
461467 if (d_pc_p9 > 0) {
462468 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
463 var diff = @divExact(d_pc_p9, dbg_out.pc_quanta) - dbg_out.pc_quanta;
464 while (diff > 0) {
465 if (diff < 64) {
466 try dbg_out.dbg_line.append(@intCast(diff + 128));
467 diff = 0;
468 } else {
469 try dbg_out.dbg_line.append(@intCast(64 + 128));
470 diff -= 64;
471 }
472 }
473 if (dbg_out.pcop_change_index) |pci|
474 dbg_out.dbg_line.items[pci] += 1;
475 dbg_out.pcop_change_index = @intCast(dbg_out.dbg_line.items.len - 1);
469 try bw.writeByte(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
470 const dbg_line = aw.getWritten();
471 if (dbg_out.pcop_change_index) |pci| dbg_line[pci] += 1;
472 dbg_out.pcop_change_index = @intCast(dbg_line.len - 1);
476473 } else if (d_pc_p9 == 0) {
477474 // we don't need to do anything, because adding the pc quanta does it for us
478475 } else unreachable;
src/arch/arm/CodeGen.zig+3-3
......@@ -997,7 +997,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
997997 }
998998
999999 const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse {
1000 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1000 return self.fail("type '{f}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
10011001 };
10021002 // TODO swap this for inst.ty.ptrAlign
10031003 const abi_align = elem_ty.abiAlignment(zcu);
......@@ -1008,7 +1008,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10081008fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
10091009 const pt = self.pt;
10101010 const abi_size = math.cast(u32, elem_ty.abiSize(pt.zcu)) orelse {
1011 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
1011 return self.fail("type '{f}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
10121012 };
10131013 const abi_align = elem_ty.abiAlignment(pt.zcu);
10141014
......@@ -4609,7 +4609,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
46094609 const mcv = try self.resolveInst(operand);
46104610 const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
46114611
4612 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv });
4612 log.debug("airDbgVar: %{f}: {f}, {}", .{ inst, ty.fmtDebug(), mcv });
46134613
46144614 try self.dbg_info_relocs.append(self.gpa, .{
46154615 .tag = tag,
src/arch/arm/Emit.zig+14-8
......@@ -67,9 +67,11 @@ const BranchType = enum {
6767 }
6868};
6969
70pub fn emitMir(
71 emit: *Emit,
72) !void {
70pub fn emitMir(emit: *Emit) InnerError!void {
71 return @errorCast(emit.emitMirInner());
72}
73
74fn emitMirInner(emit: *Emit) anyerror!void {
7375 const mir_tags = emit.mir.instructions.items(.tag);
7476
7577 // Find smallest lowerings for branch instructions
......@@ -370,16 +372,20 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
370372 .plan9 => |dbg_out| {
371373 if (delta_pc <= 0) return; // only do this when the pc changes
372374
375 var aw: std.io.AllocatingWriter = undefined;
376 const bw = aw.fromArrayList(self.bin_file.comp.gpa, &dbg_out.dbg_line);
377 defer dbg_out.dbg_line = aw.toArrayList();
378
373379 // increasing the line number
374 try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
380 try link.File.Plan9.changeLine(bw, delta_line);
375381 // increasing the pc
376382 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
377383 if (d_pc_p9 > 0) {
378384 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
379 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
380 if (dbg_out.pcop_change_index) |pci|
381 dbg_out.dbg_line.items[pci] += 1;
382 dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
385 try bw.writeByte(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
386 const dbg_line = aw.getWritten();
387 if (dbg_out.pcop_change_index) |pci| dbg_line[pci] += 1;
388 dbg_out.pcop_change_index = @intCast(dbg_line.len - 1);
383389 } else if (d_pc_p9 == 0) {
384390 // we don't need to do anything, because adding the pc quanta does it for us
385391 } else unreachable;
src/arch/riscv64/CodeGen.zig+50-75
......@@ -401,7 +401,7 @@ const InstTracking = struct {
401401 .reserved_frame => |index| inst_tracking.long = .{ .load_frame = .{ .index = index } },
402402 else => unreachable,
403403 }
404 tracking_log.debug("spill %{d} from {} to {}", .{ inst, inst_tracking.short, inst_tracking.long });
404 tracking_log.debug("spill %{f} from {} to {}", .{ inst, inst_tracking.short, inst_tracking.long });
405405 try function.genCopy(function.typeOfIndex(inst), inst_tracking.long, inst_tracking.short);
406406 }
407407
......@@ -435,7 +435,7 @@ const InstTracking = struct {
435435 fn trackSpill(inst_tracking: *InstTracking, function: *Func, inst: Air.Inst.Index) !void {
436436 try function.freeValue(inst_tracking.short);
437437 inst_tracking.reuseFrame();
438 tracking_log.debug("%{d} => {} (spilled)", .{ inst, inst_tracking.* });
438 tracking_log.debug("%{f} => {f} (spilled)", .{ inst, inst_tracking.* });
439439 }
440440
441441 fn verifyMaterialize(inst_tracking: InstTracking, target: InstTracking) void {
......@@ -499,14 +499,14 @@ const InstTracking = struct {
499499 else => target.long,
500500 } else target.long;
501501 inst_tracking.short = target.short;
502 tracking_log.debug("%{d} => {} (materialize)", .{ inst, inst_tracking.* });
502 tracking_log.debug("%{f} => {f} (materialize)", .{ inst, inst_tracking.* });
503503 }
504504
505505 fn resurrect(inst_tracking: *InstTracking, inst: Air.Inst.Index, scope_generation: u32) void {
506506 switch (inst_tracking.short) {
507507 .dead => |die_generation| if (die_generation >= scope_generation) {
508508 inst_tracking.reuseFrame();
509 tracking_log.debug("%{d} => {} (resurrect)", .{ inst, inst_tracking.* });
509 tracking_log.debug("%{f} => {f} (resurrect)", .{ inst, inst_tracking.* });
510510 },
511511 else => {},
512512 }
......@@ -516,7 +516,7 @@ const InstTracking = struct {
516516 if (inst_tracking.short == .dead) return;
517517 try function.freeValue(inst_tracking.short);
518518 inst_tracking.short = .{ .dead = function.scope_generation };
519 tracking_log.debug("%{d} => {} (death)", .{ inst, inst_tracking.* });
519 tracking_log.debug("%{f} => {f} (death)", .{ inst, inst_tracking.* });
520520 }
521521
522522 fn reuse(
......@@ -527,15 +527,15 @@ const InstTracking = struct {
527527 ) void {
528528 inst_tracking.short = .{ .dead = function.scope_generation };
529529 if (new_inst) |inst|
530 tracking_log.debug("%{d} => {} (reuse %{d})", .{ inst, inst_tracking.*, old_inst })
530 tracking_log.debug("%{f} => {f} (reuse %{f})", .{ inst, inst_tracking.*, old_inst })
531531 else
532 tracking_log.debug("tmp => {} (reuse %{d})", .{ inst_tracking.*, old_inst });
532 tracking_log.debug("tmp => {f} (reuse %{f})", .{ inst_tracking.*, old_inst });
533533 }
534534
535535 fn liveOut(inst_tracking: *InstTracking, function: *Func, inst: Air.Inst.Index) void {
536536 for (inst_tracking.getRegs()) |reg| {
537537 if (function.register_manager.isRegFree(reg)) {
538 tracking_log.debug("%{d} => {} (live-out)", .{ inst, inst_tracking.* });
538 tracking_log.debug("%{f} => {f} (live-out)", .{ inst, inst_tracking.* });
539539 continue;
540540 }
541541
......@@ -562,18 +562,13 @@ const InstTracking = struct {
562562 // Perform side-effects of freeValue manually.
563563 function.register_manager.freeReg(reg);
564564
565 tracking_log.debug("%{d} => {} (live-out %{d})", .{ inst, inst_tracking.*, tracked_inst });
565 tracking_log.debug("%{f} => {f} (live-out %{f})", .{ inst, inst_tracking.*, tracked_inst });
566566 }
567567 }
568568
569 pub fn format(
570 inst_tracking: InstTracking,
571 comptime _: []const u8,
572 _: std.fmt.FormatOptions,
573 writer: anytype,
574 ) @TypeOf(writer).Error!void {
575 if (!std.meta.eql(inst_tracking.long, inst_tracking.short)) try writer.print("|{}| ", .{inst_tracking.long});
576 try writer.print("{}", .{inst_tracking.short});
569 pub fn format(inst_tracking: InstTracking, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
570 if (!std.meta.eql(inst_tracking.long, inst_tracking.short)) try bw.print("|{}| ", .{inst_tracking.long});
571 try bw.print("{}", .{inst_tracking.short});
577572 }
578573};
579574
......@@ -802,7 +797,7 @@ pub fn generate(
802797 function.mir_instructions.deinit(gpa);
803798 }
804799
805 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
800 wip_mir_log.debug("{f}:", .{fmtNav(func.owner_nav, ip)});
806801
807802 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
808803 function.frame_allocs.set(
......@@ -937,12 +932,7 @@ const FormatWipMirData = struct {
937932 func: *Func,
938933 inst: Mir.Inst.Index,
939934};
940fn formatWipMir(
941 data: FormatWipMirData,
942 comptime _: []const u8,
943 _: std.fmt.FormatOptions,
944 writer: anytype,
945) @TypeOf(writer).Error!void {
935fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
946936 const pt = data.func.pt;
947937 const comp = pt.zcu.comp;
948938 var lower: Lower = .{
......@@ -965,11 +955,11 @@ fn formatWipMir(
965955 lower.err_msg.?.deinit(data.func.gpa);
966956 lower.err_msg = null;
967957 }
968 try writer.writeAll(lower.err_msg.?.msg);
958 try bw.writeAll(lower.err_msg.?.msg);
969959 return;
970960 },
971961 error.OutOfMemory, error.InvalidInstruction => |e| {
972 try writer.writeAll(switch (e) {
962 try bw.writeAll(switch (e) {
973963 error.OutOfMemory => "Out of memory",
974964 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
975965 });
......@@ -977,8 +967,8 @@ fn formatWipMir(
977967 },
978968 else => |e| return e,
979969 }).insts) |lowered_inst| {
980 if (!first) try writer.writeAll("\ndebug(wip_mir): ");
981 try writer.print(" | {}", .{lowered_inst});
970 if (!first) try bw.writeAll("\ndebug(wip_mir): ");
971 try bw.print(" | {}", .{lowered_inst});
982972 first = false;
983973 }
984974}
......@@ -990,13 +980,8 @@ const FormatNavData = struct {
990980 ip: *const InternPool,
991981 nav_index: InternPool.Nav.Index,
992982};
993fn formatNav(
994 data: FormatNavData,
995 comptime _: []const u8,
996 _: std.fmt.FormatOptions,
997 writer: anytype,
998) @TypeOf(writer).Error!void {
999 try writer.print("{}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
983fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
984 try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
1000985}
1001986fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
1002987 return .{ .data = .{
......@@ -1009,12 +994,7 @@ const FormatAirData = struct {
1009994 func: *Func,
1010995 inst: Air.Inst.Index,
1011996};
1012fn formatAir(
1013 data: FormatAirData,
1014 comptime _: []const u8,
1015 _: std.fmt.FormatOptions,
1016 writer: anytype,
1017) @TypeOf(writer).Error!void {
997fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1018998 data.func.air.dumpInst(data.inst, data.func.pt, data.func.liveness);
1019999}
10201000fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
......@@ -1024,14 +1004,9 @@ fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
10241004const FormatTrackingData = struct {
10251005 func: *Func,
10261006};
1027fn formatTracking(
1028 data: FormatTrackingData,
1029 comptime _: []const u8,
1030 _: std.fmt.FormatOptions,
1031 writer: anytype,
1032) @TypeOf(writer).Error!void {
1007fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
10331008 var it = data.func.inst_tracking.iterator();
1034 while (it.next()) |entry| try writer.print("\n%{d} = {}", .{ entry.key_ptr.*, entry.value_ptr.* });
1009 while (it.next()) |entry| try bw.print("\n%{d} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* });
10351010}
10361011fn fmtTracking(func: *Func) std.fmt.Formatter(formatTracking) {
10371012 return .{ .data = .{ .func = func } };
......@@ -1049,7 +1024,7 @@ fn addInst(func: *Func, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
10491024 .pseudo_dbg_epilogue_begin,
10501025 .pseudo_dead,
10511026 => false,
1052 }) wip_mir_log.debug("{}", .{func.fmtWipMir(result_index)});
1027 }) wip_mir_log.debug("{f}", .{func.fmtWipMir(result_index)});
10531028 return result_index;
10541029}
10551030
......@@ -1172,7 +1147,7 @@ fn gen(func: *Func) !void {
11721147 func.ret_mcv.long.address().offset(-func.ret_mcv.short.indirect.off),
11731148 );
11741149 func.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
1175 tracking_log.debug("spill {} to {}", .{ func.ret_mcv.long, frame_index });
1150 tracking_log.debug("spill {} to {f}", .{ func.ret_mcv.long, frame_index });
11761151 },
11771152 else => unreachable,
11781153 }
......@@ -1303,7 +1278,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
13031278 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) {
13041279 .@"enum" => {
13051280 const enum_ty = Type.fromInterned(lazy_sym.ty);
1306 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
1281 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});
13071282
13081283 const param_regs = abi.Registers.Integer.function_arg_regs;
13091284 const ret_reg = param_regs[0];
......@@ -1385,7 +1360,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
13851360 });
13861361 },
13871362 else => return func.fail(
1388 "TODO implement {s} for {}",
1363 "TODO implement {s} for {f}",
13891364 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
13901365 ),
13911366 }
......@@ -1399,8 +1374,8 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
13991374
14001375 for (body) |inst| {
14011376 if (func.liveness.isUnused(inst) and !func.air.mustLower(inst, ip)) continue;
1402 wip_mir_log.debug("{}", .{func.fmtAir(inst)});
1403 verbose_tracking_log.debug("{}", .{func.fmtTracking()});
1377 wip_mir_log.debug("{f}", .{func.fmtAir(inst)});
1378 verbose_tracking_log.debug("{f}", .{func.fmtTracking()});
14041379
14051380 const old_air_bookkeeping = func.air_bookkeeping;
14061381 try func.ensureProcessDeathCapacity(Air.Liveness.bpi);
......@@ -1679,18 +1654,18 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
16791654 var it = func.register_manager.free_registers.iterator(.{ .kind = .unset });
16801655 while (it.next()) |index| {
16811656 const tracked_inst = func.register_manager.registers[index];
1682 tracking_log.debug("tracked inst: {}", .{tracked_inst});
1657 tracking_log.debug("tracked inst: {f}", .{tracked_inst});
16831658 const tracking = func.getResolvedInstValue(tracked_inst);
16841659 for (tracking.getRegs()) |reg| {
16851660 if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break;
16861661 } else return std.debug.panic(
1687 \\%{} takes up these regs: {any}, however this regs {any}, don't use it
1662 \\%{f} takes up these regs: {any}, however this regs {any}, don't use it
16881663 , .{ tracked_inst, tracking.getRegs(), RegisterManager.regAtTrackedIndex(@intCast(index)) });
16891664 }
16901665 }
16911666 }
16921667 }
1693 verbose_tracking_log.debug("{}", .{func.fmtTracking()});
1668 verbose_tracking_log.debug("{f}", .{func.fmtTracking()});
16941669}
16951670
16961671fn getValue(func: *Func, value: MCValue, inst: ?Air.Inst.Index) !void {
......@@ -1713,7 +1688,7 @@ fn freeValue(func: *Func, value: MCValue) !void {
17131688
17141689fn feed(func: *Func, bt: *Air.Liveness.BigTomb, operand: Air.Inst.Ref) !void {
17151690 if (bt.feed()) if (operand.toIndex()) |inst| {
1716 log.debug("feed inst: %{}", .{inst});
1691 log.debug("feed inst: %{f}", .{inst});
17171692 try func.processDeath(inst);
17181693 };
17191694}
......@@ -1907,7 +1882,7 @@ fn splitType(func: *Func, ty: Type) ![2]Type {
19071882 else => return func.fail("TODO: splitType class {}", .{class}),
19081883 };
19091884 } else if (parts[0].abiSize(zcu) + parts[1].abiSize(zcu) == ty.abiSize(zcu)) return parts;
1910 return func.fail("TODO implement splitType for {}", .{ty.fmt(func.pt)});
1885 return func.fail("TODO implement splitType for {f}", .{ty.fmt(func.pt)});
19111886}
19121887
19131888/// Truncates the value in the register in place.
......@@ -2008,7 +1983,7 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex {
20081983 }
20091984 const frame_index: FrameIndex = @enumFromInt(func.frame_allocs.len);
20101985 try func.frame_allocs.append(func.gpa, alloc);
2011 log.debug("allocated frame {}", .{frame_index});
1986 log.debug("allocated frame {f}", .{frame_index});
20121987 return frame_index;
20131988}
20141989
......@@ -2020,7 +1995,7 @@ fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex {
20201995 const val_ty = ptr_ty.childType(zcu);
20211996 return func.allocFrameIndex(FrameAlloc.init(.{
20221997 .size = math.cast(u32, val_ty.abiSize(zcu)) orelse {
2023 return func.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)});
1998 return func.fail("type '{f}' too big to fit into stack frame", .{val_ty.fmt(pt)});
20241999 },
20252000 .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"),
20262001 }));
......@@ -2160,7 +2135,7 @@ pub fn spillRegisters(func: *Func, comptime registers: []const Register) !void {
21602135/// allocated. A second call to `copyToTmpRegister` may return the same register.
21612136/// This can have a side effect of spilling instructions to the stack to free up a register.
21622137fn copyToTmpRegister(func: *Func, ty: Type, mcv: MCValue) !Register {
2163 log.debug("copyToTmpRegister ty: {}", .{ty.fmt(func.pt)});
2138 log.debug("copyToTmpRegister ty: {f}", .{ty.fmt(func.pt)});
21642139 const reg = try func.register_manager.allocReg(null, func.regTempClassForType(ty));
21652140 try func.genSetReg(ty, reg, mcv);
21662141 return reg;
......@@ -2245,7 +2220,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {
22452220 break :result null; // TODO
22462221
22472222 break :result dst_mcv;
2248 } orelse return func.fail("TODO: implement airIntCast from {} to {}", .{
2223 } orelse return func.fail("TODO: implement airIntCast from {f} to {f}", .{
22492224 src_ty.fmt(pt), dst_ty.fmt(pt),
22502225 });
22512226
......@@ -2633,7 +2608,7 @@ fn genBinOp(
26332608 .add_sat,
26342609 => {
26352610 if (bit_size != 64 or !is_unsigned)
2636 return func.fail("TODO: genBinOp ty: {}", .{lhs_ty.fmt(pt)});
2611 return func.fail("TODO: genBinOp ty: {f}", .{lhs_ty.fmt(pt)});
26372612
26382613 const tmp_reg = try func.copyToTmpRegister(rhs_ty, .{ .register = rhs_reg });
26392614 const tmp_lock = func.register_manager.lockRegAssumeUnused(tmp_reg);
......@@ -4065,7 +4040,7 @@ fn airGetUnionTag(func: *Func, inst: Air.Inst.Index) !void {
40654040 );
40664041 } else {
40674042 return func.fail(
4068 "TODO implement get_union_tag for ABI larger than 8 bytes and operand {}, tag {}",
4043 "TODO implement get_union_tag for ABI larger than 8 bytes and operand {}, tag {f}",
40694044 .{ frame_mcv, tag_ty.fmt(pt) },
40704045 );
40714046 }
......@@ -4186,7 +4161,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {
41864161
41874162 switch (scalar_ty.zigTypeTag(zcu)) {
41884163 .int => if (ty.zigTypeTag(zcu) == .vector) {
4189 return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)});
4164 return func.fail("TODO implement airAbs for {f}", .{ty.fmt(pt)});
41904165 } else {
41914166 const int_info = scalar_ty.intInfo(zcu);
41924167 const int_bits = int_info.bits;
......@@ -4267,7 +4242,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void {
42674242
42684243 break :result return_mcv;
42694244 },
4270 else => return func.fail("TODO: implement airAbs {}", .{scalar_ty.fmt(pt)}),
4245 else => return func.fail("TODO: implement airAbs {f}", .{scalar_ty.fmt(pt)}),
42714246 }
42724247
42734248 break :result .unreach;
......@@ -4331,7 +4306,7 @@ fn airByteSwap(func: *Func, inst: Air.Inst.Index) !void {
43314306
43324307 break :result dest_mcv;
43334308 },
4334 else => return func.fail("TODO: airByteSwap {}", .{ty.fmt(pt)}),
4309 else => return func.fail("TODO: airByteSwap {f}", .{ty.fmt(pt)}),
43354310 }
43364311 };
43374312 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -4397,7 +4372,7 @@ fn airUnaryMath(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
43974372 else => return func.fail("TODO: airUnaryMath Float {s}", .{@tagName(tag)}),
43984373 }
43994374 },
4400 else => return func.fail("TODO: airUnaryMath ty: {}", .{ty.fmt(pt)}),
4375 else => return func.fail("TODO: airUnaryMath ty: {f}", .{ty.fmt(pt)}),
44014376 }
44024377
44034378 break :result MCValue{ .register = dst_reg };
......@@ -4497,7 +4472,7 @@ fn load(func: *Func, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerErro
44974472 const zcu = pt.zcu;
44984473 const dst_ty = ptr_ty.childType(zcu);
44994474
4500 log.debug("loading {}:{} into {}", .{ ptr_mcv, ptr_ty.fmt(pt), dst_mcv });
4475 log.debug("loading {}:{f} into {}", .{ ptr_mcv, ptr_ty.fmt(pt), dst_mcv });
45014476
45024477 switch (ptr_mcv) {
45034478 .none,
......@@ -4550,7 +4525,7 @@ fn airStore(func: *Func, inst: Air.Inst.Index, safety: bool) !void {
45504525fn store(func: *Func, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type) !void {
45514526 const zcu = func.pt.zcu;
45524527 const src_ty = ptr_ty.childType(zcu);
4553 log.debug("storing {}:{} in {}:{}", .{ src_mcv, src_ty.fmt(func.pt), ptr_mcv, ptr_ty.fmt(func.pt) });
4528 log.debug("storing {}:{f} in {}:{f}", .{ src_mcv, src_ty.fmt(func.pt), ptr_mcv, ptr_ty.fmt(func.pt) });
45544529
45554530 switch (ptr_mcv) {
45564531 .none => unreachable,
......@@ -7305,7 +7280,7 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void {
73057280 const bit_size = dst_ty.bitSize(zcu);
73067281 if (abi_size * 8 <= bit_size) break :result dst_mcv;
73077282
7308 return func.fail("TODO: airBitCast {} to {}", .{ src_ty.fmt(pt), dst_ty.fmt(pt) });
7283 return func.fail("TODO: airBitCast {f} to {f}", .{ src_ty.fmt(pt), dst_ty.fmt(pt) });
73097284 };
73107285 return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
73117286}
......@@ -8121,7 +8096,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void {
81218096 );
81228097 break :result .{ .load_frame = .{ .index = frame_index } };
81238098 },
8124 else => return func.fail("TODO: airAggregate {}", .{result_ty.fmt(pt)}),
8099 else => return func.fail("TODO: airAggregate {f}", .{result_ty.fmt(pt)}),
81258100 }
81268101 };
81278102
......@@ -8322,7 +8297,7 @@ fn resolveCallingConventionValues(
83228297 };
83238298
83248299 result.return_value = switch (ret_tracking_i) {
8325 else => return func.fail("ty {} took {} tracking return indices", .{ ret_ty.fmt(pt), ret_tracking_i }),
8300 else => return func.fail("ty {f} took {} tracking return indices", .{ ret_ty.fmt(pt), ret_tracking_i }),
83268301 1 => ret_tracking[0],
83278302 2 => InstTracking.init(.{ .register_pair = .{
83288303 ret_tracking[0].short.register, ret_tracking[1].short.register,
......@@ -8377,7 +8352,7 @@ fn resolveCallingConventionValues(
83778352 else => return func.fail("TODO: C calling convention arg class {}", .{class}),
83788353 } else {
83798354 arg.* = switch (arg_mcv_i) {
8380 else => return func.fail("ty {} took {} tracking arg indices", .{ ty.fmt(pt), arg_mcv_i }),
8355 else => return func.fail("ty {f} took {} tracking arg indices", .{ ty.fmt(pt), arg_mcv_i }),
83818356 1 => arg_mcv[0],
83828357 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } },
83838358 };
src/arch/riscv64/Emit.zig+20-11
......@@ -18,20 +18,28 @@ pub const Error = Lower.Error || error{
1818};
1919
2020pub fn emitMir(emit: *Emit) Error!void {
21 return @errorCast(emit.emitMirInner());
22}
23
24fn emitMirInner(emit: *Emit) anyerror!void {
2125 const gpa = emit.bin_file.comp.gpa;
26 var aw: std.io.AllocatingWriter = undefined;
27 const bw = aw.fromArrayList(gpa, emit.code);
28 defer emit.code.* = aw.toArrayList();
29
2230 log.debug("mir instruction len: {}", .{emit.lower.mir.instructions.len});
2331 for (0..emit.lower.mir.instructions.len) |mir_i| {
2432 const mir_index: Mir.Inst.Index = @intCast(mir_i);
2533 try emit.code_offset_mapping.putNoClobber(
2634 emit.lower.allocator,
2735 mir_index,
28 @intCast(emit.code.items.len),
36 @intCast(bw.count),
2937 );
3038 const lowered = try emit.lower.lowerMir(mir_index, .{ .allow_frame_locs = true });
3139 var lowered_relocs = lowered.relocs;
3240 for (lowered.insts, 0..) |lowered_inst, lowered_index| {
33 const start_offset: u32 = @intCast(emit.code.items.len);
34 try lowered_inst.encode(emit.code.writer(gpa));
41 const start_offset: u32 = @intCast(bw.count);
42 try lowered_inst.encode(bw);
3543
3644 while (lowered_relocs.len > 0 and
3745 lowered_relocs[0].lowered_inst_index == lowered_index) : ({
......@@ -123,7 +131,7 @@ pub fn emitMir(emit: *Emit) Error!void {
123131 log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
124132 emit.prev_di_line, emit.prev_di_column,
125133 });
126 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
134 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column, bw.count);
127135 },
128136 .plan9 => {},
129137 .none => {},
......@@ -132,6 +140,7 @@ pub fn emitMir(emit: *Emit) Error!void {
132140 .pseudo_dbg_line_column => try emit.dbgAdvancePCAndLine(
133141 mir_inst.data.pseudo_dbg_line_column.line,
134142 mir_inst.data.pseudo_dbg_line_column.column,
143 bw.count,
135144 ),
136145 .pseudo_dbg_epilogue_begin => {
137146 switch (emit.debug_output) {
......@@ -140,7 +149,7 @@ pub fn emitMir(emit: *Emit) Error!void {
140149 log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
141150 emit.prev_di_line, emit.prev_di_column,
142151 });
143 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
152 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column, bw.count);
144153 },
145154 .plan9 => {},
146155 .none => {},
......@@ -150,7 +159,7 @@ pub fn emitMir(emit: *Emit) Error!void {
150159 }
151160 }
152161 }
153 try emit.fixupRelocs();
162 try emit.fixupRelocs(aw.getWritten());
154163}
155164
156165pub fn deinit(emit: *Emit) void {
......@@ -170,14 +179,14 @@ const Reloc = struct {
170179 fmt: encoding.Lir.Format,
171180};
172181
173fn fixupRelocs(emit: *Emit) Error!void {
182fn fixupRelocs(emit: *Emit, written: []u8) Error!void {
174183 for (emit.relocs.items) |reloc| {
175 log.debug("target inst: {}", .{emit.lower.mir.instructions.get(reloc.target)});
184 log.debug("target inst: {f}", .{emit.lower.mir.instructions.get(reloc.target)});
176185 const target = emit.code_offset_mapping.get(reloc.target) orelse
177186 return emit.fail("relocation target not found!", .{});
178187
179188 const disp = @as(i32, @intCast(target)) - @as(i32, @intCast(reloc.source));
180 const code: *[4]u8 = emit.code.items[reloc.source + reloc.offset ..][0..4];
189 const code: *[4]u8 = written[reloc.source + reloc.offset ..][0..4];
181190
182191 switch (reloc.fmt) {
183192 .J => riscv_util.writeInstJ(code, @bitCast(disp)),
......@@ -187,9 +196,9 @@ fn fixupRelocs(emit: *Emit) Error!void {
187196 }
188197}
189198
190fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
199fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32, pc: usize) Error!void {
191200 const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
192 const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
201 const delta_pc = pc - emit.prev_di_pc;
193202 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
194203 switch (emit.debug_output) {
195204 .dwarf => |dw| {
src/arch/riscv64/Lower.zig+1-1
......@@ -61,7 +61,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct {
6161 defer lower.result_relocs_len = undefined;
6262
6363 const inst = lower.mir.instructions.get(index);
64 log.debug("lowerMir {}", .{inst});
64 log.debug("lowerMir {f}", .{inst});
6565 switch (inst.tag) {
6666 else => try lower.generic(inst),
6767 .pseudo_dbg_line_column,
src/arch/riscv64/Mir.zig+2-7
......@@ -92,14 +92,9 @@ pub const Inst = struct {
9292 },
9393 };
9494
95 pub fn format(
96 inst: Inst,
97 comptime fmt: []const u8,
98 _: std.fmt.FormatOptions,
99 writer: anytype,
100 ) !void {
95 pub fn format(inst: Inst, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
10196 assert(fmt.len == 0);
102 try writer.print("Tag: {s}, Data: {s}", .{ @tagName(inst.tag), @tagName(inst.data) });
97 try bw.print("Tag: {s}, Data: {s}", .{ @tagName(inst.tag), @tagName(inst.data) });
10398 }
10499};
105100
src/arch/riscv64/bits.zig+6-15
......@@ -256,21 +256,12 @@ pub const FrameIndex = enum(u32) {
256256 return @intFromEnum(fi) < named_count;
257257 }
258258
259 pub fn format(
260 fi: FrameIndex,
261 comptime fmt: []const u8,
262 options: std.fmt.FormatOptions,
263 writer: anytype,
264 ) @TypeOf(writer).Error!void {
265 try writer.writeAll("FrameIndex");
266 if (fi.isNamed()) {
267 try writer.writeByte('.');
268 try writer.writeAll(@tagName(fi));
269 } else {
270 try writer.writeByte('(');
271 try std.fmt.formatType(@intFromEnum(fi), fmt, options, writer, 0);
272 try writer.writeByte(')');
273 }
259 pub fn format(fi: FrameIndex, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
260 try bw.writeAll("FrameIndex");
261 if (fi.isNamed())
262 try bw.print(".{s}", .{@tagName(fi)})
263 else
264 try bw.print("({d})", .{@intFromEnum(fi)});
274265 }
275266};
276267
src/arch/sparc64/CodeGen.zig+5-5
......@@ -1001,7 +1001,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void {
10011001 switch (self.args[arg_index]) {
10021002 .stack_offset => |off| {
10031003 const abi_size = math.cast(u32, ty.abiSize(zcu)) orelse {
1004 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
1004 return self.fail("type '{f}' too big to fit into stack frame", .{ty.fmt(pt)});
10051005 };
10061006 const offset = off + abi_size;
10071007 break :blk .{ .stack_offset = offset };
......@@ -2748,7 +2748,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
27482748 }
27492749
27502750 const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse {
2751 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
2751 return self.fail("type '{f}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
27522752 };
27532753 // TODO swap this for inst.ty.ptrAlign
27542754 const abi_align = elem_ty.abiAlignment(zcu);
......@@ -2760,7 +2760,7 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
27602760 const zcu = pt.zcu;
27612761 const elem_ty = self.typeOfIndex(inst);
27622762 const abi_size = math.cast(u32, elem_ty.abiSize(zcu)) orelse {
2763 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
2763 return self.fail("type '{f}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
27642764 };
27652765 const abi_align = elem_ty.abiAlignment(zcu);
27662766 self.stack_align = self.stack_align.max(abi_align);
......@@ -4111,7 +4111,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
41114111 while (true) {
41124112 i -= 1;
41134113 if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| {
4114 log.debug("getResolvedInstValue %{} => {}", .{ inst, mcv });
4114 log.debug("getResolvedInstValue %{f} => {}", .{ inst, mcv });
41154115 assert(mcv != .dead);
41164116 return mcv;
41174117 }
......@@ -4382,7 +4382,7 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {
43824382 const prev_value = self.getResolvedInstValue(inst);
43834383 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
43844384 branch.inst_table.putAssumeCapacity(inst, .dead);
4385 log.debug("%{} death: {} -> .dead", .{ inst, prev_value });
4385 log.debug("%{f} death: {} -> .dead", .{ inst, prev_value });
43864386 switch (prev_value) {
43874387 .register => |reg| {
43884388 self.register_manager.freeReg(reg);
src/arch/wasm/CodeGen.zig+16-16
......@@ -1463,7 +1463,7 @@ fn allocStack(cg: *CodeGen, ty: Type) !WValue {
14631463 }
14641464
14651465 const abi_size = std.math.cast(u32, ty.abiSize(zcu)) orelse {
1466 return cg.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1466 return cg.fail("Type {f} with ABI size of {d} exceeds stack frame size", .{
14671467 ty.fmt(pt), ty.abiSize(zcu),
14681468 });
14691469 };
......@@ -1497,7 +1497,7 @@ fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue {
14971497
14981498 const abi_alignment = ptr_ty.ptrAlignment(zcu);
14991499 const abi_size = std.math.cast(u32, pointee_ty.abiSize(zcu)) orelse {
1500 return cg.fail("Type {} with ABI size of {d} exceeds stack frame size", .{
1500 return cg.fail("Type {f} with ABI size of {d} exceeds stack frame size", .{
15011501 pointee_ty.fmt(pt), pointee_ty.abiSize(zcu),
15021502 });
15031503 };
......@@ -2404,7 +2404,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
24042404 try cg.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(zcu))) });
24052405 },
24062406 else => if (abi_size > 8) {
2407 return cg.fail("TODO: `store` for type `{}` with abisize `{d}`", .{
2407 return cg.fail("TODO: `store` for type `{f}` with abisize `{d}`", .{
24082408 ty.fmt(pt),
24092409 abi_size,
24102410 });
......@@ -2597,7 +2597,7 @@ fn binOp(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WV
25972597 return cg.binOpBigInt(lhs, rhs, ty, op);
25982598 } else {
25992599 return cg.fail(
2600 "TODO: Implement binary operation for type: {}",
2600 "TODO: Implement binary operation for type: {f}",
26012601 .{ty.fmt(pt)},
26022602 );
26032603 }
......@@ -2817,7 +2817,7 @@ fn airAbs(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
28172817
28182818 switch (scalar_ty.zigTypeTag(zcu)) {
28192819 .int => if (ty.zigTypeTag(zcu) == .vector) {
2820 return cg.fail("TODO implement airAbs for {}", .{ty.fmt(pt)});
2820 return cg.fail("TODO implement airAbs for {f}", .{ty.fmt(pt)});
28212821 } else {
28222822 const int_bits = ty.intInfo(zcu).bits;
28232823 const wasm_bits = toWasmBits(int_bits) orelse {
......@@ -3244,7 +3244,7 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32443244 return .{ .imm32 = @intFromBool(!val.isNull(zcu)) };
32453245 },
32463246 .aggregate => switch (ip.indexToKey(ty.ip_index)) {
3247 .array_type => return cg.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),
3247 .array_type => return cg.fail("Wasm TODO: LowerConstant for {f}", .{ty.fmt(pt)}),
32483248 .vector_type => {
32493249 assert(determineSimdStoreStrategy(ty, zcu, cg.target) == .direct);
32503250 var buf: [16]u8 = undefined;
......@@ -3608,7 +3608,7 @@ fn airNot(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
36083608 } else {
36093609 const int_info = operand_ty.intInfo(zcu);
36103610 const wasm_bits = toWasmBits(int_info.bits) orelse {
3611 return cg.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(pt)});
3611 return cg.fail("TODO: Implement binary NOT for {f}", .{operand_ty.fmt(pt)});
36123612 };
36133613
36143614 switch (wasm_bits) {
......@@ -3874,7 +3874,7 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38743874 },
38753875 else => result: {
38763876 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, zcu)) orelse {
3877 return cg.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)});
3877 return cg.fail("Field type '{f}' too big to fit into stack frame", .{field_ty.fmt(pt)});
38783878 };
38793879 if (isByRef(field_ty, zcu, cg.target)) {
38803880 switch (operand) {
......@@ -4360,7 +4360,7 @@ fn isNull(cg: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.Opc
43604360 // a pointer to the stack value
43614361 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
43624362 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
4363 return cg.fail("Optional type {} too big to fit into stack frame", .{optional_ty.fmt(pt)});
4363 return cg.fail("Optional type {f} too big to fit into stack frame", .{optional_ty.fmt(pt)});
43644364 };
43654365 try cg.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 });
43664366 }
......@@ -4430,7 +4430,7 @@ fn airOptionalPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
44304430 }
44314431
44324432 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
4433 return cg.fail("Optional type {} too big to fit into stack frame", .{opt_ty.fmt(pt)});
4433 return cg.fail("Optional type {f} too big to fit into stack frame", .{opt_ty.fmt(pt)});
44344434 };
44354435
44364436 try cg.emitWValue(operand);
......@@ -4462,7 +4462,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44624462 break :result cg.reuseOperand(ty_op.operand, operand);
44634463 }
44644464 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
4465 return cg.fail("Optional type {} too big to fit into stack frame", .{op_ty.fmt(pt)});
4465 return cg.fail("Optional type {f} too big to fit into stack frame", .{op_ty.fmt(pt)});
44664466 };
44674467
44684468 // Create optional type, set the non-null bit, and store the operand inside the optional type
......@@ -6196,7 +6196,7 @@ fn airMulWithOverflow(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
61966196 _ = try cg.load(overflow_ret, Type.i32, 0);
61976197 try cg.addLocal(.local_set, overflow_bit.local.value);
61986198 break :blk res;
6199 } else return cg.fail("TODO: @mulWithOverflow for {}", .{ty.fmt(pt)});
6199 } else return cg.fail("TODO: @mulWithOverflow for {f}", .{ty.fmt(pt)});
62006200 var bin_op_local = try mul.toLocal(cg, ty);
62016201 defer bin_op_local.free(cg);
62026202
......@@ -6749,7 +6749,7 @@ fn airMod(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
67496749 const add = try cg.binOp(rem, rhs, ty, .add);
67506750 break :result try cg.binOp(add, rhs, ty, .rem);
67516751 }
6752 return cg.fail("TODO: @mod for {}", .{ty.fmt(pt)});
6752 return cg.fail("TODO: @mod for {f}", .{ty.fmt(pt)});
67536753 };
67546754
67556755 return cg.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
......@@ -6767,7 +6767,7 @@ fn airSatMul(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
67676767 const lhs = try cg.resolveInst(bin_op.lhs);
67686768 const rhs = try cg.resolveInst(bin_op.rhs);
67696769 const wasm_bits = toWasmBits(int_info.bits) orelse {
6770 return cg.fail("TODO: mul_sat for {}", .{ty.fmt(pt)});
6770 return cg.fail("TODO: mul_sat for {f}", .{ty.fmt(pt)});
67716771 };
67726772
67736773 switch (wasm_bits) {
......@@ -6804,7 +6804,7 @@ fn airSatMul(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68046804 },
68056805 64 => {
68066806 if (!(int_info.bits == 64 and int_info.signedness == .signed)) {
6807 return cg.fail("TODO: mul_sat for {}", .{ty.fmt(pt)});
6807 return cg.fail("TODO: mul_sat for {f}", .{ty.fmt(pt)});
68086808 }
68096809 const overflow_ret = try cg.allocStack(Type.i32);
68106810 _ = try cg.callIntrinsic(
......@@ -6822,7 +6822,7 @@ fn airSatMul(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68226822 },
68236823 128 => {
68246824 if (!(int_info.bits == 128 and int_info.signedness == .signed)) {
6825 return cg.fail("TODO: mul_sat for {}", .{ty.fmt(pt)});
6825 return cg.fail("TODO: mul_sat for {f}", .{ty.fmt(pt)});
68266826 }
68276827 const overflow_ret = try cg.allocStack(Type.i32);
68286828 const ret = try cg.callIntrinsic(
src/arch/wasm/Emit.zig+105-133
......@@ -14,16 +14,20 @@ const codegen = @import("../../codegen.zig");
1414
1515mir: Mir,
1616wasm: *Wasm,
17/// The binary representation that will be emitted by this module.
18code: *std.ArrayListUnmanaged(u8),
17/// The binary representation of this module is written here.
18bw: *std.io.BufferedWriter,
1919
2020pub const Error = error{
2121 OutOfMemory,
2222};
2323
2424pub fn lowerToCode(emit: *Emit) Error!void {
25 return @errorCast(emit.lowerToCodeInner());
26}
27
28fn lowerToCodeInner(emit: *Emit) anyerror!void {
2529 const mir = &emit.mir;
26 const code = emit.code;
30 const bw = emit.bw;
2731 const wasm = emit.wasm;
2832 const comp = wasm.base.comp;
2933 const gpa = comp.gpa;
......@@ -41,18 +45,19 @@ pub fn lowerToCode(emit: *Emit) Error!void {
4145 },
4246 .block, .loop => {
4347 const block_type = datas[inst].block_type;
44 try code.ensureUnusedCapacity(gpa, 2);
45 code.appendAssumeCapacity(@intFromEnum(tags[inst]));
46 code.appendAssumeCapacity(@intFromEnum(block_type));
48 try bw.writeAll(&.{
49 @intFromEnum(tags[inst]),
50 @intFromEnum(block_type),
51 });
4752
4853 inst += 1;
4954 continue :loop tags[inst];
5055 },
5156 .uav_ref => {
5257 if (is_obj) {
53 try uavRefObj(wasm, code, datas[inst].ip_index, 0, is_wasm32);
58 try uavRefObj(wasm, bw, datas[inst].ip_index, 0, is_wasm32);
5459 } else {
55 try uavRefExe(wasm, code, datas[inst].ip_index, 0, is_wasm32);
60 try uavRefExe(wasm, bw, datas[inst].ip_index, 0, is_wasm32);
5661 }
5762 inst += 1;
5863 continue :loop tags[inst];
......@@ -60,20 +65,20 @@ pub fn lowerToCode(emit: *Emit) Error!void {
6065 .uav_ref_off => {
6166 const extra = mir.extraData(Mir.UavRefOff, datas[inst].payload).data;
6267 if (is_obj) {
63 try uavRefObj(wasm, code, extra.value, extra.offset, is_wasm32);
68 try uavRefObj(wasm, bw, extra.value, extra.offset, is_wasm32);
6469 } else {
65 try uavRefExe(wasm, code, extra.value, extra.offset, is_wasm32);
70 try uavRefExe(wasm, bw, extra.value, extra.offset, is_wasm32);
6671 }
6772 inst += 1;
6873 continue :loop tags[inst];
6974 },
7075 .nav_ref => {
71 try navRefOff(wasm, code, .{ .nav_index = datas[inst].nav_index, .offset = 0 }, is_wasm32);
76 try navRefOff(wasm, bw, .{ .nav_index = datas[inst].nav_index, .offset = 0 }, is_wasm32);
7277 inst += 1;
7378 continue :loop tags[inst];
7479 },
7580 .nav_ref_off => {
76 try navRefOff(wasm, code, mir.extraData(Mir.NavRefOff, datas[inst].payload).data, is_wasm32);
81 try navRefOff(wasm, bw, mir.extraData(Mir.NavRefOff, datas[inst].payload).data, is_wasm32);
7782 inst += 1;
7883 continue :loop tags[inst];
7984 },
......@@ -81,11 +86,11 @@ pub fn lowerToCode(emit: *Emit) Error!void {
8186 const indirect_func_idx: Wasm.ZcuIndirectFunctionSetIndex = @enumFromInt(
8287 wasm.zcu_indirect_function_set.getIndex(datas[inst].nav_index).?,
8388 );
84 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
89 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
8590 if (is_obj) {
8691 @panic("TODO");
8792 } else {
88 leb.writeUleb128(code.fixedWriter(), 1 + @intFromEnum(indirect_func_idx)) catch unreachable;
93 try bw.writeLeb128(1 + @intFromEnum(indirect_func_idx));
8994 }
9095 inst += 1;
9196 continue :loop tags[inst];
......@@ -95,52 +100,48 @@ pub fn lowerToCode(emit: *Emit) Error!void {
95100 continue :loop tags[inst];
96101 },
97102 .errors_len => {
98 try code.ensureUnusedCapacity(gpa, 6);
99 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
103 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
100104 // MIR is lowered during flush, so there is indeed only one thread at this time.
101 const errors_len = 1 + comp.zcu.?.intern_pool.global_error_set.getNamesFromMainThread().len;
102 leb.writeIleb128(code.fixedWriter(), errors_len) catch unreachable;
105 const errors_len: u32 = @intCast(1 + comp.zcu.?.intern_pool.global_error_set.getNamesFromMainThread().len);
106 try bw.writeLeb128(@as(i32, @bitCast(errors_len)));
103107
104108 inst += 1;
105109 continue :loop tags[inst];
106110 },
107111 .error_name_table_ref => {
108112 wasm.error_name_table_ref_count += 1;
109 try code.ensureUnusedCapacity(gpa, 11);
110113 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
111 code.appendAssumeCapacity(@intFromEnum(opcode));
114 try bw.writeByte(@intFromEnum(opcode));
112115 if (is_obj) {
113116 try wasm.out_relocs.append(gpa, .{
114 .offset = @intCast(code.items.len),
117 .offset = @intCast(bw.count),
115118 .pointee = .{ .symbol_index = try wasm.errorNameTableSymbolIndex() },
116119 .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64,
117120 .addend = 0,
118121 });
119 code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
122 try bw.splatByteAll(0, if (is_wasm32) 5 else 10);
120123
121124 inst += 1;
122125 continue :loop tags[inst];
123126 } else {
124127 const addr: u32 = wasm.errorNameTableAddr();
125 leb.writeIleb128(code.fixedWriter(), addr) catch unreachable;
128 try bw.writeLeb128(@as(i32, @bitCast(addr)));
126129
127130 inst += 1;
128131 continue :loop tags[inst];
129132 }
130133 },
131134 .br_if, .br, .memory_grow, .memory_size => {
132 try code.ensureUnusedCapacity(gpa, 11);
133 code.appendAssumeCapacity(@intFromEnum(tags[inst]));
134 leb.writeUleb128(code.fixedWriter(), datas[inst].label) catch unreachable;
135 try bw.writeByte(@intFromEnum(tags[inst]));
136 try bw.writeLeb128(datas[inst].label);
135137
136138 inst += 1;
137139 continue :loop tags[inst];
138140 },
139141
140142 .local_get, .local_set, .local_tee => {
141 try code.ensureUnusedCapacity(gpa, 11);
142 code.appendAssumeCapacity(@intFromEnum(tags[inst]));
143 leb.writeUleb128(code.fixedWriter(), datas[inst].local) catch unreachable;
143 try bw.writeByte(@intFromEnum(tags[inst]));
144 try bw.writeLeb128(datas[inst].local);
144145
145146 inst += 1;
146147 continue :loop tags[inst];
......@@ -150,29 +151,27 @@ pub fn lowerToCode(emit: *Emit) Error!void {
150151 const extra_index = datas[inst].payload;
151152 const extra = mir.extraData(Mir.JumpTable, extra_index);
152153 const labels = mir.extra[extra.end..][0..extra.data.length];
153 try code.ensureUnusedCapacity(gpa, 11 + 10 * labels.len);
154 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_table));
154 try bw.writeByte(@intFromEnum(std.wasm.Opcode.br_table));
155155 // -1 because default label is not part of length/depth.
156 leb.writeUleb128(code.fixedWriter(), extra.data.length - 1) catch unreachable;
157 for (labels) |label| leb.writeUleb128(code.fixedWriter(), label) catch unreachable;
156 try bw.writeLeb128(extra.data.length - 1);
157 for (labels) |label| try bw.writeLeb128(label);
158158
159159 inst += 1;
160160 continue :loop tags[inst];
161161 },
162162
163163 .call_nav => {
164 try code.ensureUnusedCapacity(gpa, 6);
165 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call));
164 try bw.writeByte(@intFromEnum(std.wasm.Opcode.call));
166165 if (is_obj) {
167166 try wasm.out_relocs.append(gpa, .{
168 .offset = @intCast(code.items.len),
167 .offset = @intCast(bw.count),
169168 .pointee = .{ .symbol_index = try wasm.navSymbolIndex(datas[inst].nav_index) },
170169 .tag = .function_index_leb,
171170 .addend = 0,
172171 });
173 code.appendNTimesAssumeCapacity(0, 5);
172 try bw.splatByteAll(0, 5);
174173 } else {
175 appendOutputFunctionIndex(code, .fromIpNav(wasm, datas[inst].nav_index));
174 try appendOutputFunctionIndex(bw, .fromIpNav(wasm, datas[inst].nav_index));
176175 }
177176
178177 inst += 1;
......@@ -180,7 +179,6 @@ pub fn lowerToCode(emit: *Emit) Error!void {
180179 },
181180
182181 .call_indirect => {
183 try code.ensureUnusedCapacity(gpa, 11);
184182 const fn_info = comp.zcu.?.typeToFunc(.fromInterned(datas[inst].ip_index)).?;
185183 const func_ty_index = wasm.getExistingFunctionType(
186184 fn_info.cc,
......@@ -188,38 +186,37 @@ pub fn lowerToCode(emit: *Emit) Error!void {
188186 .fromInterned(fn_info.return_type),
189187 target,
190188 ).?;
191 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect));
189 try bw.writeByte(@intFromEnum(std.wasm.Opcode.call_indirect));
192190 if (is_obj) {
193191 try wasm.out_relocs.append(gpa, .{
194 .offset = @intCast(code.items.len),
192 .offset = @intCast(bw.count),
195193 .pointee = .{ .type_index = func_ty_index },
196194 .tag = .type_index_leb,
197195 .addend = 0,
198196 });
199 code.appendNTimesAssumeCapacity(0, 5);
197 try bw.splatByteAll(0, 5);
200198 } else {
201199 const index: Wasm.Flush.FuncTypeIndex = .fromTypeIndex(func_ty_index, &wasm.flush_buffer);
202 leb.writeUleb128(code.fixedWriter(), @intFromEnum(index)) catch unreachable;
200 try bw.writeLeb128(@intFromEnum(index));
203201 }
204 leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // table index
202 try bw.writeUleb128(0); // table index
205203
206204 inst += 1;
207205 continue :loop tags[inst];
208206 },
209207
210208 .call_tag_name => {
211 try code.ensureUnusedCapacity(gpa, 6);
212 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call));
209 try bw.writeByte(@intFromEnum(std.wasm.Opcode.call));
213210 if (is_obj) {
214211 try wasm.out_relocs.append(gpa, .{
215 .offset = @intCast(code.items.len),
212 .offset = @intCast(bw.count),
216213 .pointee = .{ .symbol_index = try wasm.tagNameSymbolIndex(datas[inst].ip_index) },
217214 .tag = .function_index_leb,
218215 .addend = 0,
219216 });
220 code.appendNTimesAssumeCapacity(0, 5);
217 try bw.splatByteAll(0, 5);
221218 } else {
222 appendOutputFunctionIndex(code, .fromTagNameType(wasm, datas[inst].ip_index));
219 try appendOutputFunctionIndex(bw, .fromTagNameType(wasm, datas[inst].ip_index));
223220 }
224221
225222 inst += 1;
......@@ -232,18 +229,17 @@ pub fn lowerToCode(emit: *Emit) Error!void {
232229 // table initialized based on the `Mir.Intrinsic` enum.
233230 const symbol_name = try wasm.internString(@tagName(datas[inst].intrinsic));
234231
235 try code.ensureUnusedCapacity(gpa, 6);
236 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call));
232 try bw.writeByte(@intFromEnum(std.wasm.Opcode.call));
237233 if (is_obj) {
238234 try wasm.out_relocs.append(gpa, .{
239 .offset = @intCast(code.items.len),
235 .offset = @intCast(bw.count),
240236 .pointee = .{ .symbol_index = try wasm.symbolNameIndex(symbol_name) },
241237 .tag = .function_index_leb,
242238 .addend = 0,
243239 });
244 code.appendNTimesAssumeCapacity(0, 5);
240 try bw.splatByteAll(0, 5);
245241 } else {
246 appendOutputFunctionIndex(code, .fromSymbolName(wasm, symbol_name));
242 try appendOutputFunctionIndex(bw, .fromSymbolName(wasm, symbol_name));
247243 }
248244
249245 inst += 1;
......@@ -251,19 +247,17 @@ pub fn lowerToCode(emit: *Emit) Error!void {
251247 },
252248
253249 .global_set_sp => {
254 try code.ensureUnusedCapacity(gpa, 6);
255 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_set));
250 try bw.writeByte(@intFromEnum(std.wasm.Opcode.global_set));
256251 if (is_obj) {
257252 try wasm.out_relocs.append(gpa, .{
258 .offset = @intCast(code.items.len),
253 .offset = @intCast(bw.count),
259254 .pointee = .{ .symbol_index = try wasm.stackPointerSymbolIndex() },
260255 .tag = .global_index_leb,
261256 .addend = 0,
262257 });
263 code.appendNTimesAssumeCapacity(0, 5);
258 try bw.splatByteAll(0, 5);
264259 } else {
265 const sp_global: Wasm.GlobalIndex = .stack_pointer;
266 std.leb.writeULEB128(code.fixedWriter(), @intFromEnum(sp_global)) catch unreachable;
260 try bw.writeLeb128(@intFromEnum(Wasm.GlobalIndex.stack_pointer));
267261 }
268262
269263 inst += 1;
......@@ -271,36 +265,32 @@ pub fn lowerToCode(emit: *Emit) Error!void {
271265 },
272266
273267 .f32_const => {
274 try code.ensureUnusedCapacity(gpa, 5);
275 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.f32_const));
276 std.mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), @bitCast(datas[inst].float32), .little);
268 try bw.writeByte(@intFromEnum(std.wasm.Opcode.f32_const));
269 try bw.writeInt(u32, @bitCast(datas[inst].float32), .little);
277270
278271 inst += 1;
279272 continue :loop tags[inst];
280273 },
281274
282275 .f64_const => {
283 try code.ensureUnusedCapacity(gpa, 9);
284 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.f64_const));
276 try bw.writeByte(@intFromEnum(std.wasm.Opcode.f64_const));
285277 const float64 = mir.extraData(Mir.Float64, datas[inst].payload).data;
286 std.mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), float64.toInt(), .little);
278 try bw.writeInt(u64, float64.toInt(), .little);
287279
288280 inst += 1;
289281 continue :loop tags[inst];
290282 },
291283 .i32_const => {
292 try code.ensureUnusedCapacity(gpa, 6);
293 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
294 leb.writeIleb128(code.fixedWriter(), datas[inst].imm32) catch unreachable;
284 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
285 try bw.writeLeb128(datas[inst].imm32);
295286
296287 inst += 1;
297288 continue :loop tags[inst];
298289 },
299290 .i64_const => {
300 try code.ensureUnusedCapacity(gpa, 11);
301 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
291 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_const));
302292 const int64: i64 = @bitCast(mir.extraData(Mir.Imm64, datas[inst].payload).data.toInt());
303 leb.writeIleb128(code.fixedWriter(), int64) catch unreachable;
293 try bw.writeLeb128(int64);
304294
305295 inst += 1;
306296 continue :loop tags[inst];
......@@ -330,9 +320,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
330320 .i64_store16,
331321 .i64_store32,
332322 => {
333 try code.ensureUnusedCapacity(gpa, 1 + 20);
334 code.appendAssumeCapacity(@intFromEnum(tags[inst]));
335 encodeMemArg(code, mir.extraData(Mir.MemArg, datas[inst].payload).data);
323 try bw.writeByte(@intFromEnum(tags[inst]));
324 try encodeMemArg(bw, mir.extraData(Mir.MemArg, datas[inst].payload).data);
336325 inst += 1;
337326 continue :loop tags[inst];
338327 },
......@@ -466,43 +455,42 @@ pub fn lowerToCode(emit: *Emit) Error!void {
466455 .i64_clz,
467456 .i64_ctz,
468457 => {
469 try code.append(gpa, @intFromEnum(tags[inst]));
458 try bw.writeByte(@intFromEnum(tags[inst]));
470459 inst += 1;
471460 continue :loop tags[inst];
472461 },
473462
474463 .misc_prefix => {
475 try code.ensureUnusedCapacity(gpa, 6 + 6);
476464 const extra_index = datas[inst].payload;
477 const opcode = mir.extra[extra_index];
478 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.misc_prefix));
479 leb.writeUleb128(code.fixedWriter(), opcode) catch unreachable;
480 switch (@as(std.wasm.MiscOpcode, @enumFromInt(opcode))) {
465 const opcode: std.wasm.MiscOpcode = @enumFromInt(mir.extra[extra_index]);
466 try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix));
467 try bw.writeLeb128(@intFromEnum(opcode));
468 switch (opcode) {
481469 // bulk-memory opcodes
482470 .data_drop => {
483471 const segment = mir.extra[extra_index + 1];
484 leb.writeUleb128(code.fixedWriter(), segment) catch unreachable;
472 try bw.writeLeb128(segment);
485473
486474 inst += 1;
487475 continue :loop tags[inst];
488476 },
489477 .memory_init => {
490478 const segment = mir.extra[extra_index + 1];
491 leb.writeUleb128(code.fixedWriter(), segment) catch unreachable;
492 leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // memory index
479 try bw.writeLeb128(segment);
480 try bw.writeByte(0); // memory index
493481
494482 inst += 1;
495483 continue :loop tags[inst];
496484 },
497485 .memory_fill => {
498 leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // memory index
486 try bw.writeByte(0); // memory index
499487
500488 inst += 1;
501489 continue :loop tags[inst];
502490 },
503491 .memory_copy => {
504 leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // dst memory index
505 leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // src memory index
492 try bw.writeByte(0); // dst memory index
493 try bw.writeByte(0); // src memory index
506494
507495 inst += 1;
508496 continue :loop tags[inst];
......@@ -534,12 +522,11 @@ pub fn lowerToCode(emit: *Emit) Error!void {
534522 comptime unreachable;
535523 },
536524 .simd_prefix => {
537 try code.ensureUnusedCapacity(gpa, 6 + 20);
538525 const extra_index = datas[inst].payload;
539 const opcode = mir.extra[extra_index];
540 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.simd_prefix));
541 leb.writeUleb128(code.fixedWriter(), opcode) catch unreachable;
542 switch (@as(std.wasm.SimdOpcode, @enumFromInt(opcode))) {
526 const opcode: std.wasm.SimdOpcode = @enumFromInt(mir.extra[extra_index]);
527 try bw.writeByte(@intFromEnum(std.wasm.Opcode.simd_prefix));
528 try bw.writeLeb128(@intFromEnum(opcode));
529 switch (opcode) {
543530 .v128_store,
544531 .v128_load,
545532 .v128_load8_splat,
......@@ -547,12 +534,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {
547534 .v128_load32_splat,
548535 .v128_load64_splat,
549536 => {
550 encodeMemArg(code, mir.extraData(Mir.MemArg, extra_index + 1).data);
537 try encodeMemArg(bw, mir.extraData(Mir.MemArg, extra_index + 1).data);
551538 inst += 1;
552539 continue :loop tags[inst];
553540 },
554541 .v128_const, .i8x16_shuffle => {
555 code.appendSliceAssumeCapacity(std.mem.asBytes(mir.extra[extra_index + 1 ..][0..4]));
542 try bw.writeAll(std.mem.asBytes(mir.extra[extra_index + 1 ..][0..4]));
556543 inst += 1;
557544 continue :loop tags[inst];
558545 },
......@@ -571,7 +558,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
571558 .f64x2_extract_lane,
572559 .f64x2_replace_lane,
573560 => {
574 code.appendAssumeCapacity(@intCast(mir.extra[extra_index + 1]));
561 try bw.writeByte(@intCast(mir.extra[extra_index + 1]));
575562 inst += 1;
576563 continue :loop tags[inst];
577564 },
......@@ -819,13 +806,11 @@ pub fn lowerToCode(emit: *Emit) Error!void {
819806 comptime unreachable;
820807 },
821808 .atomics_prefix => {
822 try code.ensureUnusedCapacity(gpa, 6 + 20);
823
824809 const extra_index = datas[inst].payload;
825 const opcode = mir.extra[extra_index];
826 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.atomics_prefix));
827 leb.writeUleb128(code.fixedWriter(), opcode) catch unreachable;
828 switch (@as(std.wasm.AtomicsOpcode, @enumFromInt(opcode))) {
810 const opcode: std.wasm.AtomicsOpcode = @enumFromInt(mir.extra[extra_index]);
811 try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix));
812 try bw.writeLeb128(@intFromEnum(opcode));
813 switch (opcode) {
829814 .i32_atomic_load,
830815 .i64_atomic_load,
831816 .i32_atomic_load8_u,
......@@ -892,15 +877,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {
892877 .i64_atomic_rmw32_cmpxchg_u,
893878 => {
894879 const mem_arg = mir.extraData(Mir.MemArg, extra_index + 1).data;
895 encodeMemArg(code, mem_arg);
880 try encodeMemArg(bw, mem_arg);
896881 inst += 1;
897882 continue :loop tags[inst];
898883 },
899884 .atomic_fence => {
900 // Hard-codes memory index 0 since multi-memory proposal is
901 // not yet accepted nor implemented.
902 const memory_index: u32 = 0;
903 leb.writeUleb128(code.fixedWriter(), memory_index) catch unreachable;
885 try bw.writeByte(0); // memory index
904886 inst += 1;
905887 continue :loop tags[inst];
906888 },
......@@ -915,44 +897,36 @@ pub fn lowerToCode(emit: *Emit) Error!void {
915897}
916898
917899/// Asserts 20 unused capacity.
918fn encodeMemArg(code: *std.ArrayListUnmanaged(u8), mem_arg: Mir.MemArg) void {
919 assert(code.unusedCapacitySlice().len >= 20);
920 // Wasm encodes alignment as power of 2, rather than natural alignment.
921 const encoded_alignment = @ctz(mem_arg.alignment);
922 leb.writeUleb128(code.fixedWriter(), encoded_alignment) catch unreachable;
923 leb.writeUleb128(code.fixedWriter(), mem_arg.offset) catch unreachable;
900fn encodeMemArg(bw: *std.io.BufferedWriter, mem_arg: Mir.MemArg) anyerror!void {
901 try bw.writeLeb128(Wasm.Alignment.fromNonzeroByteUnits(mem_arg.alignment).toLog2Units());
902 try bw.writeLeb128(mem_arg.offset);
924903}
925904
926fn uavRefObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
905fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
927906 const comp = wasm.base.comp;
928907 const gpa = comp.gpa;
929908 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
930909
931 try code.ensureUnusedCapacity(gpa, 11);
932 code.appendAssumeCapacity(@intFromEnum(opcode));
910 try bw.writeByte(@intFromEnum(opcode));
933911
934912 try wasm.out_relocs.append(gpa, .{
935 .offset = @intCast(code.items.len),
913 .offset = @intCast(bw.count),
936914 .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(value) },
937915 .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64,
938916 .addend = offset,
939917 });
940 code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
918 try bw.splatByteAll(0, if (is_wasm32) 5 else 10);
941919}
942920
943fn uavRefExe(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
944 const comp = wasm.base.comp;
945 const gpa = comp.gpa;
921fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
946922 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
947
948 try code.ensureUnusedCapacity(gpa, 11);
949 code.appendAssumeCapacity(@intFromEnum(opcode));
923 try bw.writeByte(@intFromEnum(opcode));
950924
951925 const addr = wasm.uavAddr(value);
952 leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(@as(i64, addr) + offset))) catch unreachable;
926 try bw.writeLeb128(@as(u32, @intCast(@as(i64, addr) + offset)));
953927}
954928
955fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void {
929fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wasm32: bool) !void {
956930 const comp = wasm.base.comp;
957931 const zcu = comp.zcu.?;
958932 const ip = &zcu.intern_pool;
......@@ -961,24 +935,22 @@ fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff
961935 const nav_ty = ip.getNav(data.nav_index).typeOf(ip);
962936 assert(!ip.isFunctionType(nav_ty));
963937
964 try code.ensureUnusedCapacity(gpa, 11);
965
966938 const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
967 code.appendAssumeCapacity(@intFromEnum(opcode));
939 try bw.writeByte(@intFromEnum(opcode));
968940 if (is_obj) {
969941 try wasm.out_relocs.append(gpa, .{
970 .offset = @intCast(code.items.len),
942 .offset = @intCast(bw.count),
971943 .pointee = .{ .symbol_index = try wasm.navSymbolIndex(data.nav_index) },
972944 .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64,
973945 .addend = data.offset,
974946 });
975 code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10);
947 try bw.splatByteAll(0, if (is_wasm32) 5 else 10);
976948 } else {
977949 const addr = wasm.navAddr(data.nav_index);
978 leb.writeUleb128(code.fixedWriter(), @as(u32, @intCast(@as(i64, addr) + data.offset))) catch unreachable;
950 try bw.writeLeb128(@as(i32, @bitCast(@as(u32, @intCast(@as(i64, addr) + data.offset)))));
979951 }
980952}
981953
982fn appendOutputFunctionIndex(code: *std.ArrayListUnmanaged(u8), i: Wasm.OutputFunctionIndex) void {
983 leb.writeUleb128(code.fixedWriter(), @intFromEnum(i)) catch unreachable;
954fn appendOutputFunctionIndex(bw: *std.io.BufferedWriter, i: Wasm.OutputFunctionIndex) anyerror!void {
955 return bw.writeLeb128(@intFromEnum(i));
984956}
src/arch/x86_64/CodeGen.zig+198-228
......@@ -524,52 +524,47 @@ pub const MCValue = union(enum) {
524524 };
525525 }
526526
527 pub fn format(
528 mcv: MCValue,
529 comptime _: []const u8,
530 _: std.fmt.FormatOptions,
531 writer: anytype,
532 ) @TypeOf(writer).Error!void {
527 pub fn format(mcv: MCValue, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
533528 switch (mcv) {
534 .none, .unreach, .dead, .undef => try writer.print("({s})", .{@tagName(mcv)}),
535 .immediate => |pl| try writer.print("0x{x}", .{pl}),
536 .memory => |pl| try writer.print("[ds:0x{x}]", .{pl}),
537 inline .eflags, .register => |pl| try writer.print("{s}", .{@tagName(pl)}),
538 .register_pair => |pl| try writer.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
539 .register_triple => |pl| try writer.print("{s}:{s}:{s}", .{
529 .none, .unreach, .dead, .undef => try bw.print("({s})", .{@tagName(mcv)}),
530 .immediate => |pl| try bw.print("0x{x}", .{pl}),
531 .memory => |pl| try bw.print("[ds:0x{x}]", .{pl}),
532 inline .eflags, .register => |pl| try bw.print("{s}", .{@tagName(pl)}),
533 .register_pair => |pl| try bw.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
534 .register_triple => |pl| try bw.print("{s}:{s}:{s}", .{
540535 @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
541536 }),
542 .register_quadruple => |pl| try writer.print("{s}:{s}:{s}:{s}", .{
537 .register_quadruple => |pl| try bw.print("{s}:{s}:{s}:{s}", .{
543538 @tagName(pl[3]), @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
544539 }),
545 .register_offset => |pl| try writer.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
546 .register_overflow => |pl| try writer.print("{s}:{s}", .{
540 .register_offset => |pl| try bw.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
541 .register_overflow => |pl| try bw.print("{s}:{s}", .{
547542 @tagName(pl.eflags),
548543 @tagName(pl.reg),
549544 }),
550 .register_mask => |pl| try writer.print("mask({s},{}):{c}{s}", .{
545 .register_mask => |pl| try bw.print("mask({s},{f}):{c}{s}", .{
551546 @tagName(pl.info.kind),
552547 pl.info.scalar,
553548 @as(u8, if (pl.info.inverted) '!' else ' '),
554549 @tagName(pl.reg),
555550 }),
556 .indirect => |pl| try writer.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
557 .indirect_load_frame => |pl| try writer.print("[[{} + 0x{x}]]", .{ pl.index, pl.off }),
558 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
559 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
560 .load_nav => |pl| try writer.print("[nav:{d}]", .{@intFromEnum(pl)}),
561 .lea_nav => |pl| try writer.print("nav:{d}", .{@intFromEnum(pl)}),
562 .load_uav => |pl| try writer.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
563 .lea_uav => |pl| try writer.print("uav:{d}", .{@intFromEnum(pl.val)}),
564 .load_lazy_sym => |pl| try writer.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
565 .lea_lazy_sym => |pl| try writer.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
566 .load_extern_func => |pl| try writer.print("[extern:{d}]", .{@intFromEnum(pl)}),
567 .lea_extern_func => |pl| try writer.print("extern:{d}", .{@intFromEnum(pl)}),
568 .elementwise_args => |pl| try writer.print("elementwise:{d}:[{} + 0x{x}]", .{
551 .indirect => |pl| try bw.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
552 .indirect_load_frame => |pl| try bw.print("[[{} + 0x{x}]]", .{ pl.index, pl.off }),
553 .load_frame => |pl| try bw.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
554 .lea_frame => |pl| try bw.print("{} + 0x{x}", .{ pl.index, pl.off }),
555 .load_nav => |pl| try bw.print("[nav:{d}]", .{@intFromEnum(pl)}),
556 .lea_nav => |pl| try bw.print("nav:{d}", .{@intFromEnum(pl)}),
557 .load_uav => |pl| try bw.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
558 .lea_uav => |pl| try bw.print("uav:{d}", .{@intFromEnum(pl.val)}),
559 .load_lazy_sym => |pl| try bw.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
560 .lea_lazy_sym => |pl| try bw.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
561 .load_extern_func => |pl| try bw.print("[extern:{d}]", .{@intFromEnum(pl)}),
562 .lea_extern_func => |pl| try bw.print("extern:{d}", .{@intFromEnum(pl)}),
563 .elementwise_args => |pl| try bw.print("elementwise:{d}:[{} + 0x{x}]", .{
569564 pl.regs, pl.frame_index, pl.frame_off,
570565 }),
571 .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),
572 .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}),
566 .reserved_frame => |pl| try bw.print("(dead:{})", .{pl}),
567 .air_ref => |pl| try bw.print("(air:0x{x})", .{@intFromEnum(pl)}),
573568 }
574569 }
575570};
......@@ -639,7 +634,7 @@ const InstTracking = struct {
639634 .reserved_frame => |index| self.long = .{ .load_frame = .{ .index = index } },
640635 else => unreachable,
641636 }
642 tracking_log.debug("spill {} from {} to {}", .{ inst, self.short, self.long });
637 tracking_log.debug("spill {f} from {f} to {f}", .{ inst, self.short, self.long });
643638 try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{});
644639 for (self.short.getRegs()) |reg| if (reg.isClass(.x87)) try cg.asmRegister(.{ .f_, .free }, reg);
645640 }
......@@ -672,7 +667,7 @@ const InstTracking = struct {
672667 else => {}, // TODO process stack allocation death
673668 }
674669 self.reuseFrame();
675 tracking_log.debug("{} => {} (spilled)", .{ inst, self.* });
670 tracking_log.debug("{f} => {f} (spilled)", .{ inst, self.* });
676671 }
677672
678673 fn verifyMaterialize(self: InstTracking, target: InstTracking) void {
......@@ -749,7 +744,7 @@ const InstTracking = struct {
749744 else => target.long,
750745 } else target.long;
751746 self.short = target.short;
752 tracking_log.debug("{} => {} (materialize)", .{ inst, self.* });
747 tracking_log.debug("{f} => {f} (materialize)", .{ inst, self.* });
753748 }
754749
755750 fn resurrect(self: *InstTracking, function: *CodeGen, inst: Air.Inst.Index, scope_generation: u32) !void {
......@@ -757,7 +752,7 @@ const InstTracking = struct {
757752 .dead => |die_generation| if (die_generation >= scope_generation) {
758753 self.reuseFrame();
759754 try function.getValue(self.short, inst);
760 tracking_log.debug("{} => {} (resurrect)", .{ inst, self.* });
755 tracking_log.debug("{f} => {f} (resurrect)", .{ inst, self.* });
761756 },
762757 else => {},
763758 }
......@@ -768,7 +763,7 @@ const InstTracking = struct {
768763 try function.freeValue(self.short, opts);
769764 if (self.long == .none) self.long = self.short;
770765 self.short = .{ .dead = function.scope_generation };
771 tracking_log.debug("{} => {} (death)", .{ inst, self.* });
766 tracking_log.debug("{f} => {f} (death)", .{ inst, self.* });
772767 }
773768
774769 fn reuse(
......@@ -778,13 +773,13 @@ const InstTracking = struct {
778773 old_inst: Air.Inst.Index,
779774 ) void {
780775 self.short = .{ .dead = function.scope_generation };
781 tracking_log.debug("{?} => {} (reuse {})", .{ new_inst, self.*, old_inst });
776 tracking_log.debug("{?f} => {f} (reuse {f})", .{ new_inst, self.*, old_inst });
782777 }
783778
784779 fn liveOut(self: *InstTracking, function: *CodeGen, inst: Air.Inst.Index) void {
785780 for (self.getRegs()) |reg| {
786781 if (function.register_manager.isRegFree(reg)) {
787 tracking_log.debug("{} => {} (live-out)", .{ inst, self.* });
782 tracking_log.debug("{f} => {f} (live-out)", .{ inst, self.* });
788783 continue;
789784 }
790785
......@@ -812,18 +807,13 @@ const InstTracking = struct {
812807 // Perform side-effects of freeValue manually.
813808 function.register_manager.freeReg(reg);
814809
815 tracking_log.debug("{} => {} (live-out {})", .{ inst, self.*, tracked_inst });
810 tracking_log.debug("{f} => {f} (live-out {f})", .{ inst, self.*, tracked_inst });
816811 }
817812 }
818813
819 pub fn format(
820 tracking: InstTracking,
821 comptime _: []const u8,
822 _: std.fmt.FormatOptions,
823 writer: anytype,
824 ) @TypeOf(writer).Error!void {
825 if (!std.meta.eql(tracking.long, tracking.short)) try writer.print("|{}| ", .{tracking.long});
826 try writer.print("{}", .{tracking.short});
814 pub fn format(tracking: InstTracking, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
815 if (!std.meta.eql(tracking.long, tracking.short)) try bw.print("|{f}| ", .{tracking.long});
816 try bw.print("{f}", .{tracking.short});
827817 }
828818};
829819
......@@ -939,7 +929,7 @@ pub fn generate(
939929 function.inst_tracking.putAssumeCapacityNoClobber(temp.toIndex(), .init(.none));
940930 }
941931
942 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
932 wip_mir_log.debug("{f}:", .{fmtNav(func.owner_nav, ip)});
943933
944934 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
945935 function.frame_allocs.set(
......@@ -1097,13 +1087,8 @@ const FormatNavData = struct {
10971087 ip: *const InternPool,
10981088 nav_index: InternPool.Nav.Index,
10991089};
1100fn formatNav(
1101 data: FormatNavData,
1102 comptime _: []const u8,
1103 _: std.fmt.FormatOptions,
1104 writer: anytype,
1105) @TypeOf(writer).Error!void {
1106 try writer.print("{}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
1090fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
1091 try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
11071092}
11081093fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
11091094 return .{ .data = .{
......@@ -1116,12 +1101,7 @@ const FormatAirData = struct {
11161101 self: *CodeGen,
11171102 inst: Air.Inst.Index,
11181103};
1119fn formatAir(
1120 data: FormatAirData,
1121 comptime _: []const u8,
1122 _: std.fmt.FormatOptions,
1123 writer: anytype,
1124) @TypeOf(writer).Error!void {
1104fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
11251105 data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness);
11261106}
11271107fn fmtAir(self: *CodeGen, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
......@@ -1132,12 +1112,7 @@ const FormatWipMirData = struct {
11321112 self: *CodeGen,
11331113 inst: Mir.Inst.Index,
11341114};
1135fn formatWipMir(
1136 data: FormatWipMirData,
1137 comptime _: []const u8,
1138 _: std.fmt.FormatOptions,
1139 writer: anytype,
1140) @TypeOf(writer).Error!void {
1115fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) !void {
11411116 var lower: Lower = .{
11421117 .target = data.self.target,
11431118 .allocator = data.self.gpa,
......@@ -1152,11 +1127,11 @@ fn formatWipMir(
11521127 lower.err_msg.?.deinit(data.self.gpa);
11531128 lower.err_msg = null;
11541129 }
1155 try writer.writeAll(lower.err_msg.?.msg);
1130 try bw.writeAll(lower.err_msg.?.msg);
11561131 return;
11571132 },
11581133 error.OutOfMemory, error.InvalidInstruction, error.CannotEncode => |e| {
1159 try writer.writeAll(switch (e) {
1134 try bw.writeAll(switch (e) {
11601135 error.OutOfMemory => "Out of memory",
11611136 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
11621137 error.CannotEncode => "CodeGen failed to encode the instruction.",
......@@ -1165,14 +1140,14 @@ fn formatWipMir(
11651140 },
11661141 else => |e| return e,
11671142 }).insts) |lowered_inst| {
1168 if (!first) try writer.writeAll("\ndebug(wip_mir): ");
1169 try writer.print(" | {}", .{lowered_inst});
1143 if (!first) try bw.writeAll("\ndebug(wip_mir): ");
1144 try bw.print(" | {f}", .{lowered_inst});
11701145 first = false;
11711146 }
11721147 if (first) {
11731148 const ip = &data.self.pt.zcu.intern_pool;
11741149 const mir_inst = lower.mir.instructions.get(data.inst);
1175 try writer.print(" | .{s}", .{@tagName(mir_inst.ops)});
1150 try bw.print(" | .{s}", .{@tagName(mir_inst.ops)});
11761151 switch (mir_inst.ops) {
11771152 else => unreachable,
11781153 .pseudo_dbg_prologue_end_none,
......@@ -1184,20 +1159,20 @@ fn formatWipMir(
11841159 .pseudo_dbg_var_none,
11851160 .pseudo_dead_none,
11861161 => {},
1187 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(
1162 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try bw.print(
11881163 " {[line]d}, {[column]d}",
11891164 mir_inst.data.line_column,
11901165 ),
1191 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{
1166 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try bw.print(" {f}", .{
11921167 ip.getNav(ip.indexToKey(mir_inst.data.ip_index).func.owner_nav).name.fmt(ip),
11931168 }),
1194 .pseudo_dbg_arg_i_s, .pseudo_dbg_var_i_s => try writer.print(" {d}", .{
1169 .pseudo_dbg_arg_i_s, .pseudo_dbg_var_i_s => try bw.print(" {d}", .{
11951170 @as(i32, @bitCast(mir_inst.data.i.i)),
11961171 }),
1197 .pseudo_dbg_arg_i_u, .pseudo_dbg_var_i_u => try writer.print(" {d}", .{
1172 .pseudo_dbg_arg_i_u, .pseudo_dbg_var_i_u => try bw.print(" {d}", .{
11981173 mir_inst.data.i.i,
11991174 }),
1200 .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => try writer.print(" {d}", .{
1175 .pseudo_dbg_arg_i_64, .pseudo_dbg_var_i_64 => try bw.print(" {d}", .{
12011176 mir_inst.data.i64,
12021177 }),
12031178 .pseudo_dbg_arg_ro, .pseudo_dbg_var_ro => {
......@@ -1205,22 +1180,22 @@ fn formatWipMir(
12051180 .base = .{ .reg = mir_inst.data.ro.reg },
12061181 .disp = mir_inst.data.ro.off,
12071182 }) };
1208 try writer.print(" {}", .{mem_op.fmt(.m)});
1183 try bw.print(" {f}", .{mem_op.fmt(.m)});
12091184 },
12101185 .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => {
12111186 const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{
12121187 .base = .{ .frame = mir_inst.data.fa.index },
12131188 .disp = mir_inst.data.fa.off,
12141189 }) };
1215 try writer.print(" {}", .{mem_op.fmt(.m)});
1190 try bw.print(" {f}", .{mem_op.fmt(.m)});
12161191 },
12171192 .pseudo_dbg_arg_m, .pseudo_dbg_var_m => {
12181193 const mem_op: encoder.Instruction.Operand = .{
12191194 .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.x.payload).data.decode(),
12201195 };
1221 try writer.print(" {}", .{mem_op.fmt(.m)});
1196 try bw.print(" {f}", .{mem_op.fmt(.m)});
12221197 },
1223 .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try writer.print(" {}", .{
1198 .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try bw.print(" {}", .{
12241199 Value.fromInterned(mir_inst.data.ip_index).fmtValue(data.self.pt),
12251200 }),
12261201 }
......@@ -1233,14 +1208,9 @@ fn fmtWipMir(self: *CodeGen, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMi
12331208const FormatTrackingData = struct {
12341209 self: *CodeGen,
12351210};
1236fn formatTracking(
1237 data: FormatTrackingData,
1238 comptime _: []const u8,
1239 _: std.fmt.FormatOptions,
1240 writer: anytype,
1241) @TypeOf(writer).Error!void {
1211fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
12421212 var it = data.self.inst_tracking.iterator();
1243 while (it.next()) |entry| try writer.print("\n{} = {}", .{ entry.key_ptr.*, entry.value_ptr.* });
1213 while (it.next()) |entry| try bw.print("\n{f} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* });
12441214}
12451215fn fmtTracking(self: *CodeGen) std.fmt.Formatter(formatTracking) {
12461216 return .{ .data = .{ .self = self } };
......@@ -1251,7 +1221,7 @@ fn addInst(self: *CodeGen, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
12511221 try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
12521222 const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
12531223 self.mir_instructions.appendAssumeCapacity(inst);
1254 if (inst.ops != .pseudo_dead_none) wip_mir_log.debug("{}", .{self.fmtWipMir(result_index)});
1224 if (inst.ops != .pseudo_dead_none) wip_mir_log.debug("{f}", .{self.fmtWipMir(result_index)});
12551225 return result_index;
12561226}
12571227
......@@ -2056,7 +2026,7 @@ fn gen(
20562026 .{},
20572027 );
20582028 self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
2059 tracking_log.debug("spill {} to {}", .{ self.ret_mcv.long, frame_index });
2029 tracking_log.debug("spill {f} to {f}", .{ self.ret_mcv.long, frame_index });
20602030 },
20612031 else => unreachable,
20622032 }
......@@ -2334,8 +2304,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
23342304
23352305 for (body) |inst| {
23362306 if (cg.liveness.isUnused(inst) and !cg.air.mustLower(inst, ip)) continue;
2337 wip_mir_log.debug("{}", .{cg.fmtAir(inst)});
2338 verbose_tracking_log.debug("{}", .{cg.fmtTracking()});
2307 wip_mir_log.debug("{f}", .{cg.fmtAir(inst)});
2308 verbose_tracking_log.debug("{f}", .{cg.fmtTracking()});
23392309
23402310 cg.reused_operands = .initEmpty();
23412311 try cg.inst_tracking.ensureUnusedCapacity(cg.gpa, 1);
......@@ -4339,7 +4309,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43394309 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
43404310 } },
43414311 } }) catch |err| switch (err) {
4342 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
4312 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
43434313 @tagName(air_tag),
43444314 cg.typeOf(bin_op.lhs).fmt(pt),
43454315 ops[0].tracking(cg),
......@@ -4351,7 +4321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43514321 else => unreachable,
43524322 .add, .add_optimized => {},
43534323 .add_wrap => res[0].wrapInt(cg) catch |err| switch (err) {
4354 error.SelectFailed => return cg.fail("failed to select {s} wrap {} {}", .{
4324 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
43554325 @tagName(air_tag),
43564326 cg.typeOf(bin_op.lhs).fmt(pt),
43574327 res[0].tracking(cg),
......@@ -14947,7 +14917,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1494714917 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
1494814918 } },
1494914919 } }) catch |err| switch (err) {
14950 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
14920 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
1495114921 @tagName(air_tag),
1495214922 cg.typeOf(bin_op.lhs).fmt(pt),
1495314923 ops[0].tracking(cg),
......@@ -14959,7 +14929,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1495914929 else => unreachable,
1496014930 .sub, .sub_optimized => {},
1496114931 .sub_wrap => res[0].wrapInt(cg) catch |err| switch (err) {
14962 error.SelectFailed => return cg.fail("failed to select {s} wrap {} {}", .{
14932 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
1496314933 @tagName(air_tag),
1496414934 cg.typeOf(bin_op.lhs).fmt(pt),
1496514935 res[0].tracking(cg),
......@@ -24587,7 +24557,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2458724557 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
2458824558 } },
2458924559 } }) catch |err| switch (err) {
24590 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
24560 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
2459124561 @tagName(air_tag),
2459224562 ty.fmt(pt),
2459324563 ops[0].tracking(cg),
......@@ -27287,7 +27257,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2728727257 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
2728827258 } },
2728927259 } }) catch |err| switch (err) {
27290 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
27260 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
2729127261 @tagName(air_tag),
2729227262 ty.fmt(pt),
2729327263 ops[0].tracking(cg),
......@@ -27296,7 +27266,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2729627266 else => |e| return e,
2729727267 };
2729827268 res[0].wrapInt(cg) catch |err| switch (err) {
27299 error.SelectFailed => return cg.fail("failed to select {s} wrap {} {}", .{
27269 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
2730027270 @tagName(air_tag),
2730127271 cg.typeOf(bin_op.lhs).fmt(pt),
2730227272 res[0].tracking(cg),
......@@ -33606,7 +33576,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3360633576 assert(air_tag == .div_exact);
3360733577 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
3360833578 }) catch |err| switch (err) {
33609 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
33579 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
3361033580 @tagName(air_tag),
3361133581 ty.fmt(pt),
3361233582 ops[0].tracking(cg),
......@@ -34837,7 +34807,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3483734807 } }) else err: {
3483834808 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
3483934809 }) catch |err| switch (err) {
34840 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
34810 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
3484134811 @tagName(air_tag),
3484234812 ty.fmt(pt),
3484334813 ops[0].tracking(cg),
......@@ -36148,7 +36118,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3614836118 } },
3614936119 } },
3615036120 }) catch |err| switch (err) {
36151 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
36121 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
3615236122 @tagName(air_tag),
3615336123 cg.typeOf(bin_op.lhs).fmt(pt),
3615436124 ops[0].tracking(cg),
......@@ -37614,7 +37584,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3761437584 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
3761537585 } },
3761637586 } })) catch |err| switch (err) {
37617 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
37587 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
3761837588 @tagName(air_tag),
3761937589 ty.fmt(pt),
3762037590 ops[0].tracking(cg),
......@@ -39248,7 +39218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3924839218 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
3924939219 } },
3925039220 } }) catch |err| switch (err) {
39251 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
39221 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
3925239222 @tagName(air_tag),
3925339223 cg.typeOf(bin_op.lhs).fmt(pt),
3925439224 ops[0].tracking(cg),
......@@ -42077,7 +42047,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4207742047 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4207842048 } },
4207942049 } }) catch |err| switch (err) {
42080 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
42050 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
4208142051 @tagName(air_tag),
4208242052 cg.typeOf(bin_op.lhs).fmt(pt),
4208342053 ops[0].tracking(cg),
......@@ -42191,7 +42161,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4219142161 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },
4219242162 } },
4219342163 } }) catch |err| switch (err) {
42194 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
42164 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
4219542165 @tagName(air_tag),
4219642166 cg.typeOf(bin_op.lhs).fmt(pt),
4219742167 ops[0].tracking(cg),
......@@ -42320,7 +42290,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4232042290 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },
4232142291 } },
4232242292 } }) catch |err| switch (err) {
42323 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
42293 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
4232442294 @tagName(air_tag),
4232542295 cg.typeOf(bin_op.lhs).fmt(pt),
4232642296 ops[0].tracking(cg),
......@@ -46485,7 +46455,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4648546455 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4648646456 } },
4648746457 } }) catch |err| switch (err) {
46488 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
46458 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
4648946459 @tagName(air_tag),
4649046460 cg.typeOf(bin_op.lhs).fmt(pt),
4649146461 ops[0].tracking(cg),
......@@ -50644,7 +50614,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5064450614 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
5064550615 } },
5064650616 } }) catch |err| switch (err) {
50647 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
50617 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
5064850618 @tagName(air_tag),
5064950619 cg.typeOf(bin_op.lhs).fmt(pt),
5065050620 ops[0].tracking(cg),
......@@ -51493,7 +51463,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5149351463 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
5149451464 } },
5149551465 } }) catch |err| switch (err) {
51496 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
51466 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
5149751467 @tagName(air_tag),
5149851468 ty_pl.ty.toType().fmt(pt),
5149951469 ops[0].tracking(cg),
......@@ -52398,7 +52368,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5239852368 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
5239952369 } },
5240052370 } }) catch |err| switch (err) {
52401 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
52371 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
5240252372 @tagName(air_tag),
5240352373 ty_pl.ty.toType().fmt(pt),
5240452374 ops[0].tracking(cg),
......@@ -55995,7 +55965,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5599555965 .{ ._, ._, .@"or", .tmp2q, .tmp1q, ._, ._ },
5599655966 } },
5599755967 } }) catch |err| switch (err) {
55998 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
55968 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
5599955969 @tagName(air_tag),
5600055970 ty_pl.ty.toType().fmt(pt),
5600155971 ops[0].tracking(cg),
......@@ -59735,7 +59705,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5973559705 } },
5973659706 } },
5973759707 }) catch |err| switch (err) {
59738 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
59708 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
5973959709 @tagName(air_tag),
5974059710 cg.typeOf(bin_op.lhs).fmt(pt),
5974159711 ops[0].tracking(cg),
......@@ -60298,7 +60268,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6029860268 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
6029960269 } },
6030060270 } }) catch |err| switch (err) {
60301 error.SelectFailed => return cg.fail("failed to select {s} {} {} {} {}", .{
60271 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
6030260272 @tagName(air_tag),
6030360273 cg.typeOf(bin_op.lhs).fmt(pt),
6030460274 cg.typeOf(bin_op.rhs).fmt(pt),
......@@ -60660,7 +60630,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6066060630 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
6066160631 } },
6066260632 } }) catch |err| switch (err) {
60663 error.SelectFailed => return cg.fail("failed to select {s} {} {} {} {}", .{
60633 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
6066460634 @tagName(air_tag),
6066560635 cg.typeOf(bin_op.lhs).fmt(pt),
6066660636 cg.typeOf(bin_op.rhs).fmt(pt),
......@@ -60672,7 +60642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6067260642 switch (air_tag) {
6067360643 else => unreachable,
6067460644 .shl => res[0].wrapInt(cg) catch |err| switch (err) {
60675 error.SelectFailed => return cg.fail("failed to select {s} wrap {} {}", .{
60645 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
6067660646 @tagName(air_tag),
6067760647 cg.typeOf(bin_op.lhs).fmt(pt),
6067860648 res[0].tracking(cg),
......@@ -65329,7 +65299,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6532965299 .{ ._, ._b, .j, .@"0b", ._, ._, ._ },
6533065300 } },
6533165301 } }) catch |err| switch (err) {
65332 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
65302 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
6533365303 @tagName(air_tag),
6533465304 ty_op.ty.toType().fmt(pt),
6533565305 ops[0].tracking(cg),
......@@ -68483,7 +68453,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6848368453 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
6848468454 } },
6848568455 } }) catch |err| switch (err) {
68486 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
68456 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
6848768457 @tagName(air_tag),
6848868458 cg.typeOf(ty_op.operand).fmt(pt),
6848968459 ops[0].tracking(cg),
......@@ -68880,7 +68850,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6888068850 .{ .@"0:", ._, .lea, .dst0d, .leasia(.dst0, .@"8", .tmp0, .add_8_src0_size), ._, ._ },
6888168851 } },
6888268852 } }) catch |err| switch (err) {
68883 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
68853 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
6888468854 @tagName(air_tag),
6888568855 cg.typeOf(ty_op.operand).fmt(pt),
6888668856 ops[0].tracking(cg),
......@@ -69768,7 +69738,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6976869738 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
6976969739 } },
6977069740 } }) catch |err| switch (err) {
69771 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
69741 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
6977269742 @tagName(air_tag),
6977369743 cg.typeOf(ty_op.operand).fmt(pt),
6977469744 ops[0].tracking(cg),
......@@ -70417,7 +70387,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7041770387 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7041870388 } },
7041970389 } }) catch |err| switch (err) {
70420 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
70390 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7042170391 @tagName(air_tag),
7042270392 ty_op.ty.toType().fmt(pt),
7042370393 ops[0].tracking(cg),
......@@ -73519,7 +73489,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7351973489 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7352073490 } },
7352173491 } }) catch |err| switch (err) {
73522 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
73492 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7352373493 @tagName(air_tag),
7352473494 ty_op.ty.toType().fmt(pt),
7352573495 ops[0].tracking(cg),
......@@ -74457,7 +74427,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7445774427 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
7445874428 } },
7445974429 } }) catch |err| switch (err) {
74460 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
74430 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7446174431 @tagName(air_tag),
7446274432 cg.typeOf(un_op).fmt(pt),
7446374433 ops[0].tracking(cg),
......@@ -75183,7 +75153,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7518375153 } },
7518475154 } },
7518575155 }) catch |err| switch (err) {
75186 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
75156 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7518775157 @tagName(air_tag),
7518875158 cg.typeOf(un_op).fmt(pt),
7518975159 ops[0].tracking(cg),
......@@ -76734,7 +76704,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7673476704 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
7673576705 } },
7673676706 } }) catch |err| switch (err) {
76737 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
76707 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7673876708 @tagName(air_tag),
7673976709 cg.typeOf(ty_op.operand).fmt(pt),
7674076710 ops[0].tracking(cg),
......@@ -77926,7 +77896,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7792677896 } },
7792777897 } },
7792877898 }) catch |err| switch (err) {
77929 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
77899 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7793077900 @tagName(air_tag),
7793177901 cg.typeOf(un_op).fmt(pt),
7793277902 ops[0].tracking(cg),
......@@ -78466,7 +78436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7846678436 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
7846778437 } },
7846878438 } }) catch |err| switch (err) {
78469 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
78439 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
7847078440 @tagName(air_tag),
7847178441 cg.typeOf(un_op).fmt(pt),
7847278442 ops[0].tracking(cg),
......@@ -78913,7 +78883,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7891378883 } else err: {
7891478884 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
7891578885 }) catch |err| switch (err) {
78916 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
78886 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
7891778887 @tagName(air_tag),
7891878888 cg.typeOf(bin_op.lhs).fmt(pt),
7891978889 ops[0].tracking(cg),
......@@ -79470,7 +79440,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7947079440 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
7947179441 },
7947279442 }) catch |err| switch (err) {
79473 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
79443 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
7947479444 @tagName(air_tag),
7947579445 ty.fmt(pt),
7947679446 ops[0].tracking(cg),
......@@ -88546,7 +88516,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8854688516 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
8854788517 } },
8854888518 } }) catch |err| switch (err) {
88549 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
88519 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
8855088520 @tagName(air_tag),
8855188521 ty_op.ty.toType().fmt(pt),
8855288522 cg.typeOf(ty_op.operand).fmt(pt),
......@@ -90221,7 +90191,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9022190191 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
9022290192 } },
9022390193 } }) catch |err| switch (err) {
90224 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
90194 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
9022590195 @tagName(air_tag),
9022690196 ty_op.ty.toType().fmt(pt),
9022790197 cg.typeOf(ty_op.operand).fmt(pt),
......@@ -94899,7 +94869,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9489994869 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
9490094870 } },
9490194871 } }) catch |err| switch (err) {
94902 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
94872 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
9490394873 @tagName(air_tag),
9490494874 dst_ty.fmt(pt),
9490594875 src_ty.fmt(pt),
......@@ -100565,7 +100535,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
100565100535 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
100566100536 } },
100567100537 } }) catch |err| switch (err) {
100568 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
100538 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
100569100539 @tagName(air_tag),
100570100540 ty_op.ty.toType().fmt(pt),
100571100541 cg.typeOf(ty_op.operand).fmt(pt),
......@@ -111427,7 +111397,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
111427111397 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
111428111398 } },
111429111399 } }) catch |err| switch (err) {
111430 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
111400 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
111431111401 @tagName(air_tag),
111432111402 ty_op.ty.toType().fmt(pt),
111433111403 cg.typeOf(ty_op.operand).fmt(pt),
......@@ -123446,7 +123416,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
123446123416 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
123447123417 } },
123448123418 } }) catch |err| switch (err) {
123449 error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
123419 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
123450123420 @tagName(air_tag),
123451123421 ty_op.ty.toType().fmt(pt),
123452123422 cg.typeOf(ty_op.operand).fmt(pt),
......@@ -166464,7 +166434,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
166464166434 .{ ._, ._, .@"test", .src0p, .src0p, ._, ._ },
166465166435 } },
166466166436 } }) catch |err| switch (err) {
166467 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
166437 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
166468166438 @tagName(air_tag),
166469166439 cg.typeOf(un_op).fmt(pt),
166470166440 ops[0].tracking(cg),
......@@ -166552,7 +166522,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
166552166522 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
166553166523 } },
166554166524 } }) catch |err| switch (err) {
166555 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
166525 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
166556166526 @tagName(air_tag),
166557166527 cg.typeOf(un_op).fmt(pt),
166558166528 ops[0].tracking(cg),
......@@ -166654,7 +166624,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
166654166624 .{ ._, ._, .lea, .dst1d, .leai(.dst1, .tmp1), ._, ._ },
166655166625 } },
166656166626 } }) catch |err| switch (err) {
166657 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
166627 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
166658166628 @tagName(air_tag),
166659166629 cg.typeOf(un_op).fmt(pt),
166660166630 ops[0].tracking(cg),
......@@ -166752,7 +166722,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
166752166722 .{ ._, ._, .@"test", .src0d, .src0d, ._, ._ },
166753166723 } },
166754166724 } }) catch |err| switch (err) {
166755 error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
166725 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
166756166726 @tagName(air_tag),
166757166727 ty_op.ty.toType().fmt(pt),
166758166728 ops[0].tracking(cg),
......@@ -166804,7 +166774,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
166804166774 }
166805166775 }
166806166776 },
166807 .@"packed" => return cg.fail("failed to select {s} {}", .{
166777 .@"packed" => return cg.fail("failed to select {s} {f}", .{
166808166778 @tagName(air_tag),
166809166779 agg_ty.fmt(pt),
166810166780 }),
......@@ -166825,7 +166795,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
166825166795 elem_disp += @intCast(field_type.abiSize(zcu));
166826166796 }
166827166797 },
166828 else => return cg.fail("failed to select {s} {}", .{
166798 else => return cg.fail("failed to select {s} {f}", .{
166829166799 @tagName(air_tag),
166830166800 agg_ty.fmt(pt),
166831166801 }),
......@@ -168123,7 +168093,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168123168093 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
168124168094 } },
168125168095 } }) catch |err| switch (err) {
168126 error.SelectFailed => return cg.fail("failed to select {s} {} {} {} {}", .{
168096 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
168127168097 @tagName(air_tag),
168128168098 cg.typeOf(bin_op.lhs).fmt(pt),
168129168099 ops[0].tracking(cg),
......@@ -168223,7 +168193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168223168193 .{ ._, ._, .cmp, .src0d, .lea(.tmp1d), ._, ._ },
168224168194 } },
168225168195 } }) catch |err| switch (err) {
168226 error.SelectFailed => return cg.fail("failed to select {s} {}", .{
168196 error.SelectFailed => return cg.fail("failed to select {s} {f}", .{
168227168197 @tagName(air_tag),
168228168198 ops[0].tracking(cg),
168229168199 }),
......@@ -168242,12 +168212,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168242168212 .ref => {
168243168213 const result = try cg.allocRegOrMem(err_ret_trace_index, true);
168244168214 try cg.genCopy(.usize, result, ops[0].tracking(cg).short, .{});
168245 tracking_log.debug("{} => {} (birth)", .{ err_ret_trace_index, result });
168215 tracking_log.debug("{f} => {f} (birth)", .{ err_ret_trace_index, result });
168246168216 cg.inst_tracking.putAssumeCapacityNoClobber(err_ret_trace_index, .init(result));
168247168217 },
168248168218 .temp => |temp_index| {
168249168219 const temp_tracking = temp_index.tracking(cg);
168250 tracking_log.debug("{} => {} (birth)", .{ err_ret_trace_index, temp_tracking.short });
168220 tracking_log.debug("{f} => {f} (birth)", .{ err_ret_trace_index, temp_tracking.short });
168251168221 cg.inst_tracking.putAssumeCapacityNoClobber(err_ret_trace_index, temp_tracking.*);
168252168222 assert(cg.reuseTemp(err_ret_trace_index, temp_index.toIndex(), temp_tracking));
168253168223 },
......@@ -168917,7 +168887,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
168917168887 try cg.resetTemps(@enumFromInt(0));
168918168888 cg.checkInvariantsAfterAirInst();
168919168889 }
168920 verbose_tracking_log.debug("{}", .{cg.fmtTracking()});
168890 verbose_tracking_log.debug("{f}", .{cg.fmtTracking()});
168921168891}
168922168892
168923168893fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
......@@ -168927,7 +168897,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
168927168897 switch (ip.indexToKey(lazy_sym.ty)) {
168928168898 .enum_type => {
168929168899 const enum_ty: Type = .fromInterned(lazy_sym.ty);
168930 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
168900 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});
168931168901
168932168902 const param_regs = abi.getCAbiIntParamRegs(.auto);
168933168903 const param_locks = cg.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*);
......@@ -168976,7 +168946,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
168976168946 },
168977168947 .error_set_type => |error_set_type| {
168978168948 const err_ty: Type = .fromInterned(lazy_sym.ty);
168979 wip_mir_log.debug("{}.@errorCast:", .{err_ty.fmt(pt)});
168949 wip_mir_log.debug("{f}.@errorCast:", .{err_ty.fmt(pt)});
168980168950
168981168951 const param_regs = abi.getCAbiIntParamRegs(.auto);
168982168952 const param_locks = cg.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*);
......@@ -169016,7 +168986,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
169016168986 try cg.asmOpOnly(.{ ._, .ret });
169017168987 },
169018168988 else => return cg.fail(
169019 "TODO implement {s} for {}",
168989 "TODO implement {s} for {f}",
169020168990 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
169021168991 ),
169022168992 }
......@@ -169076,7 +169046,7 @@ fn finishAirResult(self: *CodeGen, inst: Air.Inst.Index, result: MCValue) void {
169076169046 .none, .dead, .unreach => {},
169077169047 else => unreachable, // Why didn't the result die?
169078169048 } else {
169079 tracking_log.debug("{} => {} (birth)", .{ inst, result });
169049 tracking_log.debug("{f} => {f} (birth)", .{ inst, result });
169080169050 self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result));
169081169051 // In some cases, an operand may be reused as the result.
169082169052 // If that operand died and was a register, it was freed by
......@@ -169226,7 +169196,7 @@ fn allocMemPtr(self: *CodeGen, inst: Air.Inst.Index) !FrameIndex {
169226169196 const val_ty = ptr_ty.childType(zcu);
169227169197 return self.allocFrameIndex(.init(.{
169228169198 .size = std.math.cast(u32, val_ty.abiSize(zcu)) orelse {
169229 return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(pt)});
169199 return self.fail("type '{f}' too big to fit into stack frame", .{val_ty.fmt(pt)});
169230169200 },
169231169201 .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"),
169232169202 }));
......@@ -169244,7 +169214,7 @@ fn allocRegOrMemAdvanced(self: *CodeGen, ty: Type, inst: ?Air.Inst.Index, reg_ok
169244169214 const pt = self.pt;
169245169215 const zcu = pt.zcu;
169246169216 const abi_size = std.math.cast(u32, ty.abiSize(zcu)) orelse {
169247 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(pt)});
169217 return self.fail("type '{f}' too big to fit into stack frame", .{ty.fmt(pt)});
169248169218 };
169249169219
169250169220 if (reg_ok) need_mem: {
......@@ -169749,7 +169719,7 @@ fn airFpext(self: *CodeGen, inst: Air.Inst.Index) !void {
169749169719 );
169750169720 }
169751169721 break :result dst_mcv;
169752 } orelse return self.fail("TODO implement airFpext from {} to {}", .{
169722 } orelse return self.fail("TODO implement airFpext from {f} to {f}", .{
169753169723 src_ty.fmt(pt), dst_ty.fmt(pt),
169754169724 });
169755169725 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -170004,7 +169974,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void {
170004169974 );
170005169975
170006169976 break :result dst_mcv;
170007 }) orelse return self.fail("TODO implement airIntCast from {} to {}", .{
169977 }) orelse return self.fail("TODO implement airIntCast from {f} to {f}", .{
170008169978 src_ty.fmt(pt), dst_ty.fmt(pt),
170009169979 });
170010169980 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -170076,7 +170046,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
170076170046 else => null,
170077170047 },
170078170048 else => null,
170079 }) orelse return self.fail("TODO implement airTrunc for {}", .{dst_ty.fmt(pt)});
170049 }) orelse return self.fail("TODO implement airTrunc for {f}", .{dst_ty.fmt(pt)});
170080170050
170081170051 const dst_info = dst_elem_ty.intInfo(zcu);
170082170052 const src_info = src_elem_ty.intInfo(zcu);
......@@ -170497,7 +170467,7 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void {
170497170467 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
170498170468 const ty = self.typeOf(bin_op.lhs);
170499170469 if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail(
170500 "TODO implement airAddSat for {}",
170470 "TODO implement airAddSat for {f}",
170501170471 .{ty.fmt(pt)},
170502170472 );
170503170473
......@@ -170575,7 +170545,7 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void {
170575170545 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
170576170546 const ty = self.typeOf(bin_op.lhs);
170577170547 if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail(
170578 "TODO implement airSubSat for {}",
170548 "TODO implement airSubSat for {f}",
170579170549 .{ty.fmt(pt)},
170580170550 );
170581170551
......@@ -170726,7 +170696,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void {
170726170696 }
170727170697
170728170698 if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail(
170729 "TODO implement airMulSat for {}",
170699 "TODO implement airMulSat for {f}",
170730170700 .{ty.fmt(pt)},
170731170701 );
170732170702
......@@ -171020,7 +170990,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
171020170990 const tuple_ty = self.typeOfIndex(inst);
171021170991 const dst_ty = self.typeOf(bin_op.lhs);
171022170992 const result: MCValue = switch (dst_ty.zigTypeTag(zcu)) {
171023 .vector => return self.fail("TODO implement airMulWithOverflow for {}", .{dst_ty.fmt(pt)}),
170993 .vector => return self.fail("TODO implement airMulWithOverflow for {f}", .{dst_ty.fmt(pt)}),
171024170994 .int => result: {
171025170995 const dst_info = dst_ty.intInfo(zcu);
171026170996 if (dst_info.bits > 128 and dst_info.signedness == .unsigned) {
......@@ -171373,7 +171343,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
171373171343 else => {
171374171344 // For now, this is the only supported multiply that doesn't fit in a register.
171375171345 if (dst_info.bits > 128 or src_bits != 64)
171376 return self.fail("TODO implement airWithOverflow from {} to {}", .{
171346 return self.fail("TODO implement airWithOverflow from {f} to {f}", .{
171377171347 src_ty.fmt(pt), dst_ty.fmt(pt),
171378171348 });
171379171349
......@@ -171774,7 +171744,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void {
171774171744 },
171775171745 else => {},
171776171746 }
171777 return self.fail("TODO implement airShlShrBinOp for {}", .{lhs_ty.fmt(pt)});
171747 return self.fail("TODO implement airShlShrBinOp for {f}", .{lhs_ty.fmt(pt)});
171778171748 };
171779171749 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
171780171750}
......@@ -172034,7 +172004,7 @@ fn airUnwrapErrUnionErr(self: *CodeGen, inst: Air.Inst.Index) !void {
172034172004 .index = frame_addr.index,
172035172005 .off = frame_addr.off + @as(i32, @intCast(err_off)),
172036172006 } },
172037 else => return self.fail("TODO implement unwrap_err_err for {}", .{operand}),
172007 else => return self.fail("TODO implement unwrap_err_err for {f}", .{operand}),
172038172008 }
172039172009 };
172040172010 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
......@@ -172196,7 +172166,7 @@ fn genUnwrapErrUnionPayloadMir(
172196172166 else
172197172167 .{ .register = try self.copyToTmpRegister(payload_ty, result_mcv) };
172198172168 },
172199 else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {}", .{err_union}),
172169 else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {f}", .{err_union}),
172200172170 }
172201172171 };
172202172172
......@@ -172362,7 +172332,7 @@ fn airSliceLen(self: *CodeGen, inst: Air.Inst.Index) !void {
172362172332 .index = frame_addr.index,
172363172333 .off = frame_addr.off + 8,
172364172334 } },
172365 else => return self.fail("TODO implement slice_len for {}", .{src_mcv}),
172335 else => return self.fail("TODO implement slice_len for {f}", .{src_mcv}),
172366172336 };
172367172337 if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) {
172368172338 switch (src_mcv) {
......@@ -172645,7 +172615,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
172645172615 }.to64(),
172646172616 ),
172647172617 },
172648 else => return self.fail("TODO airArrayElemVal for {s} of {}", .{
172618 else => return self.fail("TODO airArrayElemVal for {s} of {f}", .{
172649172619 @tagName(array_mat_mcv), array_ty.fmt(pt),
172650172620 }),
172651172621 }
......@@ -172688,7 +172658,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void {
172688172658 .load_extern_func,
172689172659 .lea_extern_func,
172690172660 => try self.genSetReg(addr_reg, .usize, array_mcv.address(), .{}),
172691 else => return self.fail("TODO airArrayElemVal_val for {s} of {}", .{
172661 else => return self.fail("TODO airArrayElemVal_val for {s} of {f}", .{
172692172662 @tagName(array_mcv), array_ty.fmt(pt),
172693172663 }),
172694172664 }
......@@ -172881,7 +172851,7 @@ fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void {
172881172851 }
172882172852
172883172853 return self.fail(
172884 "TODO implement get_union_tag for ABI larger than 8 bytes and operand {}",
172854 "TODO implement get_union_tag for ABI larger than 8 bytes and operand {f}",
172885172855 .{operand},
172886172856 );
172887172857 },
......@@ -172893,7 +172863,7 @@ fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void {
172893172863 .register = registerAlias(result.register, @intCast(layout.tag_size)),
172894172864 };
172895172865 },
172896 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),
172866 else => return self.fail("TODO implement get_union_tag for {f}", .{operand}),
172897172867 }
172898172868 };
172899172869
......@@ -172909,7 +172879,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void {
172909172879
172910172880 const dst_ty = self.typeOfIndex(inst);
172911172881 const src_ty = self.typeOf(ty_op.operand);
172912 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail("TODO implement airClz for {}", .{
172882 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail("TODO implement airClz for {f}", .{
172913172883 src_ty.fmt(pt),
172914172884 });
172915172885
......@@ -173105,7 +173075,7 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void {
173105173075
173106173076 const dst_ty = self.typeOfIndex(inst);
173107173077 const src_ty = self.typeOf(ty_op.operand);
173108 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail("TODO implement airCtz for {}", .{
173078 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail("TODO implement airCtz for {f}", .{
173109173079 src_ty.fmt(pt),
173110173080 });
173111173081
......@@ -173277,7 +173247,7 @@ fn airPopCount(self: *CodeGen, inst: Air.Inst.Index) !void {
173277173247 const src_ty = self.typeOf(ty_op.operand);
173278173248 const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu));
173279173249 if (src_ty.zigTypeTag(zcu) == .vector or src_abi_size > 16)
173280 return self.fail("TODO implement airPopCount for {}", .{src_ty.fmt(pt)});
173250 return self.fail("TODO implement airPopCount for {f}", .{src_ty.fmt(pt)});
173281173251 const src_mcv = try self.resolveInst(ty_op.operand);
173282173252
173283173253 const mat_src_mcv = switch (src_mcv) {
......@@ -173430,7 +173400,7 @@ fn genByteSwap(
173430173400 const has_movbe = self.hasFeature(.movbe);
173431173401
173432173402 if (src_ty.zigTypeTag(zcu) == .vector) return self.fail(
173433 "TODO implement genByteSwap for {}",
173403 "TODO implement genByteSwap for {f}",
173434173404 .{src_ty.fmt(pt)},
173435173405 );
173436173406
......@@ -173739,7 +173709,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A
173739173709 const result = result: {
173740173710 const scalar_bits = ty.scalarType(zcu).floatBits(self.target);
173741173711 if (scalar_bits == 80) {
173742 if (ty.zigTypeTag(zcu) != .float) return self.fail("TODO implement floatSign for {}", .{
173712 if (ty.zigTypeTag(zcu) != .float) return self.fail("TODO implement floatSign for {f}", .{
173743173713 ty.fmt(pt),
173744173714 });
173745173715
......@@ -173763,7 +173733,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A
173763173733 const abi_size: u32 = switch (ty.abiSize(zcu)) {
173764173734 1...16 => 16,
173765173735 17...32 => 32,
173766 else => return self.fail("TODO implement floatSign for {}", .{
173736 else => return self.fail("TODO implement floatSign for {f}", .{
173767173737 ty.fmt(pt),
173768173738 }),
173769173739 };
......@@ -173822,7 +173792,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A
173822173792 .abs => .{ .v_pd, .@"and" },
173823173793 else => unreachable,
173824173794 },
173825 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(pt)}),
173795 80 => return self.fail("TODO implement floatSign for {f}", .{ty.fmt(pt)}),
173826173796 else => unreachable,
173827173797 },
173828173798 registerAlias(dst_reg, abi_size),
......@@ -173848,7 +173818,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A
173848173818 .abs => .{ ._pd, .@"and" },
173849173819 else => unreachable,
173850173820 },
173851 80 => return self.fail("TODO implement floatSign for {}", .{ty.fmt(pt)}),
173821 80 => return self.fail("TODO implement floatSign for {f}", .{ty.fmt(pt)}),
173852173822 else => unreachable,
173853173823 },
173854173824 registerAlias(dst_reg, abi_size),
......@@ -173928,7 +173898,7 @@ fn genRoundLibcall(self: *CodeGen, ty: Type, src_mcv: MCValue, mode: bits.RoundM
173928173898 if (self.getRoundTag(ty)) |_| return .none;
173929173899
173930173900 if (ty.zigTypeTag(zcu) != .float)
173931 return self.fail("TODO implement genRound for {}", .{ty.fmt(pt)});
173901 return self.fail("TODO implement genRound for {f}", .{ty.fmt(pt)});
173932173902
173933173903 var sym_buf: ["__trunc?".len]u8 = undefined;
173934173904 return try self.genCall(.{ .extern_func = .{
......@@ -174164,7 +174134,7 @@ fn airAbs(self: *CodeGen, inst: Air.Inst.Index) !void {
174164174134 },
174165174135 .float => return self.floatSign(inst, .abs, ty_op.operand, ty),
174166174136 },
174167 }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(pt)});
174137 }) orelse return self.fail("TODO implement airAbs for {f}", .{ty.fmt(pt)});
174168174138
174169174139 const abi_size: u32 = @intCast(ty.abiSize(zcu));
174170174140 const src_mcv = try self.resolveInst(ty_op.operand);
......@@ -174323,7 +174293,7 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void {
174323174293 else => unreachable,
174324174294 },
174325174295 else => unreachable,
174326 }) orelse return self.fail("TODO implement airSqrt for {}", .{ty.fmt(pt)});
174296 }) orelse return self.fail("TODO implement airSqrt for {f}", .{ty.fmt(pt)});
174327174297 switch (mir_tag[0]) {
174328174298 .v_ss, .v_sd => if (src_mcv.isBase()) try self.asmRegisterRegisterMemory(
174329174299 mir_tag,
......@@ -174481,7 +174451,7 @@ fn packedLoad(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue)
174481174451 return;
174482174452 }
174483174453
174484 if (val_abi_size > 8) return self.fail("TODO implement packed load of {}", .{val_ty.fmt(pt)});
174454 if (val_abi_size > 8) return self.fail("TODO implement packed load of {f}", .{val_ty.fmt(pt)});
174485174455
174486174456 const limb_abi_size: u31 = @min(val_abi_size, 8);
174487174457 const limb_abi_bits = limb_abi_size * 8;
......@@ -174753,7 +174723,7 @@ fn packedStore(self: *CodeGen, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue)
174753174723 limb_mem,
174754174724 registerAlias(tmp_reg, limb_abi_size),
174755174725 );
174756 } else return self.fail("TODO: implement packed store of {}", .{src_ty.fmt(pt)});
174726 } else return self.fail("TODO: implement packed store of {f}", .{src_ty.fmt(pt)});
174757174727 }
174758174728}
174759174729
......@@ -174856,7 +174826,7 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a
174856174826 const zcu = pt.zcu;
174857174827 const src_ty = self.typeOf(src_air);
174858174828 if (src_ty.zigTypeTag(zcu) == .vector)
174859 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(pt)});
174829 return self.fail("TODO implement genUnOp for {f}", .{src_ty.fmt(pt)});
174860174830
174861174831 var src_mcv = try self.resolveInst(src_air);
174862174832 switch (src_mcv) {
......@@ -174943,7 +174913,7 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a
174943174913fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
174944174914 const pt = self.pt;
174945174915 const abi_size: u32 = @intCast(dst_ty.abiSize(pt.zcu));
174946 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(pt) });
174916 if (abi_size > 8) return self.fail("TODO implement {} for {f}", .{ mir_tag, dst_ty.fmt(pt) });
174947174917 switch (dst_mcv) {
174948174918 .none,
174949174919 .unreach,
......@@ -175672,7 +175642,7 @@ fn genBinOp(
175672175642 },
175673175643 floatLibcAbiSuffix(lhs_ty),
175674175644 }),
175675 else => return self.fail("TODO implement genBinOp for {s} {}", .{
175645 else => return self.fail("TODO implement genBinOp for {s} {f}", .{
175676175646 @tagName(air_tag), lhs_ty.fmt(pt),
175677175647 }),
175678175648 } catch unreachable;
......@@ -175785,7 +175755,7 @@ fn genBinOp(
175785175755 );
175786175756 break :adjusted .{ .register = dst_reg };
175787175757 },
175788 80, 128 => return self.fail("TODO implement genBinOp for {s} of {}", .{
175758 80, 128 => return self.fail("TODO implement genBinOp for {s} of {f}", .{
175789175759 @tagName(air_tag), lhs_ty.fmt(pt),
175790175760 }),
175791175761 else => unreachable,
......@@ -175819,7 +175789,7 @@ fn genBinOp(
175819175789 if (sse_op and ((lhs_ty.scalarType(zcu).isRuntimeFloat() and
175820175790 lhs_ty.scalarType(zcu).floatBits(self.target) == 80) or
175821175791 lhs_ty.abiSize(zcu) > self.vectorSize(.float)))
175822 return self.fail("TODO implement genBinOp for {s} {}", .{ @tagName(air_tag), lhs_ty.fmt(pt) });
175792 return self.fail("TODO implement genBinOp for {s} {f}", .{ @tagName(air_tag), lhs_ty.fmt(pt) });
175823175793
175824175794 const maybe_mask_reg = switch (air_tag) {
175825175795 else => null,
......@@ -176199,7 +176169,7 @@ fn genBinOp(
176199176169 }
176200176170 },
176201176171
176202 else => return self.fail("TODO implement genBinOp for {s} {}", .{
176172 else => return self.fail("TODO implement genBinOp for {s} {f}", .{
176203176173 @tagName(air_tag), lhs_ty.fmt(pt),
176204176174 }),
176205176175 }
......@@ -176953,7 +176923,7 @@ fn genBinOp(
176953176923 else => unreachable,
176954176924 },
176955176925 },
176956 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
176926 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
176957176927 @tagName(air_tag), lhs_ty.fmt(pt),
176958176928 });
176959176929
......@@ -177086,7 +177056,7 @@ fn genBinOp(
177086177056 else => unreachable,
177087177057 },
177088177058 else => unreachable,
177089 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
177059 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177090177060 @tagName(air_tag), lhs_ty.fmt(pt),
177091177061 }),
177092177062 mask_reg,
......@@ -177118,7 +177088,7 @@ fn genBinOp(
177118177088 else => unreachable,
177119177089 },
177120177090 else => unreachable,
177121 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
177091 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177122177092 @tagName(air_tag), lhs_ty.fmt(pt),
177123177093 }),
177124177094 dst_reg,
......@@ -177154,7 +177124,7 @@ fn genBinOp(
177154177124 else => unreachable,
177155177125 },
177156177126 else => unreachable,
177157 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
177127 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177158177128 @tagName(air_tag), lhs_ty.fmt(pt),
177159177129 }),
177160177130 mask_reg,
......@@ -177185,7 +177155,7 @@ fn genBinOp(
177185177155 else => unreachable,
177186177156 },
177187177157 else => unreachable,
177188 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
177158 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177189177159 @tagName(air_tag), lhs_ty.fmt(pt),
177190177160 }),
177191177161 dst_reg,
......@@ -177215,7 +177185,7 @@ fn genBinOp(
177215177185 else => unreachable,
177216177186 },
177217177187 else => unreachable,
177218 }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{
177188 }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{
177219177189 @tagName(air_tag), lhs_ty.fmt(pt),
177220177190 });
177221177191 try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg);
......@@ -178022,7 +177992,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
178022177992
178023177993 break :result dst_mcv;
178024177994 },
178025 else => return self.fail("TODO implement arg for {}", .{src_mcv}),
177995 else => return self.fail("TODO implement arg for {f}", .{src_mcv}),
178026177996 }
178027177997 };
178028177998 return self.finishAir(inst, result, .{ .none, .none, .none });
......@@ -179079,7 +179049,7 @@ fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {
179079179049 const reg = try self.copyToTmpRegister(ty, mcv);
179080179050 return self.genCondBrMir(ty, .{ .register = reg });
179081179051 }
179082 return self.fail("TODO implement condbr when condition is {} with abi larger than 8 bytes", .{mcv});
179052 return self.fail("TODO implement condbr when condition is {f} with abi larger than 8 bytes", .{mcv});
179083179053 },
179084179054 else => return self.fail("TODO implement condbr when condition is {s}", .{@tagName(mcv)}),
179085179055 }
......@@ -179166,7 +179136,7 @@ fn isErr(self: *CodeGen, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCVal
179166179136 } },
179167179137 .{ .immediate = 0 },
179168179138 ),
179169 else => return self.fail("TODO implement isErr for {}", .{eu_mcv}),
179139 else => return self.fail("TODO implement isErr for {f}", .{eu_mcv}),
179170179140 }
179171179141
179172179142 if (maybe_inst) |inst| self.eflags_inst = inst;
......@@ -180916,7 +180886,7 @@ fn moveStrategy(cg: *CodeGen, ty: Type, class: Register.Class, aligned: bool) !M
180916180886 },
180917180887 .ip, .cr, .dr => {},
180918180888 }
180919 return cg.fail("TODO moveStrategy for {}", .{ty.fmt(pt)});
180889 return cg.fail("TODO moveStrategy for {f}", .{ty.fmt(pt)});
180920180890}
180921180891
180922180892const CopyOptions = struct {
......@@ -181048,7 +181018,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
181048181018 break :src_info .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock };
181049181019 },
181050181020 .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref), opts),
181051 else => return self.fail("TODO implement genCopy for {s} of {}", .{
181021 else => return self.fail("TODO implement genCopy for {s} of {f}", .{
181052181022 @tagName(src_mcv), ty.fmt(pt),
181053181023 }),
181054181024 };
......@@ -181424,7 +181394,7 @@ fn genSetReg(
181424181394 80 => null,
181425181395 else => unreachable,
181426181396 },
181427 }) orelse return self.fail("TODO implement genSetReg for {}", .{ty.fmt(pt)}),
181397 }) orelse return self.fail("TODO implement genSetReg for {f}", .{ty.fmt(pt)}),
181428181398 dst_alias,
181429181399 registerAlias(src_reg, abi_size),
181430181400 ),
......@@ -181854,7 +181824,7 @@ fn genSetMem(
181854181824 opts,
181855181825 );
181856181826 },
181857 else => return self.fail("TODO implement genSetMem for {s} of {}", .{
181827 else => return self.fail("TODO implement genSetMem for {s} of {f}", .{
181858181828 @tagName(src_mcv), ty.fmt(pt),
181859181829 }),
181860181830 },
......@@ -182167,7 +182137,7 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void {
182167182137 32, 64 => src_size > 8,
182168182138 else => unreachable,
182169182139 }) {
182170 if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {} to {}", .{
182140 if (src_bits > 128) return self.fail("TODO implement airFloatFromInt from {f} to {f}", .{
182171182141 src_ty.fmt(pt), dst_ty.fmt(pt),
182172182142 });
182173182143
......@@ -182209,7 +182179,7 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void {
182209182179 else => unreachable,
182210182180 },
182211182181 else => null,
182212 }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{
182182 }) orelse return self.fail("TODO implement airFloatFromInt from {f} to {f}", .{
182213182183 src_ty.fmt(pt), dst_ty.fmt(pt),
182214182184 });
182215182185 const dst_alias = dst_reg.to128();
......@@ -182247,7 +182217,7 @@ fn airIntFromFloat(self: *CodeGen, inst: Air.Inst.Index) !void {
182247182217 32, 64 => dst_size > 8,
182248182218 else => unreachable,
182249182219 }) {
182250 if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {} to {}", .{
182220 if (dst_bits > 128) return self.fail("TODO implement airIntFromFloat from {f} to {f}", .{
182251182221 src_ty.fmt(pt), dst_ty.fmt(pt),
182252182222 });
182253182223
......@@ -182531,7 +182501,7 @@ fn atomicOp(
182531182501 else => null,
182532182502 },
182533182503 else => unreachable,
182534 }) orelse return self.fail("TODO implement atomicOp of {s} for {}", .{
182504 }) orelse return self.fail("TODO implement atomicOp of {s} for {f}", .{
182535182505 @tagName(op), val_ty.fmt(pt),
182536182506 });
182537182507 try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{});
......@@ -183286,7 +183256,7 @@ fn airSplat(self: *CodeGen, inst: Air.Inst.Index) !void {
183286183256 else => unreachable,
183287183257 },
183288183258 }
183289 return self.fail("TODO implement airSplat for {}", .{vector_ty.fmt(pt)});
183259 return self.fail("TODO implement airSplat for {f}", .{vector_ty.fmt(pt)});
183290183260 };
183291183261 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
183292183262}
......@@ -183322,12 +183292,12 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
183322183292 else
183323183293 try self.copyToTmpRegister(pred_ty, pred_mcv)
183324183294 else
183325 return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)}),
183295 return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)}),
183326183296 else => unreachable,
183327183297 },
183328183298 .register_mask => |pred_reg_mask| {
183329183299 if (pred_reg_mask.info.scalar.bitSize(self.target) != 8 * elem_abi_size)
183330 return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
183300 return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)});
183331183301
183332183302 const mask_reg: Register = if (need_xmm0 and pred_reg_mask.reg.id() != comptime Register.xmm0.id()) mask_reg: {
183333183303 try self.register_manager.getKnownReg(.xmm0, null);
......@@ -183401,7 +183371,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
183401183371 else
183402183372 null
183403183373 else
183404 null) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
183374 null) orelse return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)});
183405183375 if (has_avx) {
183406183376 const rhs_alias = if (reuse_mcv.isRegister())
183407183377 registerAlias(reuse_mcv.getReg().?, abi_size)
......@@ -183554,7 +183524,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
183554183524 else => unreachable,
183555183525 }),
183556183526 );
183557 } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
183527 } else return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)});
183558183528 const elem_bits: u16 = @intCast(elem_abi_size * 8);
183559183529 if (!pred_fits_in_elem) if (self.hasFeature(.ssse3)) {
183560183530 const mask_len = elem_abi_size * vec_len;
......@@ -183583,7 +183553,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
183583183553 mask_alias,
183584183554 mask_mem,
183585183555 );
183586 } else return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
183556 } else return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)});
183587183557 {
183588183558 const mask_elem_ty = try pt.intType(.unsigned, elem_bits);
183589183559 const mask_ty = try pt.vectorType(.{ .len = vec_len, .child = mask_elem_ty.toIntern() });
......@@ -183706,7 +183676,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void {
183706183676 else => null,
183707183677 },
183708183678 },
183709 }) orelse return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)});
183679 }) orelse return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)});
183710183680 if (has_avx) {
183711183681 const rhs_alias = if (rhs_mcv.isRegister())
183712183682 registerAlias(rhs_mcv.getReg().?, abi_size)
......@@ -184551,7 +184521,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void {
184551184521 }
184552184522
184553184523 break :result null;
184554 }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{
184524 }) orelse return self.fail("TODO implement airShuffle from {f} and {f} to {f} with {f}", .{
184555184525 lhs_ty.fmt(pt),
184556184526 rhs_ty.fmt(pt),
184557184527 dst_ty.fmt(pt),
......@@ -184800,7 +184770,7 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void {
184800184770 32, 64 => !self.hasFeature(.fma),
184801184771 else => unreachable,
184802184772 }) {
184803 if (ty.zigTypeTag(zcu) != .float) return self.fail("TODO implement airMulAdd for {}", .{
184773 if (ty.zigTypeTag(zcu) != .float) return self.fail("TODO implement airMulAdd for {f}", .{
184804184774 ty.fmt(pt),
184805184775 });
184806184776
......@@ -184930,7 +184900,7 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void {
184930184900 else => unreachable,
184931184901 }
184932184902 else
184933 unreachable) orelse return self.fail("TODO implement airMulAdd for {}", .{ty.fmt(pt)});
184903 unreachable) orelse return self.fail("TODO implement airMulAdd for {f}", .{ty.fmt(pt)});
184934184904
184935184905 var mops: [3]MCValue = undefined;
184936184906 for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv;
......@@ -185130,7 +185100,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void {
185130185100 assert(classes.len == 1);
185131185101 unreachable;
185132185102 },
185133 else => return self.fail("TODO implement c_va_arg for {} on SysV", .{promote_ty.fmt(pt)}),
185103 else => return self.fail("TODO implement c_va_arg for {f} on SysV", .{promote_ty.fmt(pt)}),
185134185104 }
185135185105
185136185106 if (unused) break :result .unreach;
......@@ -185779,7 +185749,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty
185779185749 for (parts) |part| part_sizes += part.abiSize(zcu);
185780185750 if (part_sizes == ty.abiSize(zcu)) return parts;
185781185751 };
185782 return self.fail("TODO implement splitType({d}, {})", .{ parts_len, ty.fmt(pt) });
185752 return self.fail("TODO implement splitType({d}, {f})", .{ parts_len, ty.fmt(pt) });
185783185753}
185784185754
185785185755/// Truncates the value in the register in place.
......@@ -186153,7 +186123,7 @@ const Temp = struct {
186153186123 cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1);
186154186124 const mcv = temp.tracking(cg).short;
186155186125 switch (mcv) {
186156 else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
186126 else => std.debug.panic("{s}: {f}\n", .{ @src().fn_name, mcv }),
186157186127 .register => |reg| {
186158186128 const new_reg = try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp);
186159186129 new_temp_index.tracking(cg).* = .init(.{ .register = new_reg });
......@@ -186227,7 +186197,7 @@ const Temp = struct {
186227186197 const new_temp_index = cg.next_temp_index;
186228186198 cg.temp_type[@intFromEnum(new_temp_index)] = limb_ty;
186229186199 switch (temp.tracking(cg).short) {
186230 else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
186200 else => |mcv| std.debug.panic("{s}: {f}\n", .{ @src().fn_name, mcv }),
186231186201 .immediate => |imm| {
186232186202 assert(limb_index == 0);
186233186203 new_temp_index.tracking(cg).* = .init(.{ .immediate = imm });
......@@ -186568,7 +186538,7 @@ const Temp = struct {
186568186538 },
186569186539 else => {},
186570186540 }
186571 std.debug.panic("{s}: {} {}\n", .{ @src().fn_name, temp_tracking, overflow_temp_tracking });
186541 std.debug.panic("{s}: {f} {f}\n", .{ @src().fn_name, temp_tracking, overflow_temp_tracking });
186572186542 }
186573186543
186574186544 fn asMask(temp: Temp, info: MaskInfo, cg: *CodeGen) void {
......@@ -186658,7 +186628,7 @@ const Temp = struct {
186658186628 while (try ptr.toLea(cg)) {}
186659186629 const val_mcv = val.tracking(cg).short;
186660186630 switch (val_mcv) {
186661 else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
186631 else => |mcv| std.debug.panic("{s}: {f}\n", .{ @src().fn_name, mcv }),
186662186632 .register => |val_reg| try ptr.loadReg(val_ty, registerAlias(
186663186633 val_reg,
186664186634 @intCast(val_ty.abiSize(cg.pt.zcu)),
......@@ -186698,7 +186668,7 @@ const Temp = struct {
186698186668 {}) {
186699186669 const val_mcv = val.tracking(cg).short;
186700186670 switch (val_mcv) {
186701 else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
186671 else => |mcv| std.debug.panic("{s}: {f}\n", .{ @src().fn_name, mcv }),
186702186672 .undef => if (opts.safe) {
186703186673 var pat = try cg.tempInit(.u8, .{ .immediate = 0xaa });
186704186674 var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) });
......@@ -186772,7 +186742,7 @@ const Temp = struct {
186772186742 assert(!val_ty.optionalReprIsPayload(cg.pt.zcu));
186773186743 break :first_ty opt_child;
186774186744 },
186775 else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }),
186745 else => std.debug.panic("{s}: {f}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }),
186776186746 });
186777186747 const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu));
186778186748 try ptr.storeRegs(first_ty, &.{registerAlias(val_reg_ov.reg, first_size)}, cg);
......@@ -186804,7 +186774,7 @@ const Temp = struct {
186804186774
186805186775 fn readTo(src: *Temp, val_ty: Type, val_mcv: MCValue, opts: AccessOptions, cg: *CodeGen) InnerError!void {
186806186776 switch (val_mcv) {
186807 else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
186777 else => |mcv| std.debug.panic("{s}: {f}\n", .{ @src().fn_name, mcv }),
186808186778 .register => |val_reg| try src.readReg(opts.disp, val_ty, registerAlias(
186809186779 val_reg,
186810186780 @intCast(cg.unalignedSize(val_ty)),
......@@ -186844,7 +186814,7 @@ const Temp = struct {
186844186814 {}) {
186845186815 const val_mcv = val.tracking(cg).short;
186846186816 switch (val_mcv) {
186847 else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
186817 else => |mcv| std.debug.panic("{s}: {f}\n", .{ @src().fn_name, mcv }),
186848186818 .none => {},
186849186819 .undef => if (opts.safe) {
186850186820 var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp));
......@@ -186905,7 +186875,7 @@ const Temp = struct {
186905186875 assert(!val_ty.optionalReprIsPayload(cg.pt.zcu));
186906186876 break :first_ty opt_child;
186907186877 },
186908 else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }),
186878 else => std.debug.panic("{s}: {f}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }),
186909186879 });
186910186880 const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu));
186911186881 try dst.writeReg(opts.disp, first_ty, registerAlias(val_reg_ov.reg, first_size), cg);
......@@ -191677,12 +191647,12 @@ const Temp = struct {
191677191647 break :result result;
191678191648 },
191679191649 };
191680 tracking_log.debug("{} => {} (birth)", .{ inst, result });
191650 tracking_log.debug("{f} => {f} (birth)", .{ inst, result });
191681191651 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result));
191682191652 },
191683191653 .temp => |temp_index| {
191684191654 const temp_tracking = temp_index.tracking(cg);
191685 tracking_log.debug("{} => {} (birth)", .{ inst, temp_tracking.short });
191655 tracking_log.debug("{f} => {f} (birth)", .{ inst, temp_tracking.short });
191686191656 cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short));
191687191657 assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking));
191688191658 },
......@@ -191757,7 +191727,7 @@ fn resetTemps(cg: *CodeGen, from_index: Temp.Index) InnerError!void {
191757191727 const temp: Temp.Index = @enumFromInt(temp_index);
191758191728 if (temp.isValid(cg)) {
191759191729 any_valid = true;
191760 tracking_log.err("failed to kill {}: {}", .{
191730 tracking_log.err("failed to kill {f}: {f}", .{
191761191731 temp.toIndex(),
191762191732 cg.temp_type[temp_index].fmt(cg.pt),
191763191733 });
src/arch/x86_64/Disassembler.zig+73-92
......@@ -31,10 +31,11 @@ pub fn init(code: []const u8) Disassembler {
3131}
3232
3333pub fn next(dis: *Disassembler) Error!?Instruction {
34 const prefixes = dis.parsePrefixes() catch |err| switch (err) {
35 error.EndOfStream => return null,
36 else => |e| return e,
37 };
34 return @errorCast(dis.nextInner());
35}
36
37fn nextInner(dis: *Disassembler) anyerror!?Instruction {
38 const prefixes = try dis.parsePrefixes();
3839
3940 const enc = try dis.parseEncoding(prefixes) orelse return error.UnknownOpcode;
4041 switch (enc.data.op_en) {
......@@ -283,66 +284,53 @@ const Prefixes = struct {
283284
284285fn parsePrefixes(dis: *Disassembler) !Prefixes {
285286 const rex_prefix_mask: u4 = 0b0100;
286 var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
287 const reader = stream.reader();
288
289287 var res: Prefixes = .{};
288 for (dis.code[dis.pos..], dis.pos..) |byte, pos| switch (byte) {
289 0xf0, 0xf2, 0xf3, 0x2e, 0x36, 0x26, 0x64, 0x65, 0x3e, 0x66, 0x67 => {
290 // Legacy prefix
291 if (res.rex.present) return error.LegacyPrefixAfterRex;
292 switch (byte) {
293 0xf0 => res.legacy.prefix_f0 = true,
294 0xf2 => res.legacy.prefix_f2 = true,
295 0xf3 => res.legacy.prefix_f3 = true,
296 0x2e => res.legacy.prefix_2e = true,
297 0x36 => res.legacy.prefix_36 = true,
298 0x26 => res.legacy.prefix_26 = true,
299 0x64 => res.legacy.prefix_64 = true,
300 0x65 => res.legacy.prefix_65 = true,
301 0x3e => res.legacy.prefix_3e = true,
302 0x66 => res.legacy.prefix_66 = true,
303 0x67 => res.legacy.prefix_67 = true,
304 else => unreachable,
305 }
306 },
307 else => {
308 if (rex_prefix_mask == @as(u4, @truncate(byte >> 4))) {
309 // REX prefix
310 res.rex.w = byte & 0b1000 != 0;
311 res.rex.r = byte & 0b100 != 0;
312 res.rex.x = byte & 0b10 != 0;
313 res.rex.b = byte & 0b1 != 0;
314 res.rex.present = true;
315 continue;
316 }
290317
291 while (true) {
292 const next_byte = try reader.readByte();
293 dis.pos += 1;
294
295 switch (next_byte) {
296 0xf0, 0xf2, 0xf3, 0x2e, 0x36, 0x26, 0x64, 0x65, 0x3e, 0x66, 0x67 => {
297 // Legacy prefix
298 if (res.rex.present) return error.LegacyPrefixAfterRex;
299 switch (next_byte) {
300 0xf0 => res.legacy.prefix_f0 = true,
301 0xf2 => res.legacy.prefix_f2 = true,
302 0xf3 => res.legacy.prefix_f3 = true,
303 0x2e => res.legacy.prefix_2e = true,
304 0x36 => res.legacy.prefix_36 = true,
305 0x26 => res.legacy.prefix_26 = true,
306 0x64 => res.legacy.prefix_64 = true,
307 0x65 => res.legacy.prefix_65 = true,
308 0x3e => res.legacy.prefix_3e = true,
309 0x66 => res.legacy.prefix_66 = true,
310 0x67 => res.legacy.prefix_67 = true,
311 else => unreachable,
312 }
313 },
314 else => {
315 if (rex_prefix_mask == @as(u4, @truncate(next_byte >> 4))) {
316 // REX prefix
317 res.rex.w = next_byte & 0b1000 != 0;
318 res.rex.r = next_byte & 0b100 != 0;
319 res.rex.x = next_byte & 0b10 != 0;
320 res.rex.b = next_byte & 0b1 != 0;
321 res.rex.present = true;
322 continue;
323 }
324
325 // TODO VEX prefix
326
327 dis.pos -= 1;
328 break;
329 },
330 }
331 }
318 // TODO VEX prefix
332319
320 dis.pos = pos;
321 break;
322 },
323 };
333324 return res;
334325}
335326
336327fn parseEncoding(dis: *Disassembler, prefixes: Prefixes) !?Encoding {
337328 const o_mask: u8 = 0b1111_1000;
338
339329 var opcode: [3]u8 = .{ 0, 0, 0 };
340 var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
341 const reader = stream.reader();
342330
343331 comptime var opc_count = 0;
344332 inline while (opc_count < 3) : (opc_count += 1) {
345 const byte = try reader.readByte();
333 const byte = dis.code[dis.pos];
346334 opcode[opc_count] = byte;
347335 dis.pos += 1;
348336
......@@ -387,30 +375,27 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi
387375 };
388376}
389377
390fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate {
391 var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
392 var creader = std.io.countingReader(stream.reader());
393 const reader = creader.reader();
394 const imm = switch (kind) {
395 .imm8s, .rel8 => Immediate.s(try reader.readInt(i8, .little)),
396 .imm16s, .rel16 => Immediate.s(try reader.readInt(i16, .little)),
397 .imm32s, .rel32 => Immediate.s(try reader.readInt(i32, .little)),
398 .imm8 => Immediate.u(try reader.readInt(u8, .little)),
399 .imm16 => Immediate.u(try reader.readInt(u16, .little)),
400 .imm32 => Immediate.u(try reader.readInt(u32, .little)),
401 .imm64 => Immediate.u(try reader.readInt(u64, .little)),
378fn parseImm(dis: *Disassembler, kind: Encoding.Op) anyerror!Immediate {
379 var br: std.io.BufferedReader = undefined;
380 br.initFixed(dis.code[dis.pos..]);
381 defer dis.pos += br.seek;
382 return switch (kind) {
383 .imm8s, .rel8 => .s(try br.takeInt(i8, .little)),
384 .imm16s, .rel16 => .s(try br.takeInt(i16, .little)),
385 .imm32s, .rel32 => .s(try br.takeInt(i32, .little)),
386 .imm8 => .u(try br.takeInt(u8, .little)),
387 .imm16 => .u(try br.takeInt(u16, .little)),
388 .imm32 => .u(try br.takeInt(u32, .little)),
389 .imm64 => .u(try br.takeInt(u64, .little)),
402390 else => unreachable,
403391 };
404 dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow;
405 return imm;
406392}
407393
408fn parseOffset(dis: *Disassembler) !u64 {
409 var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
410 const reader = stream.reader();
411 const offset = try reader.readInt(u64, .little);
412 dis.pos += 8;
413 return offset;
394fn parseOffset(dis: *Disassembler) anyerror!u64 {
395 var br: std.io.BufferedReader = undefined;
396 br.initFixed(dis.code[dis.pos..]);
397 defer dis.pos += br.seek;
398 return br.takeInt(u64, .little);
414399}
415400
416401const ModRm = packed struct {
......@@ -482,26 +467,22 @@ fn parseSibByte(dis: *Disassembler) !Sib {
482467 return Sib{ .scale = scale, .index = index, .base = base };
483468}
484469
485fn parseDisplacement(dis: *Disassembler, modrm: ModRm, sib: ?Sib) !i32 {
486 var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
487 var creader = std.io.countingReader(stream.reader());
488 const reader = creader.reader();
489 const disp = disp: {
490 if (sib) |info| {
491 if (info.base == 0b101 and modrm.mod == 0) {
492 break :disp try reader.readInt(i32, .little);
493 }
494 }
495 if (modrm.rip()) {
496 break :disp try reader.readInt(i32, .little);
470fn parseDisplacement(dis: *Disassembler, modrm: ModRm, sib: ?Sib) anyerror!i32 {
471 var br: std.io.BufferedReader = undefined;
472 br.initFixed(dis.code[dis.pos..]);
473 defer dis.pos += br.seek;
474 if (sib) |info| {
475 if (info.base == 0b101 and modrm.mod == 0) {
476 return br.takeInt(i32, .little);
497477 }
498 break :disp switch (modrm.mod) {
499 0b00 => 0,
500 0b01 => try reader.readInt(i8, .little),
501 0b10 => try reader.readInt(i32, .little),
502 0b11 => unreachable,
503 };
478 }
479 if (modrm.rip()) {
480 return br.takeInt(i32, .little);
481 }
482 return switch (modrm.mod) {
483 0b00 => 0,
484 0b01 => try br.takeInt(i8, .little),
485 0b10 => try br.takeInt(i32, .little),
486 0b11 => unreachable,
504487 };
505 dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow;
506 return disp;
507488}
src/arch/x86_64/Emit.zig+16-21
......@@ -424,19 +424,19 @@ pub fn emitMir(emit: *Emit) Error!void {
424424 .line = mir_inst.data.line_column.line,
425425 .column = mir_inst.data.line_column.column,
426426 .is_stmt = true,
427 }),
427 }, emit.code.items.len),
428428 .pseudo_dbg_line_line_column => try emit.dbgAdvancePCAndLine(.{
429429 .line = mir_inst.data.line_column.line,
430430 .column = mir_inst.data.line_column.column,
431431 .is_stmt = false,
432 }),
432 }, emit.code.items.len),
433433 .pseudo_dbg_epilogue_begin_none => switch (emit.debug_output) {
434434 .dwarf => |dwarf| {
435435 try dwarf.setEpilogueBegin();
436436 log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
437437 emit.prev_di_loc.line, emit.prev_di_loc.column,
438438 });
439 try emit.dbgAdvancePCAndLine(emit.prev_di_loc);
439 try emit.dbgAdvancePCAndLine(emit.prev_di_loc, emit.code.items.len);
440440 },
441441 .plan9 => {},
442442 .none => {},
......@@ -909,9 +909,9 @@ const Loc = struct {
909909 is_stmt: bool,
910910};
911911
912fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
912fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc, pc: usize) anyerror!void {
913913 const delta_line = @as(i33, loc.line) - @as(i33, emit.prev_di_loc.line);
914 const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
914 const delta_pc = pc - emit.prev_di_pc;
915915 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
916916 switch (emit.debug_output) {
917917 .dwarf => |dwarf| {
......@@ -919,30 +919,25 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
919919 if (loc.column != emit.prev_di_loc.column) try dwarf.setColumn(loc.column);
920920 try dwarf.advancePCAndLine(delta_line, delta_pc);
921921 emit.prev_di_loc = loc;
922 emit.prev_di_pc = emit.code.items.len;
922 emit.prev_di_pc = pc;
923923 },
924924 .plan9 => |dbg_out| {
925925 if (delta_pc <= 0) return; // only do this when the pc changes
926926
927 var aw: std.io.AllocatingWriter = undefined;
928 const bw = aw.fromArrayList(emit.lower.bin_file.comp.gpa, &dbg_out.dbg_line);
929 defer dbg_out.dbg_line = aw.toArrayList();
930
927931 // increasing the line number
928 try link.File.Plan9.changeLine(&dbg_out.dbg_line, @intCast(delta_line));
932 try link.File.Plan9.changeLine(bw, @intCast(delta_line));
929933 // increasing the pc
930934 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
931935 if (d_pc_p9 > 0) {
932936 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
933 var diff = @divExact(d_pc_p9, dbg_out.pc_quanta) - dbg_out.pc_quanta;
934 while (diff > 0) {
935 if (diff < 64) {
936 try dbg_out.dbg_line.append(@intCast(diff + 128));
937 diff = 0;
938 } else {
939 try dbg_out.dbg_line.append(@intCast(64 + 128));
940 diff -= 64;
941 }
942 }
943 if (dbg_out.pcop_change_index) |pci|
944 dbg_out.dbg_line.items[pci] += 1;
945 dbg_out.pcop_change_index = @intCast(dbg_out.dbg_line.items.len - 1);
937 try bw.writeByte(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
938 const dbg_line = aw.getWritten();
939 if (dbg_out.pcop_change_index) |pci| dbg_line[pci] += 1;
940 dbg_out.pcop_change_index = @intCast(dbg_line.len - 1);
946941 } else if (d_pc_p9 == 0) {
947942 // we don't need to do anything, because adding the pc quanta does it for us
948943 } else unreachable;
......@@ -951,7 +946,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
951946 dbg_out.end_line = loc.line;
952947 // only do this if the pc changed
953948 emit.prev_di_loc = loc;
954 emit.prev_di_pc = emit.code.items.len;
949 emit.prev_di_pc = pc;
955950 },
956951 .none => {},
957952 }
src/arch/x86_64/Encoding.zig+25-29
......@@ -158,20 +158,14 @@ pub fn modRmExt(encoding: Encoding) u3 {
158158 };
159159}
160160
161pub fn format(
162 encoding: Encoding,
163 comptime fmt: []const u8,
164 options: std.fmt.FormatOptions,
165 writer: anytype,
166) !void {
167 _ = options;
161pub fn format(encoding: Encoding, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
168162 _ = fmt;
169163
170164 var opc = encoding.opcode();
171165 if (encoding.data.mode.isVex()) {
172 try writer.writeAll("VEX.");
166 try bw.writeAll("VEX.");
173167
174 try writer.writeAll(switch (encoding.data.mode) {
168 try bw.writeAll(switch (encoding.data.mode) {
175169 .vex_128_w0, .vex_128_w1, .vex_128_wig => "128",
176170 .vex_256_w0, .vex_256_w1, .vex_256_wig => "256",
177171 .vex_lig_w0, .vex_lig_w1, .vex_lig_wig => "LIG",
......@@ -182,25 +176,25 @@ pub fn format(
182176 switch (opc[0]) {
183177 else => {},
184178 0x66, 0xf3, 0xf2 => {
185 try writer.print(".{X:0>2}", .{opc[0]});
179 try bw.print(".{X:0>2}", .{opc[0]});
186180 opc = opc[1..];
187181 },
188182 }
189183
190 try writer.print(".{}", .{std.fmt.fmtSliceHexUpper(opc[0 .. opc.len - 1])});
184 try bw.print(".{X}", .{opc[0 .. opc.len - 1]});
191185 opc = opc[opc.len - 1 ..];
192186
193 try writer.writeAll(".W");
194 try writer.writeAll(switch (encoding.data.mode) {
187 try bw.writeAll(".W");
188 try bw.writeAll(switch (encoding.data.mode) {
195189 .vex_128_w0, .vex_256_w0, .vex_lig_w0, .vex_lz_w0 => "0",
196190 .vex_128_w1, .vex_256_w1, .vex_lig_w1, .vex_lz_w1 => "1",
197191 .vex_128_wig, .vex_256_wig, .vex_lig_wig, .vex_lz_wig => "IG",
198192 else => unreachable,
199193 });
200194
201 try writer.writeByte(' ');
202 } else if (encoding.data.mode.isLong()) try writer.writeAll("REX.W + ");
203 for (opc) |byte| try writer.print("{x:0>2} ", .{byte});
195 try bw.writeByte(' ');
196 } else if (encoding.data.mode.isLong()) try bw.writeAll("REX.W + ");
197 for (opc) |byte| try bw.print("{x:0>2} ", .{byte});
204198
205199 switch (encoding.data.op_en) {
206200 .z, .fd, .td, .i, .zi, .ii, .d => {},
......@@ -217,10 +211,10 @@ pub fn format(
217211 .r64 => "rd",
218212 else => unreachable,
219213 };
220 try writer.print("+{s} ", .{tag});
214 try bw.print("+{s} ", .{tag});
221215 },
222 .ia, .m, .mi, .m1, .mc, .vm, .vmi => try writer.print("/{d} ", .{encoding.modRmExt()}),
223 .mr, .rm, .rmi, .mri, .mrc, .rm0, .rvm, .rvmr, .rvmi, .mvr, .rmv => try writer.writeAll("/r "),
216 .ia, .m, .mi, .m1, .mc, .vm, .vmi => try bw.print("/{d} ", .{encoding.modRmExt()}),
217 .mr, .rm, .rmi, .mri, .mrc, .rm0, .rvm, .rvmr, .rvmi, .mvr, .rmv => try bw.writeAll("/r "),
224218 }
225219
226220 switch (encoding.data.op_en) {
......@@ -249,24 +243,24 @@ pub fn format(
249243 .rel32 => "cd",
250244 else => unreachable,
251245 };
252 try writer.print("{s} ", .{tag});
246 try bw.print("{s} ", .{tag});
253247 },
254 .rvmr => try writer.writeAll("/is4 "),
248 .rvmr => try bw.writeAll("/is4 "),
255249 .z, .fd, .td, .o, .zo, .oz, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .vm, .rvm, .mvr, .rmv => {},
256250 }
257251
258 try writer.print("{s} ", .{@tagName(encoding.mnemonic)});
252 try bw.print("{s} ", .{@tagName(encoding.mnemonic)});
259253
260254 for (encoding.data.ops) |op| switch (op) {
261255 .none => break,
262 else => try writer.print("{s} ", .{@tagName(op)}),
256 else => try bw.print("{s} ", .{@tagName(op)}),
263257 };
264258
265259 const op_en = switch (encoding.data.op_en) {
266260 .zi => .i,
267261 else => |op_en| op_en,
268262 };
269 try writer.print("{s}", .{@tagName(op_en)});
263 try bw.print("{s}", .{@tagName(op_en)});
270264}
271265
272266pub const Mnemonic = enum {
......@@ -1014,19 +1008,21 @@ pub const Feature = enum {
10141008};
10151009
10161010fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Operand) usize {
1017 var inst = Instruction{
1011 var inst: Instruction = .{
10181012 .prefix = prefix,
10191013 .encoding = encoding,
10201014 .ops = @splat(.none),
10211015 };
10221016 @memcpy(inst.ops[0..ops.len], ops);
10231017
1024 var cwriter = std.io.countingWriter(std.io.null_writer);
1025 inst.encode(cwriter.writer(), .{
1018 var buf: [15]u8 = undefined;
1019 var bw: std.io.BufferedWriter = undefined;
1020 bw.initFixed(&buf);
1021 inst.encode(&bw, .{
10261022 .allow_frame_locs = true,
10271023 .allow_symbols = true,
1028 }) catch unreachable; // Not allowed to fail here unless OOM.
1029 return @as(usize, @intCast(cwriter.bytes_written));
1024 }) catch unreachable;
1025 return @intCast(bw.end);
10301026}
10311027
10321028const mnemonic_to_encodings_map = init: {
src/arch/x86_64/bits.zig+9-26
......@@ -728,21 +728,12 @@ pub const FrameIndex = enum(u32) {
728728 return @intFromEnum(fi) < named_count;
729729 }
730730
731 pub fn format(
732 fi: FrameIndex,
733 comptime fmt: []const u8,
734 options: std.fmt.FormatOptions,
735 writer: anytype,
736 ) @TypeOf(writer).Error!void {
737 try writer.writeAll("FrameIndex");
738 if (fi.isNamed()) {
739 try writer.writeByte('.');
740 try writer.writeAll(@tagName(fi));
741 } else {
742 try writer.writeByte('(');
743 try std.fmt.formatType(@intFromEnum(fi), fmt, options, writer, 0);
744 try writer.writeByte(')');
745 }
731 pub fn format(fi: FrameIndex, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
732 try bw.writeAll("FrameIndex");
733 if (fi.isNamed())
734 try bw.print(".{s}", .{@tagName(fi)})
735 else
736 try bw.print("({d})", .{@intFromEnum(fi)});
746737 }
747738};
748739
......@@ -844,21 +835,13 @@ pub const Memory = struct {
844835 };
845836 }
846837
847 pub fn format(
848 s: Size,
849 comptime _: []const u8,
850 _: std.fmt.FormatOptions,
851 writer: anytype,
852 ) @TypeOf(writer).Error!void {
838 pub fn format(s: Size, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
853839 if (s == .none) return;
854 try writer.writeAll(@tagName(s));
840 try bw.writeAll(@tagName(s));
855841 switch (s) {
856842 .none => unreachable,
857843 .ptr, .gpr => {},
858 else => {
859 try writer.writeByte(' ');
860 try writer.writeAll("ptr");
861 },
844 else => try bw.writeAll(" ptr"),
862845 }
863846 }
864847 };
src/arch/x86_64/encoder.zig+102-121
......@@ -226,16 +226,10 @@ pub const Instruction = struct {
226226 };
227227 }
228228
229 fn format(
230 op: Operand,
231 comptime unused_format_string: []const u8,
232 options: std.fmt.FormatOptions,
233 writer: anytype,
234 ) !void {
229 fn format(op: Operand, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
235230 _ = op;
231 _ = bw;
236232 _ = unused_format_string;
237 _ = options;
238 _ = writer;
239233 @compileError("do not format Operand directly; use fmt() instead");
240234 }
241235
......@@ -244,78 +238,72 @@ pub const Instruction = struct {
244238 enc_op: Encoding.Op,
245239 };
246240
247 fn fmtContext(
248 ctx: FormatContext,
249 comptime unused_format_string: []const u8,
250 options: std.fmt.FormatOptions,
251 writer: anytype,
252 ) @TypeOf(writer).Error!void {
241 fn fmtContext(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
253242 _ = unused_format_string;
254 _ = options;
255243 const op = ctx.op;
256244 const enc_op = ctx.enc_op;
257245 switch (op) {
258246 .none => {},
259 .reg => |reg| try writer.writeAll(@tagName(reg)),
247 .reg => |reg| try bw.writeAll(@tagName(reg)),
260248 .mem => |mem| switch (mem) {
261249 .rip => |rip| {
262 try writer.print("{} [rip", .{rip.ptr_size});
263 if (rip.disp != 0) try writer.print(" {c} 0x{x}", .{
250 try bw.print("{f} [rip", .{rip.ptr_size});
251 if (rip.disp != 0) try bw.print(" {c} 0x{x}", .{
264252 @as(u8, if (rip.disp < 0) '-' else '+'),
265253 @abs(rip.disp),
266254 });
267 try writer.writeByte(']');
255 try bw.writeByte(']');
268256 },
269257 .sib => |sib| {
270 try writer.print("{} ", .{sib.ptr_size});
258 try bw.print("{f} ", .{sib.ptr_size});
271259
272260 if (mem.isSegmentRegister()) {
273 return writer.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp });
261 return bw.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp });
274262 }
275263
276 try writer.writeByte('[');
264 try bw.writeByte('[');
277265
278266 var any = true;
279267 switch (sib.base) {
280268 .none => any = false,
281 .reg => |reg| try writer.print("{s}", .{@tagName(reg)}),
282 .frame => |frame_index| try writer.print("{}", .{frame_index}),
283 .table => try writer.print("Table", .{}),
284 .rip_inst => |inst_index| try writer.print("RipInst({d})", .{inst_index}),
285 .nav => |nav| try writer.print("Nav({d})", .{@intFromEnum(nav)}),
286 .uav => |uav| try writer.print("Uav({d})", .{@intFromEnum(uav.val)}),
287 .lazy_sym => |lazy_sym| try writer.print("LazySym({s}, {d})", .{
269 .reg => |reg| try bw.print("{s}", .{@tagName(reg)}),
270 .frame => |frame_index| try bw.print("{}", .{frame_index}),
271 .table => try bw.print("Table", .{}),
272 .rip_inst => |inst_index| try bw.print("RipInst({d})", .{inst_index}),
273 .nav => |nav| try bw.print("Nav({d})", .{@intFromEnum(nav)}),
274 .uav => |uav| try bw.print("Uav({d})", .{@intFromEnum(uav.val)}),
275 .lazy_sym => |lazy_sym| try bw.print("LazySym({s}, {d})", .{
288276 @tagName(lazy_sym.kind),
289277 @intFromEnum(lazy_sym.ty),
290278 }),
291 .extern_func => |extern_func| try writer.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
279 .extern_func => |extern_func| try bw.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
292280 }
293281 if (mem.scaleIndex()) |si| {
294 if (any) try writer.writeAll(" + ");
295 try writer.print("{s} * {d}", .{ @tagName(si.index), si.scale });
282 if (any) try bw.writeAll(" + ");
283 try bw.print("{s} * {d}", .{ @tagName(si.index), si.scale });
296284 any = true;
297285 }
298286 if (sib.disp != 0 or !any) {
299287 if (any)
300 try writer.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')})
288 try bw.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')})
301289 else if (sib.disp < 0)
302 try writer.writeByte('-');
303 try writer.print("0x{x}", .{@abs(sib.disp)});
290 try bw.writeByte('-');
291 try bw.print("0x{x}", .{@abs(sib.disp)});
304292 any = true;
305293 }
306294
307 try writer.writeByte(']');
295 try bw.writeByte(']');
308296 },
309 .moffs => |moffs| try writer.print("{s}:0x{x}", .{
297 .moffs => |moffs| try bw.print("{s}:0x{x}", .{
310298 @tagName(moffs.seg),
311299 moffs.offset,
312300 }),
313301 },
314302 .imm => |imm| if (enc_op.isSigned()) {
315303 const imms = imm.asSigned(enc_op.immBitSize());
316 if (imms < 0) try writer.writeByte('-');
317 try writer.print("0x{x}", .{@abs(imms)});
318 } else try writer.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}),
304 if (imms < 0) try bw.writeByte('-');
305 try bw.print("0x{x}", .{@abs(imms)});
306 } else try bw.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}),
319307 .bytes => unreachable,
320308 }
321309 }
......@@ -361,7 +349,7 @@ pub const Instruction = struct {
361349 },
362350 },
363351 };
364 log.debug("selected encoding: {}", .{encoding});
352 log.debug("selected encoding: {f}", .{encoding});
365353
366354 var inst: Instruction = .{
367355 .prefix = prefix,
......@@ -372,30 +360,23 @@ pub const Instruction = struct {
372360 return inst;
373361 }
374362
375 pub fn format(
376 inst: Instruction,
377 comptime unused_format_string: []const u8,
378 options: std.fmt.FormatOptions,
379 writer: anytype,
380 ) @TypeOf(writer).Error!void {
363 pub fn format(inst: Instruction, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
381364 _ = unused_format_string;
382 _ = options;
383365 switch (inst.prefix) {
384366 .none, .directive => {},
385 else => try writer.print("{s} ", .{@tagName(inst.prefix)}),
367 else => try bw.print("{s} ", .{@tagName(inst.prefix)}),
386368 }
387 try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)});
369 try bw.print("{s}", .{@tagName(inst.encoding.mnemonic)});
388370 for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| {
389371 if (op == .none) break;
390 if (i > 0) try writer.writeByte(',');
391 try writer.writeByte(' ');
392 try writer.print("{}", .{op.fmt(enc)});
372 if (i > 0) try bw.writeByte(',');
373 try bw.print(" {f}", .{op.fmt(enc)});
393374 }
394375 }
395376
396 pub fn encode(inst: Instruction, writer: anytype, comptime opts: Options) !void {
377 pub fn encode(inst: Instruction, bw: *std.io.BufferedWriter, comptime opts: Options) !void {
397378 assert(inst.prefix != .directive);
398 const encoder = Encoder(@TypeOf(writer), opts){ .writer = writer };
379 const encoder: Encoder(opts) = .{ .bw = bw };
399380 const enc = inst.encoding;
400381 const data = enc.data;
401382
......@@ -801,9 +782,9 @@ pub const LegacyPrefixes = packed struct {
801782
802783pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool = false };
803784
804fn Encoder(comptime T: type, comptime opts: Options) type {
785fn Encoder(comptime opts: Options) type {
805786 return struct {
806 writer: T,
787 bw: *std.io.BufferedWriter,
807788
808789 const Self = @This();
809790 pub const options = opts;
......@@ -813,44 +794,44 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
813794 // --------
814795
815796 /// Encodes legacy prefixes
816 pub fn legacyPrefixes(self: Self, prefixes: LegacyPrefixes) !void {
797 pub fn legacyPrefixes(self: Self, prefixes: LegacyPrefixes) anyerror!void {
817798 if (@as(u16, @bitCast(prefixes)) != 0) {
818799 // Hopefully this path isn't taken very often, so we'll do it the slow way for now
819800
820801 // LOCK
821 if (prefixes.prefix_f0) try self.writer.writeByte(0xf0);
802 if (prefixes.prefix_f0) try self.bw.writeByte(0xf0);
822803 // REPNZ, REPNE, REP, Scalar Double-precision
823 if (prefixes.prefix_f2) try self.writer.writeByte(0xf2);
804 if (prefixes.prefix_f2) try self.bw.writeByte(0xf2);
824805 // REPZ, REPE, REP, Scalar Single-precision
825 if (prefixes.prefix_f3) try self.writer.writeByte(0xf3);
806 if (prefixes.prefix_f3) try self.bw.writeByte(0xf3);
826807
827808 // CS segment override or Branch not taken
828 if (prefixes.prefix_2e) try self.writer.writeByte(0x2e);
809 if (prefixes.prefix_2e) try self.bw.writeByte(0x2e);
829810 // DS segment override
830 if (prefixes.prefix_36) try self.writer.writeByte(0x36);
811 if (prefixes.prefix_36) try self.bw.writeByte(0x36);
831812 // ES segment override
832 if (prefixes.prefix_26) try self.writer.writeByte(0x26);
813 if (prefixes.prefix_26) try self.bw.writeByte(0x26);
833814 // FS segment override
834 if (prefixes.prefix_64) try self.writer.writeByte(0x64);
815 if (prefixes.prefix_64) try self.bw.writeByte(0x64);
835816 // GS segment override
836 if (prefixes.prefix_65) try self.writer.writeByte(0x65);
817 if (prefixes.prefix_65) try self.bw.writeByte(0x65);
837818
838819 // Branch taken
839 if (prefixes.prefix_3e) try self.writer.writeByte(0x3e);
820 if (prefixes.prefix_3e) try self.bw.writeByte(0x3e);
840821
841822 // Operand size override
842 if (prefixes.prefix_66) try self.writer.writeByte(0x66);
823 if (prefixes.prefix_66) try self.bw.writeByte(0x66);
843824
844825 // Address size override
845 if (prefixes.prefix_67) try self.writer.writeByte(0x67);
826 if (prefixes.prefix_67) try self.bw.writeByte(0x67);
846827 }
847828 }
848829
849830 /// Use 16 bit operand size
850831 ///
851832 /// Note that this flag is overridden by REX.W, if both are present.
852 pub fn prefix16BitMode(self: Self) !void {
853 try self.writer.writeByte(0x66);
833 pub fn prefix16BitMode(self: Self) anyerror!void {
834 try self.bw.writeByte(0x66);
854835 }
855836
856837 /// Encodes a REX prefix byte given all the fields
......@@ -859,7 +840,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
859840 /// or one of reg, index, r/m, base, or opcode-reg might be extended.
860841 ///
861842 /// See struct `Rex` for a description of each field.
862 pub fn rex(self: Self, fields: Rex) !void {
843 pub fn rex(self: Self, fields: Rex) anyerror!void {
863844 if (!fields.present and !fields.isSet()) return;
864845
865846 var byte: u8 = 0b0100_0000;
......@@ -869,32 +850,32 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
869850 if (fields.x) byte |= 0b0010;
870851 if (fields.b) byte |= 0b0001;
871852
872 try self.writer.writeByte(byte);
853 try self.bw.writeByte(byte);
873854 }
874855
875856 /// Encodes a VEX prefix given all the fields
876857 ///
877858 /// See struct `Vex` for a description of each field.
878 pub fn vex(self: Self, fields: Vex) !void {
859 pub fn vex(self: Self, fields: Vex) anyerror!void {
879860 if (fields.is3Byte()) {
880 try self.writer.writeByte(0b1100_0100);
861 try self.bw.writeByte(0b1100_0100);
881862
882 try self.writer.writeByte(
863 try self.bw.writeByte(
883864 @as(u8, ~@intFromBool(fields.r)) << 7 |
884865 @as(u8, ~@intFromBool(fields.x)) << 6 |
885866 @as(u8, ~@intFromBool(fields.b)) << 5 |
886867 @as(u8, @intFromEnum(fields.m)) << 0,
887868 );
888869
889 try self.writer.writeByte(
870 try self.bw.writeByte(
890871 @as(u8, @intFromBool(fields.w)) << 7 |
891872 @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 |
892873 @as(u8, @intFromBool(fields.l)) << 2 |
893874 @as(u8, @intFromEnum(fields.p)) << 0,
894875 );
895876 } else {
896 try self.writer.writeByte(0b1100_0101);
897 try self.writer.writeByte(
877 try self.bw.writeByte(0b1100_0101);
878 try self.bw.writeByte(
898879 @as(u8, ~@intFromBool(fields.r)) << 7 |
899880 @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 |
900881 @as(u8, @intFromBool(fields.l)) << 2 |
......@@ -908,8 +889,8 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
908889 // ------
909890
910891 /// Encodes a 1 byte opcode
911 pub fn opcode_1byte(self: Self, opcode: u8) !void {
912 try self.writer.writeByte(opcode);
892 pub fn opcode_1byte(self: Self, opcode: u8) anyerror!void {
893 try self.bw.writeByte(opcode);
913894 }
914895
915896 /// Encodes a 2 byte opcode
......@@ -917,8 +898,8 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
917898 /// e.g. IMUL has the opcode 0x0f 0xaf, so you use
918899 ///
919900 /// encoder.opcode_2byte(0x0f, 0xaf);
920 pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) !void {
921 try self.writer.writeAll(&.{ prefix, opcode });
901 pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) anyerror!void {
902 try self.bw.writeAll(&.{ prefix, opcode });
922903 }
923904
924905 /// Encodes a 3 byte opcode
......@@ -926,16 +907,16 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
926907 /// e.g. MOVSD has the opcode 0xf2 0x0f 0x10
927908 ///
928909 /// encoder.opcode_3byte(0xf2, 0x0f, 0x10);
929 pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) !void {
930 try self.writer.writeAll(&.{ prefix_1, prefix_2, opcode });
910 pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) anyerror!void {
911 try self.bw.writeAll(&.{ prefix_1, prefix_2, opcode });
931912 }
932913
933914 /// Encodes a 1 byte opcode with a reg field
934915 ///
935916 /// Remember to add a REX prefix byte if reg is extended!
936 pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) !void {
917 pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) anyerror!void {
937918 assert(opcode & 0b111 == 0);
938 try self.writer.writeByte(opcode | reg);
919 try self.bw.writeByte(opcode | reg);
939920 }
940921
941922 // ------
......@@ -945,8 +926,8 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
945926 /// Construct a ModR/M byte given all the fields
946927 ///
947928 /// Remember to add a REX prefix byte if reg or rm are extended!
948 pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) !void {
949 try self.writer.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm);
929 pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) anyerror!void {
930 try self.bw.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm);
950931 }
951932
952933 /// Construct a ModR/M byte using direct r/m addressing
......@@ -954,7 +935,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
954935 ///
955936 /// Note reg's effective address is always just reg for the ModR/M byte.
956937 /// Remember to add a REX prefix byte if reg or rm are extended!
957 pub fn modRm_direct(self: Self, reg_or_opx: u3, rm: u3) !void {
938 pub fn modRm_direct(self: Self, reg_or_opx: u3, rm: u3) anyerror!void {
958939 try self.modRm(0b11, reg_or_opx, rm);
959940 }
960941
......@@ -963,7 +944,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
963944 ///
964945 /// Note reg's effective address is always just reg for the ModR/M byte.
965946 /// Remember to add a REX prefix byte if reg or rm are extended!
966 pub fn modRm_indirectDisp0(self: Self, reg_or_opx: u3, rm: u3) !void {
947 pub fn modRm_indirectDisp0(self: Self, reg_or_opx: u3, rm: u3) anyerror!void {
967948 assert(rm != 4 and rm != 5);
968949 try self.modRm(0b00, reg_or_opx, rm);
969950 }
......@@ -973,7 +954,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
973954 ///
974955 /// Note reg's effective address is always just reg for the ModR/M byte.
975956 /// Remember to add a REX prefix byte if reg or rm are extended!
976 pub fn modRm_SIBDisp0(self: Self, reg_or_opx: u3) !void {
957 pub fn modRm_SIBDisp0(self: Self, reg_or_opx: u3) anyerror!void {
977958 try self.modRm(0b00, reg_or_opx, 0b100);
978959 }
979960
......@@ -982,7 +963,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
982963 ///
983964 /// Note reg's effective address is always just reg for the ModR/M byte.
984965 /// Remember to add a REX prefix byte if reg or rm are extended!
985 pub fn modRm_RIPDisp32(self: Self, reg_or_opx: u3) !void {
966 pub fn modRm_RIPDisp32(self: Self, reg_or_opx: u3) anyerror!void {
986967 try self.modRm(0b00, reg_or_opx, 0b101);
987968 }
988969
......@@ -991,7 +972,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
991972 ///
992973 /// Note reg's effective address is always just reg for the ModR/M byte.
993974 /// Remember to add a REX prefix byte if reg or rm are extended!
994 pub fn modRm_indirectDisp8(self: Self, reg_or_opx: u3, rm: u3) !void {
975 pub fn modRm_indirectDisp8(self: Self, reg_or_opx: u3, rm: u3) anyerror!void {
995976 assert(rm != 4);
996977 try self.modRm(0b01, reg_or_opx, rm);
997978 }
......@@ -1001,7 +982,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
1001982 ///
1002983 /// Note reg's effective address is always just reg for the ModR/M byte.
1003984 /// Remember to add a REX prefix byte if reg or rm are extended!
1004 pub fn modRm_SIBDisp8(self: Self, reg_or_opx: u3) !void {
985 pub fn modRm_SIBDisp8(self: Self, reg_or_opx: u3) anyerror!void {
1005986 try self.modRm(0b01, reg_or_opx, 0b100);
1006987 }
1007988
......@@ -1010,7 +991,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
1010991 ///
1011992 /// Note reg's effective address is always just reg for the ModR/M byte.
1012993 /// Remember to add a REX prefix byte if reg or rm are extended!
1013 pub fn modRm_indirectDisp32(self: Self, reg_or_opx: u3, rm: u3) !void {
994 pub fn modRm_indirectDisp32(self: Self, reg_or_opx: u3, rm: u3) anyerror!void {
1014995 assert(rm != 4);
1015996 try self.modRm(0b10, reg_or_opx, rm);
1016997 }
......@@ -1020,7 +1001,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10201001 ///
10211002 /// Note reg's effective address is always just reg for the ModR/M byte.
10221003 /// Remember to add a REX prefix byte if reg or rm are extended!
1023 pub fn modRm_SIBDisp32(self: Self, reg_or_opx: u3) !void {
1004 pub fn modRm_SIBDisp32(self: Self, reg_or_opx: u3) anyerror!void {
10241005 try self.modRm(0b10, reg_or_opx, 0b100);
10251006 }
10261007
......@@ -1031,15 +1012,15 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10311012 /// Construct a SIB byte given all the fields
10321013 ///
10331014 /// Remember to add a REX prefix byte if index or base are extended!
1034 pub fn sib(self: Self, scale: u2, index: u3, base: u3) !void {
1035 try self.writer.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base);
1015 pub fn sib(self: Self, scale: u2, index: u3, base: u3) anyerror!void {
1016 try self.bw.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base);
10361017 }
10371018
10381019 /// Construct a SIB byte with scale * index + base, no frills.
10391020 /// r/m effective address: [base + scale * index]
10401021 ///
10411022 /// Remember to add a REX prefix byte if index or base are extended!
1042 pub fn sib_scaleIndexBase(self: Self, scale: u2, index: u3, base: u3) !void {
1023 pub fn sib_scaleIndexBase(self: Self, scale: u2, index: u3, base: u3) anyerror!void {
10431024 assert(base != 5);
10441025
10451026 try self.sib(scale, index, base);
......@@ -1049,7 +1030,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10491030 /// r/m effective address: [scale * index + disp32]
10501031 ///
10511032 /// Remember to add a REX prefix byte if index or base are extended!
1052 pub fn sib_scaleIndexDisp32(self: Self, scale: u2, index: u3) !void {
1033 pub fn sib_scaleIndexDisp32(self: Self, scale: u2, index: u3) anyerror!void {
10531034 // scale is actually ignored
10541035 // index = 4 means no index if and only if we haven't extended the register
10551036 // TODO enforce this
......@@ -1061,7 +1042,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10611042 /// r/m effective address: [base]
10621043 ///
10631044 /// Remember to add a REX prefix byte if index or base are extended!
1064 pub fn sib_base(self: Self, base: u3) !void {
1045 pub fn sib_base(self: Self, base: u3) anyerror!void {
10651046 assert(base != 5);
10661047
10671048 // scale is actually ignored
......@@ -1073,7 +1054,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10731054 /// r/m effective address: [disp32]
10741055 ///
10751056 /// Remember to add a REX prefix byte if index or base are extended!
1076 pub fn sib_disp32(self: Self) !void {
1057 pub fn sib_disp32(self: Self) anyerror!void {
10771058 // scale is actually ignored
10781059 // index = 4 means no index
10791060 // base = 5 means no base, if mod == 0.
......@@ -1084,7 +1065,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10841065 /// r/m effective address: [base + scale * index + disp8]
10851066 ///
10861067 /// Remember to add a REX prefix byte if index or base are extended!
1087 pub fn sib_scaleIndexBaseDisp8(self: Self, scale: u2, index: u3, base: u3) !void {
1068 pub fn sib_scaleIndexBaseDisp8(self: Self, scale: u2, index: u3, base: u3) anyerror!void {
10881069 try self.sib(scale, index, base);
10891070 }
10901071
......@@ -1092,7 +1073,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
10921073 /// r/m effective address: [base + disp8]
10931074 ///
10941075 /// Remember to add a REX prefix byte if index or base are extended!
1095 pub fn sib_baseDisp8(self: Self, base: u3) !void {
1076 pub fn sib_baseDisp8(self: Self, base: u3) anyerror!void {
10961077 // scale is ignored
10971078 // index = 4 means no index
10981079 try self.sib(0, 4, base);
......@@ -1102,7 +1083,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
11021083 /// r/m effective address: [base + scale * index + disp32]
11031084 ///
11041085 /// Remember to add a REX prefix byte if index or base are extended!
1105 pub fn sib_scaleIndexBaseDisp32(self: Self, scale: u2, index: u3, base: u3) !void {
1086 pub fn sib_scaleIndexBaseDisp32(self: Self, scale: u2, index: u3, base: u3) anyerror!void {
11061087 try self.sib(scale, index, base);
11071088 }
11081089
......@@ -1110,7 +1091,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
11101091 /// r/m effective address: [base + disp32]
11111092 ///
11121093 /// Remember to add a REX prefix byte if index or base are extended!
1113 pub fn sib_baseDisp32(self: Self, base: u3) !void {
1094 pub fn sib_baseDisp32(self: Self, base: u3) anyerror!void {
11141095 // scale is ignored
11151096 // index = 4 means no index
11161097 try self.sib(0, 4, base);
......@@ -1123,43 +1104,43 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
11231104 /// Encode an 8 bit displacement
11241105 ///
11251106 /// It is sign-extended to 64 bits by the cpu.
1126 pub fn disp8(self: Self, disp: i8) !void {
1127 try self.writer.writeByte(@as(u8, @bitCast(disp)));
1107 pub fn disp8(self: Self, disp: i8) anyerror!void {
1108 try self.bw.writeByte(@as(u8, @bitCast(disp)));
11281109 }
11291110
11301111 /// Encode an 32 bit displacement
11311112 ///
11321113 /// It is sign-extended to 64 bits by the cpu.
1133 pub fn disp32(self: Self, disp: i32) !void {
1134 try self.writer.writeInt(i32, disp, .little);
1114 pub fn disp32(self: Self, disp: i32) anyerror!void {
1115 try self.bw.writeInt(i32, disp, .little);
11351116 }
11361117
11371118 /// Encode an 8 bit immediate
11381119 ///
11391120 /// It is sign-extended to 64 bits by the cpu.
1140 pub fn imm8(self: Self, imm: u8) !void {
1141 try self.writer.writeByte(imm);
1121 pub fn imm8(self: Self, imm: u8) anyerror!void {
1122 try self.bw.writeByte(imm);
11421123 }
11431124
11441125 /// Encode an 16 bit immediate
11451126 ///
11461127 /// It is sign-extended to 64 bits by the cpu.
1147 pub fn imm16(self: Self, imm: u16) !void {
1148 try self.writer.writeInt(u16, imm, .little);
1128 pub fn imm16(self: Self, imm: u16) anyerror!void {
1129 try self.bw.writeInt(u16, imm, .little);
11491130 }
11501131
11511132 /// Encode an 32 bit immediate
11521133 ///
11531134 /// It is sign-extended to 64 bits by the cpu.
1154 pub fn imm32(self: Self, imm: u32) !void {
1155 try self.writer.writeInt(u32, imm, .little);
1135 pub fn imm32(self: Self, imm: u32) anyerror!void {
1136 try self.bw.writeInt(u32, imm, .little);
11561137 }
11571138
11581139 /// Encode an 64 bit immediate
11591140 ///
11601141 /// It is sign-extended to 64 bits by the cpu.
1161 pub fn imm64(self: Self, imm: u64) !void {
1162 try self.writer.writeInt(u64, imm, .little);
1142 pub fn imm64(self: Self, imm: u64) anyerror!void {
1143 try self.bw.writeInt(u64, imm, .little);
11631144 }
11641145 };
11651146}
......@@ -2217,10 +2198,10 @@ const Assembler = struct {
22172198 };
22182199 }
22192200
2220 pub fn assemble(as: *Assembler, writer: anytype) !void {
2201 pub fn assemble(as: *Assembler, bw: *std.io.BufferedWriter) !void {
22212202 while (try as.next()) |parsed_inst| {
22222203 const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops);
2223 try inst.encode(writer, .{});
2204 try inst.encode(bw, .{});
22242205 }
22252206 }
22262207
src/codegen.zig+127-149
......@@ -225,14 +225,6 @@ pub fn generateLazyFunction(
225225 }
226226}
227227
228fn writeFloat(comptime F: type, f: F, target: *const std.Target, endian: std.builtin.Endian, code: []u8) void {
229 _ = target;
230 const bits = @typeInfo(F).float.bits;
231 const Int = @Type(.{ .int = .{ .signedness = .unsigned, .bits = bits } });
232 const int: Int = @bitCast(f);
233 mem.writeInt(Int, code[0..@divExact(bits, 8)], int, endian);
234}
235
236228pub fn generateLazySymbol(
237229 bin_file: *link.File,
238230 pt: Zcu.PerThread,
......@@ -256,7 +248,7 @@ pub fn generateLazySymbol(
256248 const target = &comp.root_mod.resolved_target.result;
257249 const endian = target.cpu.arch.endian();
258250
259 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
251 log.debug("generateLazySymbol: kind = {s}, ty = {f}", .{
260252 @tagName(lazy_sym.kind),
261253 Type.fromInterned(lazy_sym.ty).fmt(pt),
262254 });
......@@ -296,7 +288,7 @@ pub fn generateLazySymbol(
296288 code.appendAssumeCapacity(0);
297289 }
298290 } else {
299 return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {}", .{
291 return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {f}", .{
300292 @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt),
301293 });
302294 }
......@@ -321,19 +313,31 @@ pub fn generateSymbol(
321313 const tracy = trace(@src());
322314 defer tracy.end();
323315
316 var aw: std.io.AllocatingWriter = undefined;
317 const bw = aw.fromArrayList(pt.zcu.gpa, code);
318 defer code.* = aw.toArrayList();
319 return @errorCast(generateSymbolInner(bin_file, pt, src_loc, val, bw, reloc_parent));
320}
321pub fn generateSymbolInner(
322 bin_file: *link.File,
323 pt: Zcu.PerThread,
324 src_loc: Zcu.LazySrcLoc,
325 val: Value,
326 bw: *std.io.BufferedWriter,
327 reloc_parent: link.File.RelocInfo.Parent,
328) anyerror!void {
324329 const zcu = pt.zcu;
325 const gpa = zcu.gpa;
326330 const ip = &zcu.intern_pool;
327331 const ty = val.typeOf(zcu);
328332
329333 const target = zcu.getTarget();
330334 const endian = target.cpu.arch.endian();
331335
332 log.debug("generateSymbol: val = {}", .{val.fmtValue(pt)});
336 log.debug("generateSymbol: val = {f}", .{val.fmtValue(pt)});
333337
334338 if (val.isUndefDeep(zcu)) {
335339 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
336 try code.appendNTimes(gpa, 0xaa, abi_size);
340 try bw.splatByteAll(0xaa, abi_size);
337341 return;
338342 }
339343
......@@ -363,7 +367,7 @@ pub fn generateSymbol(
363367 .null => unreachable, // non-runtime value
364368 .@"unreachable" => unreachable, // non-runtime value
365369 .empty_tuple => return,
366 .false, .true => try code.append(gpa, switch (simple_value) {
370 .false, .true => try bw.writeByte(switch (simple_value) {
367371 .false => 0,
368372 .true => 1,
369373 else => unreachable,
......@@ -379,11 +383,12 @@ pub fn generateSymbol(
379383 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
380384 var space: Value.BigIntSpace = undefined;
381385 const int_val = val.toBigInt(&space, zcu);
382 int_val.writeTwosComplement(try code.addManyAsSlice(gpa, abi_size), endian);
386 int_val.writeTwosComplement((try bw.writableSlice(abi_size))[0..abi_size], endian);
387 bw.advance(abi_size);
383388 },
384389 .err => |err| {
385390 const int = try pt.getErrorValue(err.name);
386 try code.writer(gpa).writeInt(u16, @intCast(int), endian);
391 try bw.writeInt(u16, @intCast(int), endian);
387392 },
388393 .error_union => |error_union| {
389394 const payload_ty = ty.errorUnionPayload(zcu);
......@@ -393,7 +398,7 @@ pub fn generateSymbol(
393398 };
394399
395400 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
396 try code.writer(gpa).writeInt(u16, err_val, endian);
401 try bw.writeInt(u16, err_val, endian);
397402 return;
398403 }
399404
......@@ -403,57 +408,49 @@ pub fn generateSymbol(
403408
404409 // error value first when its type is larger than the error union's payload
405410 if (error_align.order(payload_align) == .gt) {
406 try code.writer(gpa).writeInt(u16, err_val, endian);
411 try bw.writeInt(u16, err_val, endian);
407412 }
408413
409414 // emit payload part of the error union
410415 {
411 const begin = code.items.len;
412 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
416 const begin = bw.count;
417 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(switch (error_union.val) {
413418 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
414419 .payload => |payload| payload,
415 }), code, reloc_parent);
416 const unpadded_end = code.items.len - begin;
420 }), bw, reloc_parent);
421 const unpadded_end = bw.count - begin;
417422 const padded_end = abi_align.forward(unpadded_end);
418 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
419
420 if (padding > 0) {
421 try code.appendNTimes(gpa, 0, padding);
422 }
423 try bw.splatByteAll(0, math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow);
423424 }
424425
425426 // Payload size is larger than error set, so emit our error set last
426427 if (error_align.compare(.lte, payload_align)) {
427 const begin = code.items.len;
428 try code.writer(gpa).writeInt(u16, err_val, endian);
429 const unpadded_end = code.items.len - begin;
428 const begin = bw.count;
429 try bw.writeInt(u16, err_val, endian);
430 const unpadded_end = bw.count - begin;
430431 const padded_end = abi_align.forward(unpadded_end);
431 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
432
433 if (padding > 0) {
434 try code.appendNTimes(gpa, 0, padding);
435 }
432 try bw.splatByteAll(0, math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow);
436433 }
437434 },
438435 .enum_tag => |enum_tag| {
439436 const int_tag_ty = ty.intTagType(zcu);
440 try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent);
437 try generateSymbolInner(bin_file, pt, src_loc, try pt.getCoerced(.fromInterned(enum_tag.int), int_tag_ty), bw, reloc_parent);
441438 },
442439 .float => |float| switch (float.storage) {
443 .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(gpa, 2)),
444 .f32 => |f32_val| writeFloat(f32, f32_val, target, endian, try code.addManyAsArray(gpa, 4)),
445 .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(gpa, 8)),
440 .f16 => |f16_val| try bw.writeInt(u16, @bitCast(f16_val), endian),
441 .f32 => |f32_val| try bw.writeInt(u32, @bitCast(f32_val), endian),
442 .f64 => |f64_val| try bw.writeInt(u64, @bitCast(f64_val), endian),
446443 .f80 => |f80_val| {
447 writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(gpa, 10));
444 try bw.writeInt(u80, @bitCast(f80_val), endian);
448445 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
449 try code.appendNTimes(gpa, 0, abi_size - 10);
446 try bw.splatByteAll(0, abi_size - 10);
450447 },
451 .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(gpa, 16)),
448 .f128 => |f128_val| try bw.writeInt(u128, @bitCast(f128_val), endian),
452449 },
453 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
450 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), bw, reloc_parent, 0),
454451 .slice => |slice| {
455 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent);
456 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent);
452 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(slice.ptr), bw, reloc_parent);
453 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(slice.len), bw, reloc_parent);
457454 },
458455 .opt => {
459456 const payload_type = ty.optionalChild(zcu);
......@@ -462,44 +459,44 @@ pub fn generateSymbol(
462459
463460 if (ty.optionalReprIsPayload(zcu)) {
464461 if (payload_val) |value| {
465 try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
462 try generateSymbolInner(bin_file, pt, src_loc, value, bw, reloc_parent);
466463 } else {
467 try code.appendNTimes(gpa, 0, abi_size);
464 try bw.splatByteAll(0, abi_size);
468465 }
469466 } else {
470467 const padding = abi_size - (math.cast(usize, payload_type.abiSize(zcu)) orelse return error.Overflow) - 1;
471468 if (payload_type.hasRuntimeBits(zcu)) {
472 const value = payload_val orelse Value.fromInterned(try pt.intern(.{
469 const value: Value = payload_val orelse .fromInterned(try pt.intern(.{
473470 .undef = payload_type.toIntern(),
474471 }));
475 try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
472 try generateSymbolInner(bin_file, pt, src_loc, value, bw, reloc_parent);
476473 }
477 try code.writer(gpa).writeByte(@intFromBool(payload_val != null));
478 try code.appendNTimes(gpa, 0, padding);
474 try bw.writeByte(@intFromBool(payload_val != null));
475 try bw.splatByteAll(0, padding);
479476 }
480477 },
481478 .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {
482479 .array_type => |array_type| switch (aggregate.storage) {
483 .bytes => |bytes| try code.appendSlice(gpa, bytes.toSlice(array_type.lenIncludingSentinel(), ip)),
480 .bytes => |bytes| try bw.writeAll(bytes.toSlice(array_type.lenIncludingSentinel(), ip)),
484481 .elems, .repeated_elem => {
485482 var index: u64 = 0;
486483 while (index < array_type.lenIncludingSentinel()) : (index += 1) {
487 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
484 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(switch (aggregate.storage) {
488485 .bytes => unreachable,
489486 .elems => |elems| elems[@intCast(index)],
490487 .repeated_elem => |elem| if (index < array_type.len)
491488 elem
492489 else
493490 array_type.sentinel,
494 }), code, reloc_parent);
491 }), bw, reloc_parent);
495492 }
496493 },
497494 },
498495 .vector_type => |vector_type| {
499496 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
500497 if (vector_type.child == .bool_type) {
501 const bytes = try code.addManyAsSlice(gpa, abi_size);
502 @memset(bytes, 0xaa);
498 const buffer = (try bw.writableSlice(abi_size))[0..abi_size];
499 @memset(buffer, 0xaa);
503500 var index: usize = 0;
504501 const len = math.cast(usize, vector_type.len) orelse return error.Overflow;
505502 while (index < len) : (index += 1) {
......@@ -507,7 +504,7 @@ pub fn generateSymbol(
507504 .big => len - 1 - index,
508505 .little => index,
509506 };
510 const byte = &bytes[bit_index / 8];
507 const byte = &buffer[bit_index / 8];
511508 const mask = @as(u8, 1) << @truncate(bit_index);
512509 if (switch (switch (aggregate.storage) {
513510 .bytes => unreachable,
......@@ -535,31 +532,31 @@ pub fn generateSymbol(
535532 },
536533 }) byte.* |= mask else byte.* &= ~mask;
537534 }
535 bw.advance(abi_size);
538536 } else {
539537 switch (aggregate.storage) {
540 .bytes => |bytes| try code.appendSlice(gpa, bytes.toSlice(vector_type.len, ip)),
538 .bytes => |bytes| try bw.writeAll(bytes.toSlice(vector_type.len, ip)),
541539 .elems, .repeated_elem => {
542540 var index: u64 = 0;
543541 while (index < vector_type.len) : (index += 1) {
544 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
542 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(switch (aggregate.storage) {
545543 .bytes => unreachable,
546544 .elems => |elems| elems[
547545 math.cast(usize, index) orelse return error.Overflow
548546 ],
549547 .repeated_elem => |elem| elem,
550 }), code, reloc_parent);
548 }), bw, reloc_parent);
551549 }
552550 },
553551 }
554552
555 const padding = abi_size -
553 try bw.splatByteAll(0, abi_size -
556554 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse
557 return error.Overflow);
558 if (padding > 0) try code.appendNTimes(gpa, 0, padding);
555 return error.Overflow));
559556 }
560557 },
561558 .tuple_type => |tuple| {
562 const struct_begin = code.items.len;
559 const struct_begin = bw.count;
563560 for (
564561 tuple.types.get(ip),
565562 tuple.values.get(ip),
......@@ -577,17 +574,13 @@ pub fn generateSymbol(
577574 .repeated_elem => |elem| elem,
578575 };
579576
580 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
581 const unpadded_field_end = code.items.len - struct_begin;
577 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(field_val), bw, reloc_parent);
578 const unpadded_field_end = bw.count - struct_begin;
582579
583580 // Pad struct members if required
584581 const padded_field_end = ty.structFieldOffset(index + 1, zcu);
585 const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse
586 return error.Overflow;
587
588 if (padding > 0) {
589 try code.appendNTimes(gpa, 0, padding);
590 }
582 try bw.splatByteAll(0, math.cast(usize, padded_field_end - unpadded_field_end) orelse
583 return error.Overflow);
591584 }
592585 },
593586 .struct_type => {
......@@ -595,8 +588,9 @@ pub fn generateSymbol(
595588 switch (struct_type.layout) {
596589 .@"packed" => {
597590 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
598 const current_pos = code.items.len;
599 try code.appendNTimes(gpa, 0, abi_size);
591 const current_end, const current_count = .{ bw.end, bw.count };
592 const buffer = (try bw.writableSlice(abi_size))[0..abi_size];
593 @memset(buffer, 0);
600594 var bits: u16 = 0;
601595
602596 for (struct_type.field_types.get(ip), 0..) |field_ty, index| {
......@@ -616,22 +610,25 @@ pub fn generateSymbol(
616610 error.DivisionByZero => unreachable,
617611 error.UnexpectedRemainder => return error.RelocationNotByteAligned,
618612 };
619 code.items.len = current_pos + field_offset;
620 // TODO: code.lockPointers();
613 bw.end = current_end + field_offset;
614 bw.count = current_count + field_offset;
621615 defer {
622 assert(code.items.len == current_pos + field_offset + @divExact(target.ptrBitWidth(), 8));
623 // TODO: code.unlockPointers();
624 code.items.len = current_pos + abi_size;
616 const field_size = @divExact(target.ptrBitWidth(), 8);
617 assert(bw.end == current_end + field_offset + field_size);
618 assert(bw.count == current_count + field_offset + field_size);
619 bw.end = current_end;
620 bw.count = current_count;
625621 }
626 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
622 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(field_val), bw, reloc_parent);
627623 } else {
628 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
624 Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, buffer, bits) catch unreachable;
629625 }
630626 bits += @intCast(Type.fromInterned(field_ty).bitSize(zcu));
631627 }
628 bw.advance(abi_size);
632629 },
633630 .auto, .@"extern" => {
634 const struct_begin = code.items.len;
631 const struct_begin = bw.count;
635632 const field_types = struct_type.field_types.get(ip);
636633 const offsets = struct_type.offsets.get(ip);
637634
......@@ -649,24 +646,22 @@ pub fn generateSymbol(
649646 .repeated_elem => |elem| elem,
650647 };
651648
652 const padding = math.cast(
649 try bw.splatByteAll(0, math.cast(
653650 usize,
654 offsets[field_index] - (code.items.len - struct_begin),
655 ) orelse return error.Overflow;
656 if (padding > 0) try code.appendNTimes(gpa, 0, padding);
651 offsets[field_index] - (bw.count - struct_begin),
652 ) orelse return error.Overflow);
657653
658 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
654 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(field_val), bw, reloc_parent);
659655 }
660656
661657 const size = struct_type.sizeUnordered(ip);
662658 const alignment = struct_type.flagsUnordered(ip).alignment.toByteUnits().?;
663659
664 const padding = math.cast(
660 try bw.splatByteAll(0, math.cast(
665661 usize,
666662 std.mem.alignForward(u64, size, @max(alignment, 1)) -
667 (code.items.len - struct_begin),
668 ) orelse return error.Overflow;
669 if (padding > 0) try code.appendNTimes(gpa, 0, padding);
663 (bw.count - struct_begin),
664 ) orelse return error.Overflow);
670665 },
671666 }
672667 },
......@@ -676,38 +671,31 @@ pub fn generateSymbol(
676671 const layout = ty.unionGetLayout(zcu);
677672
678673 if (layout.payload_size == 0) {
679 return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
674 return generateSymbolInner(bin_file, pt, src_loc, .fromInterned(un.tag), bw, reloc_parent);
680675 }
681676
682677 // Check if we should store the tag first.
683678 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
684 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
679 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(un.tag), bw, reloc_parent);
685680 }
686681
687682 const union_obj = zcu.typeToUnion(ty).?;
688683 if (un.tag != .none) {
689 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
684 const field_index = ty.unionTagFieldIndex(.fromInterned(un.tag), zcu).?;
690685 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
691686 if (!field_ty.hasRuntimeBits(zcu)) {
692 try code.appendNTimes(gpa, 0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
687 try bw.splatByteAll(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
693688 } else {
694 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
695
696 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
697 if (padding > 0) {
698 try code.appendNTimes(gpa, 0, padding);
699 }
689 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(un.val), bw, reloc_parent);
690 try bw.splatByteAll(0, math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow);
700691 }
701692 } else {
702 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
693 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(un.val), bw, reloc_parent);
703694 }
704695
705696 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
706 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
707
708 if (layout.padding > 0) {
709 try code.appendNTimes(gpa, 0, layout.padding);
710 }
697 try generateSymbolInner(bin_file, pt, src_loc, .fromInterned(un.tag), bw, reloc_parent);
698 try bw.splatByteAll(0, layout.padding);
711699 }
712700 },
713701 .memoized_call => unreachable,
......@@ -719,32 +707,32 @@ fn lowerPtr(
719707 pt: Zcu.PerThread,
720708 src_loc: Zcu.LazySrcLoc,
721709 ptr_val: InternPool.Index,
722 code: *std.ArrayListUnmanaged(u8),
710 bw: *std.io.BufferedWriter,
723711 reloc_parent: link.File.RelocInfo.Parent,
724712 prev_offset: u64,
725) GenerateSymbolError!void {
713) anyerror!void {
726714 const zcu = pt.zcu;
727715 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
728716 const offset: u64 = prev_offset + ptr.byte_offset;
729717 return switch (ptr.base_addr) {
730 .nav => |nav| try lowerNavRef(bin_file, pt, nav, code, reloc_parent, offset),
731 .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, code, reloc_parent, offset),
732 .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, reloc_parent),
718 .nav => |nav| try lowerNavRef(bin_file, pt, nav, bw, reloc_parent, offset),
719 .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, bw, reloc_parent, offset),
720 .int => try generateSymbolInner(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), bw, reloc_parent),
733721 .eu_payload => |eu_ptr| try lowerPtr(
734722 bin_file,
735723 pt,
736724 src_loc,
737725 eu_ptr,
738 code,
726 bw,
739727 reloc_parent,
740728 offset + errUnionPayloadOffset(
741729 Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu),
742730 zcu,
743731 ),
744732 ),
745 .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, src_loc, opt_ptr, code, reloc_parent, offset),
733 .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, src_loc, opt_ptr, bw, reloc_parent, offset),
746734 .field => |field| {
747 const base_ptr = Value.fromInterned(field.base);
735 const base_ptr: Value = .fromInterned(field.base);
748736 const base_ty = base_ptr.typeOf(zcu).childType(zcu);
749737 const field_off: u64 = switch (base_ty.zigTypeTag(zcu)) {
750738 .pointer => off: {
......@@ -761,7 +749,7 @@ fn lowerPtr(
761749 },
762750 else => unreachable,
763751 };
764 return lowerPtr(bin_file, pt, src_loc, field.base, code, reloc_parent, offset + field_off);
752 return lowerPtr(bin_file, pt, src_loc, field.base, bw, reloc_parent, offset + field_off);
765753 },
766754 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
767755 };
......@@ -772,12 +760,11 @@ fn lowerUavRef(
772760 pt: Zcu.PerThread,
773761 src_loc: Zcu.LazySrcLoc,
774762 uav: InternPool.Key.Ptr.BaseAddr.Uav,
775 code: *std.ArrayListUnmanaged(u8),
763 bw: *std.io.BufferedWriter,
776764 reloc_parent: link.File.RelocInfo.Parent,
777765 offset: u64,
778) GenerateSymbolError!void {
766) anyerror!void {
779767 const zcu = pt.zcu;
780 const gpa = zcu.gpa;
781768 const ip = &zcu.intern_pool;
782769 const comp = lf.comp;
783770 const target = &comp.root_mod.resolved_target.result;
......@@ -786,13 +773,9 @@ fn lowerUavRef(
786773 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));
787774 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
788775
789 log.debug("lowerUavRef: ty = {}", .{uav_ty.fmt(pt)});
790 try code.ensureUnusedCapacity(gpa, ptr_width_bytes);
776 log.debug("lowerUavRef: ty = {f}", .{uav_ty.fmt(pt)});
791777
792 if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {
793 code.appendNTimesAssumeCapacity(0xaa, ptr_width_bytes);
794 return;
795 }
778 if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) return bw.splatByteAll(0xaa, ptr_width_bytes);
796779
797780 switch (lf.tag) {
798781 .c => unreachable,
......@@ -801,9 +784,8 @@ fn lowerUavRef(
801784 dev.check(link.File.Tag.wasm.devFeature());
802785 const wasm = lf.cast(.wasm).?;
803786 assert(reloc_parent == .none);
804 try wasm.addUavReloc(code.items.len, uav.val, uav.orig_ty, @intCast(offset));
805 code.appendNTimesAssumeCapacity(0, ptr_width_bytes);
806 return;
787 try wasm.addUavReloc(bw.count, uav.val, uav.orig_ty, @intCast(offset));
788 return bw.splatByteAll(0, ptr_width_bytes);
807789 },
808790 else => {},
809791 }
......@@ -816,14 +798,14 @@ fn lowerUavRef(
816798
817799 const vaddr = try lf.getUavVAddr(uav_val, .{
818800 .parent = reloc_parent,
819 .offset = code.items.len,
801 .offset = bw.count,
820802 .addend = @intCast(offset),
821803 });
822804 const endian = target.cpu.arch.endian();
823805 switch (ptr_width_bytes) {
824 2 => mem.writeInt(u16, code.addManyAsArrayAssumeCapacity(2), @intCast(vaddr), endian),
825 4 => mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), @intCast(vaddr), endian),
826 8 => mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), vaddr, endian),
806 2 => try bw.writeInt(u16, @intCast(vaddr), endian),
807 4 => try bw.writeInt(u32, @intCast(vaddr), endian),
808 8 => try bw.writeInt(u64, vaddr, endian),
827809 else => unreachable,
828810 }
829811}
......@@ -832,10 +814,10 @@ fn lowerNavRef(
832814 lf: *link.File,
833815 pt: Zcu.PerThread,
834816 nav_index: InternPool.Nav.Index,
835 code: *std.ArrayListUnmanaged(u8),
817 bw: *std.io.BufferedWriter,
836818 reloc_parent: link.File.RelocInfo.Parent,
837819 offset: u64,
838) GenerateSymbolError!void {
820) anyerror!void {
839821 const zcu = pt.zcu;
840822 const gpa = zcu.gpa;
841823 const ip = &zcu.intern_pool;
......@@ -845,12 +827,9 @@ fn lowerNavRef(
845827 const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
846828 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
847829
848 try code.ensureUnusedCapacity(gpa, ptr_width_bytes);
830 log.debug("lowerNavRef: ty = {f}", .{nav_ty.fmt(pt)});
849831
850 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
851 code.appendNTimesAssumeCapacity(0xaa, ptr_width_bytes);
852 return;
853 }
832 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) return bw.splatByteAll(0xaa, ptr_width_bytes);
854833
855834 switch (lf.tag) {
856835 .c => unreachable,
......@@ -867,13 +846,13 @@ fn lowerNavRef(
867846 } else {
868847 try wasm.func_table_fixups.append(gpa, .{
869848 .table_index = @enumFromInt(gop.index),
870 .offset = @intCast(code.items.len),
849 .offset = @intCast(bw.count),
871850 });
872851 }
873852 } else {
874853 if (is_obj) {
875854 try wasm.out_relocs.append(gpa, .{
876 .offset = @intCast(code.items.len),
855 .offset = @intCast(bw.count),
877856 .pointee = .{ .symbol_index = try wasm.navSymbolIndex(nav_index) },
878857 .tag = if (ptr_width_bytes == 4) .memory_addr_i32 else .memory_addr_i64,
879858 .addend = @intCast(offset),
......@@ -882,27 +861,26 @@ fn lowerNavRef(
882861 try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1);
883862 wasm.nav_fixups.appendAssumeCapacity(.{
884863 .navs_exe_index = try wasm.refNavExe(nav_index),
885 .offset = @intCast(code.items.len),
864 .offset = @intCast(bw.count),
886865 .addend = @intCast(offset),
887866 });
888867 }
889868 }
890 code.appendNTimesAssumeCapacity(0, ptr_width_bytes);
891 return;
869 return bw.splatByteAll(0, ptr_width_bytes);
892870 },
893871 else => {},
894872 }
895873
896874 const vaddr = lf.getNavVAddr(pt, nav_index, .{
897875 .parent = reloc_parent,
898 .offset = code.items.len,
876 .offset = bw.count,
899877 .addend = @intCast(offset),
900878 }) catch @panic("TODO rework getNavVAddr");
901879 const endian = target.cpu.arch.endian();
902880 switch (ptr_width_bytes) {
903 2 => mem.writeInt(u16, code.addManyAsArrayAssumeCapacity(2), @intCast(vaddr), endian),
904 4 => mem.writeInt(u32, code.addManyAsArrayAssumeCapacity(4), @intCast(vaddr), endian),
905 8 => mem.writeInt(u64, code.addManyAsArrayAssumeCapacity(8), vaddr, endian),
881 2 => try bw.writeInt(u16, @intCast(vaddr), endian),
882 4 => try bw.writeInt(u32, @intCast(vaddr), endian),
883 8 => try bw.writeInt(u64, vaddr, endian),
906884 else => unreachable,
907885 }
908886}
......@@ -1084,7 +1062,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
10841062 const ip = &zcu.intern_pool;
10851063 const ty = val.typeOf(zcu);
10861064
1087 log.debug("lowerValue(@as({}, {}))", .{ ty.fmt(pt), val.fmtValue(pt) });
1065 log.debug("lowerValue(@as({f}, {f}))", .{ ty.fmt(pt), val.fmtValue(pt) });
10881066
10891067 if (val.isUndef(zcu)) return .undef;
10901068
src/codegen/llvm.zig+14-12
......@@ -746,12 +746,14 @@ pub const Object = struct {
746746 try wip.finish();
747747 }
748748
749 fn genModuleLevelAssembly(object: *Object) !void {
750 const writer = object.builder.setModuleAsm();
749 fn genModuleLevelAssembly(object: *Object) Allocator.Error!void {
750 var aw: std.io.AllocatingWriter = undefined;
751 const bw = object.builder.setModuleAsm(&aw);
752 errdefer aw.deinit();
751753 for (object.pt.zcu.global_assembly.values()) |assembly| {
752 try writer.print("{s}\n", .{assembly});
754 bw.print("{s}\n", .{assembly}) catch |err| return @errorCast(err);
753755 }
754 try object.builder.finishModuleAsm();
756 try object.builder.finishModuleAsm(&aw);
755757 }
756758
757759 pub const EmitOptions = struct {
......@@ -939,7 +941,7 @@ pub const Object = struct {
939941 if (std.mem.eql(u8, path, "-")) {
940942 o.builder.dump();
941943 } else {
942 _ = try o.builder.printToFile(path);
944 _ = o.builder.printToFile(path);
943945 }
944946 }
945947
......@@ -2677,9 +2679,9 @@ pub const Object = struct {
26772679
26782680 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
26792681 var aw: std.io.AllocatingWriter = undefined;
2680 const bw = aw.init(o.gpa);
2682 aw.init(o.gpa);
26812683 defer aw.deinit();
2682 try ty.print(bw, o.pt);
2684 ty.print(&aw.buffered_writer, o.pt) catch |err| return @errorCast(err);
26832685 return aw.toOwnedSliceSentinel(0);
26842686 }
26852687
......@@ -4479,7 +4481,7 @@ pub const Object = struct {
44794481 const target = &zcu.root_mod.resolved_target.result;
44804482 const function_index = try o.builder.addFunction(
44814483 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
4482 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{enum_type.name.fmt(ip)}),
4484 try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_type.name.fmt(ip)}),
44834485 toLlvmAddressSpace(.generic, target),
44844486 );
44854487
......@@ -4630,7 +4632,7 @@ pub const NavGen = struct {
46304632 if (zcu.getTarget().cpu.arch.isWasm() and ty.zigTypeTag(zcu) == .@"fn") {
46314633 if (lib_name.toSlice(ip)) |lib_name_slice| {
46324634 if (!std.mem.eql(u8, lib_name_slice, "c")) {
4633 break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ nav.name.fmt(ip), lib_name_slice });
4635 break :decl_name try o.builder.strtabStringFmt("{f}|{s}", .{ nav.name.fmt(ip), lib_name_slice });
46344636 }
46354637 }
46364638 }
......@@ -7469,7 +7471,7 @@ pub const FuncGen = struct {
74697471 llvm_param_types[llvm_param_i] = llvm_elem_ty;
74707472 }
74717473
7472 try llvm_constraints.writer(self.gpa).print(",{d}", .{output_index});
7474 try llvm_constraints.print(self.gpa, ",{d}", .{output_index});
74737475
74747476 // In the case of indirect inputs, LLVM requires the callsite to have
74757477 // an elementtype(<ty>) attribute.
......@@ -7570,7 +7572,7 @@ pub const FuncGen = struct {
75707572 // we should validate the assembly in Sema; by now it is too late
75717573 return self.todo("unknown input or output name: '{s}'", .{name});
75727574 };
7573 try rendered_template.writer().print("{d}", .{index});
7575 try rendered_template.print("{d}", .{index});
75747576 if (byte == ':') {
75757577 try rendered_template.append(':');
75767578 modifier_start = i + 1;
......@@ -10377,7 +10379,7 @@ pub const FuncGen = struct {
1037710379 const target = &zcu.root_mod.resolved_target.result;
1037810380 const function_index = try o.builder.addFunction(
1037910381 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
10380 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{enum_type.name.fmt(ip)}),
10382 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_type.name.fmt(ip)}),
1038110383 toLlvmAddressSpace(.generic, target),
1038210384 );
1038310385
src/codegen/spirv.zig+9-9
......@@ -817,7 +817,7 @@ const NavGen = struct {
817817 const result_ty_id = try self.resolveType(ty, repr);
818818 const ip = &zcu.intern_pool;
819819
820 log.debug("lowering constant: ty = {}, val = {}, key = {s}", .{ ty.fmt(pt), val.fmtValue(pt), @tagName(ip.indexToKey(val.toIntern())) });
820 log.debug("lowering constant: ty = {f}, val = {f}, key = {s}", .{ ty.fmt(pt), val.fmtValue(pt), @tagName(ip.indexToKey(val.toIntern())) });
821821 if (val.isUndefDeep(zcu)) {
822822 return self.spv.constUndef(result_ty_id);
823823 }
......@@ -1147,7 +1147,7 @@ const NavGen = struct {
11471147 return result_ptr_id;
11481148 }
11491149
1150 return self.fail("cannot perform pointer cast: '{}' to '{}'", .{
1150 return self.fail("cannot perform pointer cast: '{f}' to '{f}'", .{
11511151 parent_ptr_ty.fmt(pt),
11521152 oac.new_ptr_ty.fmt(pt),
11531153 });
......@@ -1259,11 +1259,11 @@ const NavGen = struct {
12591259 }
12601260
12611261 // Turn a Zig type's name into a cache reference.
1262 fn resolveTypeName(self: *NavGen, ty: Type) ![]const u8 {
1263 var name = std.ArrayList(u8).init(self.gpa);
1264 defer name.deinit();
1265 try ty.print(name.writer(), self.pt);
1266 return try name.toOwnedSlice();
1262 fn resolveTypeName(self: *NavGen, ty: Type) Allocator.Error![]const u8 {
1263 var aw: std.io.AllocatingWriter = undefined;
1264 aw.init(self.gpa);
1265 ty.print(&aw.buffered_writer, self.pt) catch |err| return @errorCast(err);
1266 return aw.toOwnedSlice();
12671267 }
12681268
12691269 /// Create an integer type suitable for storing at least 'bits' bits.
......@@ -1462,7 +1462,7 @@ const NavGen = struct {
14621462 const pt = self.pt;
14631463 const zcu = pt.zcu;
14641464 const ip = &zcu.intern_pool;
1465 log.debug("resolveType: ty = {}", .{ty.fmt(pt)});
1465 log.debug("resolveType: ty = {f}", .{ty.fmt(pt)});
14661466 const target = self.spv.target;
14671467
14681468 const section = &self.spv.sections.types_globals_constants;
......@@ -3068,7 +3068,7 @@ const NavGen = struct {
30683068 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
30693069 try self.spv.addFunction(spv_decl_index, self.func);
30703070
3071 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{nav.fqn.fmt(ip)});
3071 try self.spv.debugNameFmt(initializer_id, "initializer of {f}", .{nav.fqn.fmt(ip)});
30723072
30733073 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
30743074 .id_result_type = ptr_ty_id,
src/codegen/spirv/spec.zig+3-8
......@@ -18,15 +18,10 @@ pub const IdResult = enum(Word) {
1818 none,
1919 _,
2020
21 pub fn format(
22 self: IdResult,
23 comptime _: []const u8,
24 _: std.fmt.FormatOptions,
25 writer: anytype,
26 ) @TypeOf(writer).Error!void {
21 pub fn format(self: IdResult, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void {
2722 switch (self) {
28 .none => try writer.writeAll("(none)"),
29 else => try writer.print("%{}", .{@intFromEnum(self)}),
23 .none => try bw.writeAll("(none)"),
24 else => try bw.print("%{}", .{@intFromEnum(self)}),
3025 }
3126 }
3227};
src/crash_report.zig+13-12
......@@ -80,18 +80,18 @@ fn dumpStatusReport() !void {
8080 var fba = std.heap.FixedBufferAllocator.init(&crash_heap);
8181 const allocator = fba.allocator();
8282
83 const stderr = std.fs.File.stderr.writer().unbuffered();
83 var stderr = std.fs.File.stderr().writer().unbuffered();
8484 const block: *Sema.Block = anal.block;
8585 const zcu = anal.sema.pt.zcu;
8686
8787 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse {
8888 const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool));
89 try stderr.print("Analyzing lost instruction in file '{}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)});
89 try stderr.print("Analyzing lost instruction in file '{f}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)});
9090 return;
9191 };
9292
9393 try stderr.writeAll("Analyzing ");
94 try stderr.print("Analyzing '{}'\n", .{file.path.fmt(zcu.comp)});
94 try stderr.print("Analyzing '{f}'\n", .{file.path.fmt(zcu.comp)});
9595
9696 print_zir.renderInstructionContext(
9797 allocator,
......@@ -100,14 +100,14 @@ fn dumpStatusReport() !void {
100100 file,
101101 src_base_node,
102102 6, // indent
103 stderr,
103 &stderr,
104104 ) catch |err| switch (err) {
105105 error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"),
106106 else => |e| return e,
107107 };
108108 try stderr.print(
109109 \\ For full context, use the command
110 \\ zig ast-check -t {}
110 \\ zig ast-check -t {f}
111111 \\
112112 \\
113113 , .{file.path.fmt(zcu.comp)});
......@@ -116,7 +116,7 @@ fn dumpStatusReport() !void {
116116 while (parent) |curr| {
117117 fba.reset();
118118 const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool));
119 try stderr.print(" in {}\n", .{cur_block_file.path.fmt(zcu.comp)});
119 try stderr.print(" in {f}\n", .{cur_block_file.path.fmt(zcu.comp)});
120120 _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse {
121121 try stderr.writeAll(" > [lost instruction; this should not happen]\n");
122122 parent = curr.parent;
......@@ -129,7 +129,7 @@ fn dumpStatusReport() !void {
129129 cur_block_file,
130130 cur_block_src_base_node,
131131 6, // indent
132 stderr,
132 &stderr,
133133 ) catch |err| switch (err) {
134134 error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"),
135135 else => |e| return e,
......@@ -139,7 +139,7 @@ fn dumpStatusReport() !void {
139139 parent = curr.parent;
140140 }
141141
142 try stderr.writeAll("\n");
142 try stderr.writeByte('\n');
143143}
144144
145145var crash_heap: [16 * 4096]u8 = undefined;
......@@ -268,7 +268,8 @@ const StackContext = union(enum) {
268268 debug.dumpCurrentStackTrace(ct.ret_addr);
269269 },
270270 .exception => |context| {
271 debug.dumpStackTraceFromBase(context);
271 var stderr = std.fs.File.stderr().writer().unbuffered();
272 debug.dumpStackTraceFromBase(context, &stderr);
272273 },
273274 .not_supported => {
274275 std.fs.File.stderr().writeAll("Stack trace not supported on this platform.\n") catch {};
......@@ -378,7 +379,7 @@ const PanicSwitch = struct {
378379
379380 state.recover_stage = .release_mutex;
380381
381 const stderr = std.fs.File.stderr().writer().unbuffered();
382 var stderr = std.fs.File.stderr().writer().unbuffered();
382383 if (builtin.single_threaded) {
383384 stderr.print("panic: ", .{}) catch goTo(releaseMutex, .{state});
384385 } else {
......@@ -405,7 +406,7 @@ const PanicSwitch = struct {
405406 recover(state, trace, stack, msg);
406407
407408 state.recover_stage = .release_mutex;
408 const stderr = std.fs.File.stderr().writer().unbuffered();
409 var stderr = std.fs.File.stderr().writer().unbuffered();
409410 stderr.writeAll("\nOriginal Error:\n") catch {};
410411 goTo(reportStack, .{state});
411412 }
......@@ -521,7 +522,7 @@ const PanicSwitch = struct {
521522 var stderr = std.fs.File.stderr().writer().unbuffered();
522523 stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {};
523524 stderr.writeAll(msg) catch {};
524 stderr.writeAll("\n") catch {};
525 stderr.writeByte('\n') catch {};
525526
526527 // If we succeed, restore all the way to dumping the stack.
527528 state.recover_verbosity = .message_and_stack;
src/fmt.zig+3-3
......@@ -89,7 +89,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
8989 fatal("cannot use --stdin with positional arguments", .{});
9090 }
9191
92 const source_code = std.zig.readSourceFileToEndAlloc(gpa, .stdin(), null) catch |err| {
92 const source_code = std.zig.readSourceFileToEndAlloc(gpa, .stdin(), 0) catch |err| {
9393 fatal("unable to read stdin: {}", .{err});
9494 };
9595 defer gpa.free(source_code);
......@@ -134,9 +134,9 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
134134 process.exit(2);
135135 }
136136 var aw: std.io.AllocatingWriter = undefined;
137 const bw = aw.init(gpa);
137 aw.init(gpa);
138138 defer aw.deinit();
139 try tree.render(gpa, bw, .{});
139 try tree.render(gpa, &aw.buffered_writer, .{});
140140 const formatted = aw.getWritten();
141141
142142 if (check_flag) {
src/libs/glibc.zig+24-33
......@@ -736,13 +736,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
736736 .lt => continue,
737737 .gt => {
738738 // TODO Expose via compile error mechanism instead of log.
739 log.warn("invalid target glibc version: {}", .{target_version});
739 log.warn("invalid target glibc version: {f}", .{target_version});
740740 return error.InvalidTargetGLibCVersion;
741741 },
742742 }
743743 } else blk: {
744744 const latest_index = metadata.all_versions.len - 1;
745 log.warn("zig cannot build new glibc version {}; providing instead {}", .{
745 log.warn("zig cannot build new glibc version {f}; providing instead {f}", .{
746746 target_version, metadata.all_versions[latest_index],
747747 });
748748 break :blk latest_index;
......@@ -752,9 +752,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
752752 var map_contents = std.ArrayList(u8).init(arena);
753753 for (metadata.all_versions[0 .. target_ver_index + 1]) |ver| {
754754 if (ver.patch == 0) {
755 try map_contents.writer().print("GLIBC_{d}.{d} {{ }};\n", .{ ver.major, ver.minor });
755 try map_contents.print("GLIBC_{d}.{d} {{ }};\n", .{ ver.major, ver.minor });
756756 } else {
757 try map_contents.writer().print("GLIBC_{d}.{d}.{d} {{ }};\n", .{ ver.major, ver.minor, ver.patch });
757 try map_contents.print("GLIBC_{d}.{d}.{d} {{ }};\n", .{ ver.major, ver.minor, ver.patch });
758758 }
759759 }
760760 try o_directory.handle.writeFile(.{ .sub_path = all_map_basename, .data = map_contents.items });
......@@ -773,7 +773,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
773773 try stubs_asm.appendSlice(".text\n");
774774
775775 var sym_i: usize = 0;
776 var sym_name_buf = std.ArrayList(u8).init(arena);
777776 var opt_symbol_name: ?[]const u8 = null;
778777 var versions_buffer: [32]u8 = undefined;
779778 var versions_len: usize = undefined;
......@@ -794,24 +793,20 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
794793 // twice, which causes a "duplicate symbol" assembler error.
795794 var versions_written = std.AutoArrayHashMap(Version, void).init(arena);
796795
797 var inc_fbs = std.io.fixedBufferStream(metadata.inclusions);
798 var inc_reader = inc_fbs.reader();
796 var inc_br: std.io.BufferedReader = undefined;
797 inc_br.initFixed(metadata.inclusions);
799798
800 const fn_inclusions_len = try inc_reader.readInt(u16, .little);
799 const fn_inclusions_len = try inc_br.takeInt(u16, .little);
801800
802801 while (sym_i < fn_inclusions_len) : (sym_i += 1) {
803802 const sym_name = opt_symbol_name orelse n: {
804 sym_name_buf.clearRetainingCapacity();
805 try inc_reader.streamUntilDelimiter(sym_name_buf.writer(), 0, null);
806
807 opt_symbol_name = sym_name_buf.items;
803 opt_symbol_name = try inc_br.takeSentinel(0);
808804 versions_buffer = undefined;
809805 versions_len = 0;
810
811 break :n sym_name_buf.items;
806 break :n opt_symbol_name.?;
812807 };
813 const targets = try std.leb.readUleb128(u64, inc_reader);
814 var lib_index = try inc_reader.readByte();
808 const targets = try inc_br.takeLeb128(u64);
809 var lib_index = try inc_br.takeByte();
815810
816811 const is_terminal = (lib_index & (1 << 7)) != 0;
817812 if (is_terminal) {
......@@ -825,7 +820,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
825820 ((targets & (@as(u64, 1) << @as(u6, @intCast(target_targ_index)))) != 0);
826821
827822 while (true) {
828 const byte = try inc_reader.readByte();
823 const byte = try inc_br.takeByte();
829824 const last = (byte & 0b1000_0000) != 0;
830825 const ver_i = @as(u7, @truncate(byte));
831826 if (ok_lib_and_target and ver_i <= target_ver_index) {
......@@ -880,7 +875,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
880875 "{s}_{d}_{d}",
881876 .{ sym_name, ver.major, ver.minor },
882877 );
883 try stubs_asm.writer().print(
878 try stubs_asm.print(
884879 \\.balign {d}
885880 \\.globl {s}
886881 \\.type {s}, %function
......@@ -905,7 +900,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
905900 "{s}_{d}_{d}_{d}",
906901 .{ sym_name, ver.major, ver.minor, ver.patch },
907902 );
908 try stubs_asm.writer().print(
903 try stubs_asm.print(
909904 \\.balign {d}
910905 \\.globl {s}
911906 \\.type {s}, %function
......@@ -950,7 +945,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
950945 // versions where the symbol didn't exist. We only care about modern glibc versions, so use
951946 // a strong reference.
952947 if (std.mem.eql(u8, lib.name, "c")) {
953 try stubs_asm.writer().print(
948 try stubs_asm.print(
954949 \\.balign {d}
955950 \\.globl _IO_stdin_used
956951 \\{s} _IO_stdin_used
......@@ -963,7 +958,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
963958
964959 try stubs_asm.appendSlice(".data\n");
965960
966 const obj_inclusions_len = try inc_reader.readInt(u16, .little);
961 const obj_inclusions_len = try inc_br.takeInt(u16, .little);
967962
968963 var sizes = try arena.alloc(u16, metadata.all_versions.len);
969964
......@@ -973,18 +968,14 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
973968 versions_len = undefined;
974969 while (sym_i < obj_inclusions_len) : (sym_i += 1) {
975970 const sym_name = opt_symbol_name orelse n: {
976 sym_name_buf.clearRetainingCapacity();
977 try inc_reader.streamUntilDelimiter(sym_name_buf.writer(), 0, null);
978
979 opt_symbol_name = sym_name_buf.items;
971 opt_symbol_name = try inc_br.takeSentinel(0);
980972 versions_buffer = undefined;
981973 versions_len = 0;
982
983 break :n sym_name_buf.items;
974 break :n opt_symbol_name.?;
984975 };
985 const targets = try std.leb.readUleb128(u64, inc_reader);
986 const size = try std.leb.readUleb128(u16, inc_reader);
987 var lib_index = try inc_reader.readByte();
976 const targets = try inc_br.takeLeb128(u64);
977 const size = try inc_br.takeLeb128(u16);
978 var lib_index = try inc_br.takeByte();
988979
989980 const is_terminal = (lib_index & (1 << 7)) != 0;
990981 if (is_terminal) {
......@@ -998,7 +989,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
998989 ((targets & (@as(u64, 1) << @as(u6, @intCast(target_targ_index)))) != 0);
999990
1000991 while (true) {
1001 const byte = try inc_reader.readByte();
992 const byte = try inc_br.takeByte();
1002993 const last = (byte & 0b1000_0000) != 0;
1003994 const ver_i = @as(u7, @truncate(byte));
1004995 if (ok_lib_and_target and ver_i <= target_ver_index) {
......@@ -1055,7 +1046,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
10551046 "{s}_{d}_{d}",
10561047 .{ sym_name, ver.major, ver.minor },
10571048 );
1058 try stubs_asm.writer().print(
1049 try stubs_asm.print(
10591050 \\.balign {d}
10601051 \\.globl {s}
10611052 \\.type {s}, %object
......@@ -1083,7 +1074,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
10831074 "{s}_{d}_{d}_{d}",
10841075 .{ sym_name, ver.major, ver.minor, ver.patch },
10851076 );
1086 try stubs_asm.writer().print(
1077 try stubs_asm.print(
10871078 \\.balign {d}
10881079 \\.globl {s}
10891080 \\.type {s}, %object
src/libs/mingw.zig+7-7
......@@ -401,7 +401,7 @@ fn findDef(
401401 };
402402
403403 var override_path: std.io.AllocatingWriter = undefined;
404 const override_path_writer = override_path.init(gpa);
404 override_path.init(gpa);
405405 defer override_path.deinit();
406406
407407 const s = path.sep_str;
......@@ -410,9 +410,9 @@ fn findDef(
410410 // Try the archtecture-specific path first.
411411 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "{s}" ++ s ++ "{s}.def";
412412 if (zig_lib_directory.path) |p| {
413 try override_path_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_path, lib_name });
413 try override_path.buffered_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_path, lib_name });
414414 } else {
415 try override_path_writer.print(fmt_path, .{ lib_path, lib_name });
415 try override_path.buffered_writer.print(fmt_path, .{ lib_path, lib_name });
416416 }
417417 if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| {
418418 return override_path.toOwnedSlice();
......@@ -427,9 +427,9 @@ fn findDef(
427427 override_path.clearRetainingCapacity();
428428 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def";
429429 if (zig_lib_directory.path) |p| {
430 try override_path_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_name });
430 try override_path.buffered_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_name });
431431 } else {
432 try override_path_writer.print(fmt_path, .{lib_name});
432 try override_path.buffered_writer.print(fmt_path, .{lib_name});
433433 }
434434 if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| {
435435 return override_path.toOwnedSlice();
......@@ -444,9 +444,9 @@ fn findDef(
444444 override_path.clearRetainingCapacity();
445445 const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def.in";
446446 if (zig_lib_directory.path) |p| {
447 try override_path_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_name });
447 try override_path.buffered_writer.print("{s}" ++ s ++ fmt_path, .{ p, lib_name });
448448 } else {
449 try override_path_writer.print(fmt_path, .{lib_name});
449 try override_path.buffered_writer.print(fmt_path, .{lib_name});
450450 }
451451 if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| {
452452 return override_path.toOwnedSlice();
src/libs/musl.zig+11-13
......@@ -115,7 +115,8 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
115115 var c_source_files = std.ArrayList(Compilation.CSourceFile).init(comp.gpa);
116116 defer c_source_files.deinit();
117117
118 var override_path = std.ArrayList(u8).init(comp.gpa);
118 var override_path: std.io.AllocatingWriter = undefined;
119 override_path.init(comp.gpa);
119120 defer override_path.deinit();
120121
121122 const s = path.sep_str;
......@@ -139,26 +140,23 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
139140 }
140141 if (!is_arch_specific) {
141142 // Look for an arch specific override.
142 override_path.shrinkRetainingCapacity(0);
143 try override_path.writer().print("{s}" ++ s ++ "{s}" ++ s ++ "{s}.s", .{
143 override_path.clearRetainingCapacity();
144 try override_path.buffered_writer.print("{s}" ++ s ++ "{s}" ++ s ++ "{s}.s", .{
144145 dirname, arch_name, noextbasename,
145146 });
146 if (source_table.contains(override_path.items))
147 continue;
147 if (source_table.contains(override_path.getWritten())) continue;
148148
149 override_path.shrinkRetainingCapacity(0);
150 try override_path.writer().print("{s}" ++ s ++ "{s}" ++ s ++ "{s}.S", .{
149 override_path.clearRetainingCapacity();
150 try override_path.buffered_writer.print("{s}" ++ s ++ "{s}" ++ s ++ "{s}.S", .{
151151 dirname, arch_name, noextbasename,
152152 });
153 if (source_table.contains(override_path.items))
154 continue;
153 if (source_table.contains(override_path.getWritten())) continue;
155154
156 override_path.shrinkRetainingCapacity(0);
157 try override_path.writer().print("{s}" ++ s ++ "{s}" ++ s ++ "{s}.c", .{
155 override_path.clearRetainingCapacity();
156 try override_path.buffered_writer.print("{s}" ++ s ++ "{s}" ++ s ++ "{s}.c", .{
158157 dirname, arch_name, noextbasename,
159158 });
160 if (source_table.contains(override_path.items))
161 continue;
159 if (source_table.contains(override_path.getWritten())) continue;
162160 }
163161
164162 var args = std.ArrayList([]const u8).init(arena);
src/link.zig+25-25
......@@ -323,7 +323,7 @@ pub const Diags = struct {
323323 const main_msg = try m;
324324 errdefer gpa.free(main_msg);
325325 try diags.msgs.ensureUnusedCapacity(gpa, 1);
326 const note = try std.fmt.allocPrint(gpa, "while parsing {}", .{path});
326 const note = try std.fmt.allocPrint(gpa, "while parsing {f}", .{path});
327327 errdefer gpa.free(note);
328328 const notes = try gpa.create([1]Msg);
329329 errdefer gpa.destroy(notes);
......@@ -838,7 +838,7 @@ pub const File = struct {
838838 const cached_pp_file_path = the_key.status.success.object_path;
839839 cached_pp_file_path.root_dir.handle.copyFile(cached_pp_file_path.sub_path, emit.root_dir.handle, emit.sub_path, .{}) catch |err| {
840840 const diags = &base.comp.link_diags;
841 return diags.fail("failed to copy '{'}' to '{'}': {s}", .{
841 return diags.fail("failed to copy '{f'}' to '{f'}': {s}", .{
842842 @as(Path, cached_pp_file_path), @as(Path, emit), @errorName(err),
843843 });
844844 };
......@@ -1351,7 +1351,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
13511351 .search_strategy = .paths_first,
13521352 }) catch |archive_err| switch (archive_err) {
13531353 error.LinkFailure => return, // error reported via diags
1354 else => |e| diags.addParseError(dso_path, "failed to parse archive {}: {s}", .{ archive_path, @errorName(e) }),
1354 else => |e| diags.addParseError(dso_path, "failed to parse archive {f}: {s}", .{ archive_path, @errorName(e) }),
13551355 };
13561356 },
13571357 error.LinkFailure => return, // error reported via diags
......@@ -1874,7 +1874,7 @@ pub fn resolveInputs(
18741874 )) |lib_result| {
18751875 switch (lib_result) {
18761876 .ok => {},
1877 .no_match => fatal("{}: file not found", .{pq.path}),
1877 .no_match => fatal("{f}: file not found", .{pq.path}),
18781878 }
18791879 }
18801880 continue;
......@@ -1928,10 +1928,10 @@ fn resolveLibInput(
19281928 .root_dir = lib_directory,
19291929 .sub_path = try std.fmt.allocPrint(arena, "lib{s}.tbd", .{lib_name}),
19301930 };
1931 try checked_paths.print(gpa, "\n {}", .{test_path});
1931 try checked_paths.print(gpa, "\n {f}", .{test_path});
19321932 var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
19331933 error.FileNotFound => break :tbd,
1934 else => |e| fatal("unable to search for tbd library '{}': {s}", .{ test_path, @errorName(e) }),
1934 else => |e| fatal("unable to search for tbd library '{f}': {s}", .{ test_path, @errorName(e) }),
19351935 };
19361936 errdefer file.close();
19371937 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
......@@ -1947,7 +1947,7 @@ fn resolveLibInput(
19471947 },
19481948 }),
19491949 };
1950 try checked_paths.print(gpa, "\n {}", .{test_path});
1950 try checked_paths.print(gpa, "\n {f}", .{test_path});
19511951 switch (try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, .{
19521952 .path = test_path,
19531953 .query = name_query.query,
......@@ -1964,10 +1964,10 @@ fn resolveLibInput(
19641964 .root_dir = lib_directory,
19651965 .sub_path = try std.fmt.allocPrint(arena, "lib{s}.so", .{lib_name}),
19661966 };
1967 try checked_paths.print(gpa, "\n {}", .{test_path});
1967 try checked_paths.print(gpa, "\n {f}", .{test_path});
19681968 var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
19691969 error.FileNotFound => break :so,
1970 else => |e| fatal("unable to search for so library '{}': {s}", .{
1970 else => |e| fatal("unable to search for so library '{f}': {s}", .{
19711971 test_path, @errorName(e),
19721972 }),
19731973 };
......@@ -1982,10 +1982,10 @@ fn resolveLibInput(
19821982 .root_dir = lib_directory,
19831983 .sub_path = try std.fmt.allocPrint(arena, "lib{s}.a", .{lib_name}),
19841984 };
1985 try checked_paths.print(gpa, "\n {}", .{test_path});
1985 try checked_paths.print(gpa, "\n {f}", .{test_path});
19861986 var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
19871987 error.FileNotFound => break :mingw,
1988 else => |e| fatal("unable to search for static library '{}': {s}", .{ test_path, @errorName(e) }),
1988 else => |e| fatal("unable to search for static library '{f}': {s}", .{ test_path, @errorName(e) }),
19891989 };
19901990 errdefer file.close();
19911991 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query);
......@@ -2037,7 +2037,7 @@ fn resolvePathInput(
20372037 .shared_library => return try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .dynamic, color),
20382038 .object => {
20392039 var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err|
2040 fatal("failed to open object {}: {s}", .{ pq.path, @errorName(err) });
2040 fatal("failed to open object {f}: {s}", .{ pq.path, @errorName(err) });
20412041 errdefer file.close();
20422042 try resolved_inputs.append(gpa, .{ .object = .{
20432043 .path = pq.path,
......@@ -2049,7 +2049,7 @@ fn resolvePathInput(
20492049 },
20502050 .res => {
20512051 var file = pq.path.root_dir.handle.openFile(pq.path.sub_path, .{}) catch |err|
2052 fatal("failed to open windows resource {}: {s}", .{ pq.path, @errorName(err) });
2052 fatal("failed to open windows resource {f}: {s}", .{ pq.path, @errorName(err) });
20532053 errdefer file.close();
20542054 try resolved_inputs.append(gpa, .{ .res = .{
20552055 .path = pq.path,
......@@ -2057,7 +2057,7 @@ fn resolvePathInput(
20572057 } });
20582058 return null;
20592059 },
2060 else => fatal("{}: unrecognized file extension", .{pq.path}),
2060 else => fatal("{f}: unrecognized file extension", .{pq.path}),
20612061 }
20622062}
20632063
......@@ -2086,13 +2086,13 @@ fn resolvePathInputLib(
20862086 }) {
20872087 var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
20882088 error.FileNotFound => return .no_match,
2089 else => |e| fatal("unable to search for {s} library '{'}': {s}", .{
2089 else => |e| fatal("unable to search for {s} library '{f'}': {s}", .{
20902090 @tagName(link_mode), test_path, @errorName(e),
20912091 }),
20922092 };
20932093 errdefer file.close();
20942094 try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len));
2095 const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{'}': {s}", .{
2095 const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f'}': {s}", .{
20962096 test_path, @errorName(err),
20972097 });
20982098 const buf = ld_script_bytes.items[0..n];
......@@ -2101,14 +2101,14 @@ fn resolvePathInputLib(
21012101 return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
21022102 }
21032103 const stat = file.stat() catch |err|
2104 fatal("failed to stat {}: {s}", .{ test_path, @errorName(err) });
2104 fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) });
21052105 const size = std.math.cast(u32, stat.size) orelse
2106 fatal("{}: linker script too big", .{test_path});
2106 fatal("{f}: linker script too big", .{test_path});
21072107 try ld_script_bytes.resize(gpa, size);
21082108 const buf2 = ld_script_bytes.items[n..];
21092109 const n2 = file.preadAll(buf2, n) catch |err|
2110 fatal("failed to read {}: {s}", .{ test_path, @errorName(err) });
2111 if (n2 != buf2.len) fatal("failed to read {}: unexpected end of file", .{test_path});
2110 fatal("failed to read {f}: {s}", .{ test_path, @errorName(err) });
2111 if (n2 != buf2.len) fatal("failed to read {f}: unexpected end of file", .{test_path});
21122112 var diags = Diags.init(gpa);
21132113 defer diags.deinit();
21142114 const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items);
......@@ -2128,7 +2128,7 @@ fn resolvePathInputLib(
21282128 }
21292129
21302130 var ld_script = ld_script_result catch |err|
2131 fatal("{}: failed to parse linker script: {s}", .{ test_path, @errorName(err) });
2131 fatal("{f}: failed to parse linker script: {s}", .{ test_path, @errorName(err) });
21322132 defer ld_script.deinit(gpa);
21332133
21342134 try unresolved_inputs.ensureUnusedCapacity(gpa, ld_script.args.len);
......@@ -2159,7 +2159,7 @@ fn resolvePathInputLib(
21592159
21602160 var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
21612161 error.FileNotFound => return .no_match,
2162 else => |e| fatal("unable to search for {s} library {}: {s}", .{
2162 else => |e| fatal("unable to search for {s} library {f}: {s}", .{
21632163 @tagName(link_mode), test_path, @errorName(e),
21642164 }),
21652165 };
......@@ -2192,19 +2192,19 @@ pub fn openDso(path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso
21922192
21932193pub fn openObjectInput(diags: *Diags, path: Path) error{LinkFailure}!Input {
21942194 return .{ .object = openObject(path, false, false) catch |err| {
2195 return diags.failParse(path, "failed to open {}: {s}", .{ path, @errorName(err) });
2195 return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) });
21962196 } };
21972197}
21982198
21992199pub fn openArchiveInput(diags: *Diags, path: Path, must_link: bool, hidden: bool) error{LinkFailure}!Input {
22002200 return .{ .archive = openObject(path, must_link, hidden) catch |err| {
2201 return diags.failParse(path, "failed to open {}: {s}", .{ path, @errorName(err) });
2201 return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) });
22022202 } };
22032203}
22042204
22052205pub fn openDsoInput(diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{LinkFailure}!Input {
22062206 return .{ .dso = openDso(path, needed, weak, reexport) catch |err| {
2207 return diags.failParse(path, "failed to open {}: {s}", .{ path, @errorName(err) });
2207 return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) });
22082208 } };
22092209}
22102210
src/link/Coff.zig+25-32
......@@ -1213,7 +1213,7 @@ fn updateLazySymbolAtom(
12131213 var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
12141214 defer code_buffer.deinit(gpa);
12151215
1216 const name = try allocPrint(gpa, "__lazy_{s}_{}", .{
1216 const name = try allocPrint(gpa, "__lazy_{s}_{f}", .{
12171217 @tagName(sym.kind),
12181218 Type.fromInterned(sym.ty).fmt(pt),
12191219 });
......@@ -1333,7 +1333,7 @@ fn updateNavCode(
13331333 const ip = &zcu.intern_pool;
13341334 const nav = ip.getNav(nav_index);
13351335
1336 log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
1336 log.debug("updateNavCode {f} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
13371337
13381338 const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
13391339 const required_alignment = switch (pt.navAlignment(nav_index)) {
......@@ -1361,7 +1361,7 @@ fn updateNavCode(
13611361 error.OutOfMemory => return error.OutOfMemory,
13621362 else => |e| return coff.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(e)}),
13631363 };
1364 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
1364 log.debug("growing {f} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
13651365 log.debug(" (required alignment 0x{x}", .{required_alignment});
13661366
13671367 if (vaddr != sym.value) {
......@@ -1389,7 +1389,7 @@ fn updateNavCode(
13891389 else => |e| return coff.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(e)}),
13901390 };
13911391 errdefer coff.freeAtom(atom_index);
1392 log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });
1392 log.debug("allocated atom for {f} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });
13931393 coff.getAtomPtr(atom_index).size = code_len;
13941394 sym.value = vaddr;
13951395
......@@ -1454,7 +1454,7 @@ pub fn updateExports(
14541454
14551455 for (export_indices) |export_idx| {
14561456 const exp = export_idx.ptr(zcu);
1457 log.debug("adding new export '{}'", .{exp.opts.name.fmt(&zcu.intern_pool)});
1457 log.debug("adding new export '{f}'", .{exp.opts.name.fmt(&zcu.intern_pool)});
14581458
14591459 if (exp.opts.section.toSlice(&zcu.intern_pool)) |section_name| {
14601460 if (!mem.eql(u8, section_name, ".text")) {
......@@ -1530,7 +1530,7 @@ pub fn deleteExport(
15301530 const gpa = coff.base.comp.gpa;
15311531 const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null };
15321532 const sym = coff.getSymbolPtr(sym_loc);
1533 log.debug("deleting export '{}'", .{name.fmt(&zcu.intern_pool)});
1533 log.debug("deleting export '{f}'", .{name.fmt(&zcu.intern_pool)});
15341534 assert(sym.storage_class == .EXTERNAL and sym.section_number != .UNDEFINED);
15351535 sym.* = .{
15361536 .name = [_]u8{0} ** 8,
......@@ -1748,7 +1748,7 @@ pub fn getNavVAddr(
17481748 const zcu = pt.zcu;
17491749 const ip = &zcu.intern_pool;
17501750 const nav = ip.getNav(nav_index);
1751 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1751 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
17521752 const sym_index = if (nav.getExtern(ip)) |e|
17531753 try coff.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip))
17541754 else
......@@ -2175,15 +2175,14 @@ fn writeDataDirectoriesHeaders(coff: *Coff) !void {
21752175fn writeHeader(coff: *Coff) !void {
21762176 const target = &coff.base.comp.root_mod.resolved_target.result;
21772177 const gpa = coff.base.comp.gpa;
2178 var buffer = std.ArrayList(u8).init(gpa);
2179 defer buffer.deinit();
2180 const writer = buffer.writer();
2178 var bw: std.io.BufferedWriter = undefined;
2179 bw.initFixed(try gpa.alloc(u8, coff.getSizeOfHeaders()));
2180 defer gpa.free(bw.buffer);
21812181
2182 try buffer.ensureTotalCapacity(coff.getSizeOfHeaders());
2183 writer.writeAll(&msdos_stub) catch unreachable;
2184 mem.writeInt(u32, buffer.items[0x3c..][0..4], msdos_stub.len, .little);
2182 bw.writeAll(&msdos_stub) catch unreachable;
2183 mem.writeInt(u32, bw.buffer[0x3c..][0..4], msdos_stub.len, .little);
21852184
2186 writer.writeAll("PE\x00\x00") catch unreachable;
2185 bw.writeAll("PE\x00\x00") catch unreachable;
21872186 var flags = coff_util.CoffHeaderFlags{
21882187 .EXECUTABLE_IMAGE = 1,
21892188 .DEBUG_STRIPPED = 1, // TODO
......@@ -2208,7 +2207,7 @@ fn writeHeader(coff: *Coff) !void {
22082207 .flags = flags,
22092208 };
22102209
2211 writer.writeAll(mem.asBytes(&coff_header)) catch unreachable;
2210 bw.writeAll(mem.asBytes(&coff_header)) catch unreachable;
22122211
22132212 const dll_flags: coff_util.DllFlags = .{
22142213 .HIGH_ENTROPY_VA = 1, // TODO do we want to permit non-PIE builds at all?
......@@ -2271,7 +2270,7 @@ fn writeHeader(coff: *Coff) !void {
22712270 .loader_flags = 0,
22722271 .number_of_rva_and_sizes = @intCast(coff.data_directories.len),
22732272 };
2274 writer.writeAll(mem.asBytes(&opt_header)) catch unreachable;
2273 bw.writeAll(mem.asBytes(&opt_header)) catch unreachable;
22752274 },
22762275 .p64 => {
22772276 var opt_header = coff_util.OptionalHeaderPE64{
......@@ -2305,11 +2304,12 @@ fn writeHeader(coff: *Coff) !void {
23052304 .loader_flags = 0,
23062305 .number_of_rva_and_sizes = @intCast(coff.data_directories.len),
23072306 };
2308 writer.writeAll(mem.asBytes(&opt_header)) catch unreachable;
2307 bw.writeAll(mem.asBytes(&opt_header)) catch unreachable;
23092308 },
23102309 }
23112310
2312 try coff.pwriteAll(buffer.items, 0);
2311 assert(bw.end == bw.buffer.len);
2312 try coff.pwriteAll(bw.buffer, 0);
23132313}
23142314
23152315pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
......@@ -2605,7 +2605,7 @@ fn logSymtab(coff: *Coff) void {
26052605 }
26062606
26072607 log.debug("GOT entries:", .{});
2608 log.debug("{}", .{coff.got_table});
2608 log.debug("{f}", .{coff.got_table});
26092609}
26102610
26112611fn logSections(coff: *Coff) void {
......@@ -2625,7 +2625,7 @@ fn logImportTables(coff: *const Coff) void {
26252625 log.debug("import tables:", .{});
26262626 for (coff.import_tables.keys(), 0..) |off, i| {
26272627 const itable = coff.import_tables.values()[i];
2628 log.debug("{}", .{itable.fmtDebug(.{
2628 log.debug("{f}", .{itable.fmtDebug(.{
26292629 .coff = coff,
26302630 .index = i,
26312631 .name_off = off,
......@@ -3066,27 +3066,20 @@ const ImportTable = struct {
30663066 ctx: Context,
30673067 };
30683068
3069 fn format(itab: ImportTable, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
3069 fn format(itab: ImportTable, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
30703070 _ = itab;
3071 _ = bw;
30713072 _ = unused_format_string;
3072 _ = options;
3073 _ = writer;
30743073 @compileError("do not format ImportTable directly; use itab.fmtDebug()");
30753074 }
30763075
3077 fn format2(
3078 fmt_ctx: FormatContext,
3079 comptime unused_format_string: []const u8,
3080 options: fmt.FormatOptions,
3081 writer: anytype,
3082 ) @TypeOf(writer).Error!void {
3083 _ = options;
3076 fn format2(fmt_ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
30843077 comptime assert(unused_format_string.len == 0);
30853078 const lib_name = fmt_ctx.ctx.coff.temp_strtab.getAssumeExists(fmt_ctx.ctx.name_off);
30863079 const base_vaddr = getBaseAddress(fmt_ctx.ctx);
3087 try writer.print("IAT({s}.dll) @{x}:", .{ lib_name, base_vaddr });
3080 try bw.print("IAT({s}.dll) @{x}:", .{ lib_name, base_vaddr });
30883081 for (fmt_ctx.itab.entries.items, 0..) |entry, i| {
3089 try writer.print("\n {d}@{?x} => {s}", .{
3082 try bw.print("\n {d}@{?x} => {s}", .{
30903083 i,
30913084 fmt_ctx.itab.getImportAddress(entry, fmt_ctx.ctx),
30923085 fmt_ctx.ctx.coff.getSymbolName(entry),
src/link/Dwarf.zig+797-697
......@@ -132,7 +132,7 @@ const DebugInfo = struct {
132132 return AbbrevCode.decl_bytes + dwarf.sectionOffsetBytes();
133133 }
134134
135 fn declAbbrevCode(debug_info: *DebugInfo, unit: Unit.Index, entry: Entry.Index) !AbbrevCode {
135 fn declAbbrevCode(debug_info: *DebugInfo, unit: Unit.Index, entry: Entry.Index) anyerror!AbbrevCode {
136136 const dwarf: *Dwarf = @fieldParentPtr("debug_info", debug_info);
137137 const unit_ptr = debug_info.section.getUnit(unit);
138138 const entry_ptr = unit_ptr.getEntry(entry);
......@@ -142,8 +142,9 @@ const DebugInfo = struct {
142142 &abbrev_code_buf,
143143 debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
144144 ) != abbrev_code_buf.len) return error.InputOutput;
145 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
146 return @enumFromInt(std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable);
145 var abbrev_code_br: std.io.BufferedReader = undefined;
146 abbrev_code_br.initFixed(&abbrev_code_buf);
147 return @enumFromInt(abbrev_code_br.takeLeb128(@typeInfo(AbbrevCode).@"enum".tag_type) catch unreachable);
147148 }
148149
149150 const trailer_bytes = 1 + 1;
......@@ -226,7 +227,7 @@ const StringSection = struct {
226227 str_sec.section.deinit(gpa);
227228 }
228229
229 fn addString(str_sec: *StringSection, dwarf: *Dwarf, str: []const u8) UpdateError!Entry.Index {
230 fn addString(str_sec: *StringSection, dwarf: *Dwarf, str: []const u8) anyerror!Entry.Index {
230231 const gop = try str_sec.map.getOrPutAdapted(dwarf.gpa, str, Adapter{ .str_sec = str_sec });
231232 const entry: Entry.Index = @enumFromInt(gop.index);
232233 if (!gop.found_existing) {
......@@ -368,7 +369,7 @@ pub const Section = struct {
368369 return &sec.units.items[@intFromEnum(unit)];
369370 }
370371
371 fn resizeEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, len: u32) UpdateError!void {
372 fn resizeEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, len: u32) anyerror!void {
372373 const unit_ptr = sec.getUnit(unit);
373374 const entry_ptr = unit_ptr.getEntry(entry);
374375 if (len > 0) {
......@@ -389,13 +390,13 @@ pub const Section = struct {
389390 assert(entry_ptr.len == len);
390391 }
391392
392 fn replaceEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
393 fn replaceEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf, contents: []const u8) anyerror!void {
393394 try sec.resizeEntry(unit, entry, dwarf, @intCast(contents.len));
394395 const unit_ptr = sec.getUnit(unit);
395396 try unit_ptr.getEntry(entry).replace(unit_ptr, sec, dwarf, contents);
396397 }
397398
398 fn freeEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf) UpdateError!void {
399 fn freeEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf) anyerror!void {
399400 const unit_ptr = sec.getUnit(unit);
400401 const entry_ptr = unit_ptr.getEntry(entry);
401402 if (entry_ptr.len > 0) {
......@@ -648,35 +649,36 @@ const Unit = struct {
648649 assert(len >= unit.trailer_len);
649650 if (sec == &dwarf.debug_line.section) {
650651 var buf: [1 + uleb128Bytes(std.math.maxInt(u32)) + 1]u8 = undefined;
651 var fbs = std.io.fixedBufferStream(&buf);
652 const writer = fbs.writer();
653 writer.writeByte(DW.LNS.extended_op) catch unreachable;
654 const extended_op_bytes = fbs.pos;
652 var bw: std.io.BufferedWriter = undefined;
653 bw.initFixed(&buf);
654 bw.writeByte(DW.LNS.extended_op) catch unreachable;
655 const extended_op_bytes = bw.end;
655656 var op_len_bytes: u5 = 1;
656657 while (true) switch (std.math.order(len - extended_op_bytes - op_len_bytes, @as(u32, 1) << 7 * op_len_bytes)) {
657 .lt => break uleb128(writer, len - extended_op_bytes - op_len_bytes) catch unreachable,
658 .lt => break bw.writeLeb128(len - extended_op_bytes - op_len_bytes) catch unreachable,
658659 .eq => {
659660 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
660661 op_len_bytes += 1;
661 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
662 fbs.pos += op_len_bytes;
662 std.leb.writeUnsignedExtended((bw.writableSlice(op_len_bytes) catch unreachable)[0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
663 bw.advance(op_len_bytes);
663664 break;
664665 },
665666 .gt => op_len_bytes += 1,
666667 };
667 assert(fbs.pos == extended_op_bytes + op_len_bytes);
668 writer.writeByte(DW.LNE.padding) catch unreachable;
669 assert(fbs.pos >= unit.trailer_len and fbs.pos <= len);
670 return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + start);
668 assert(bw.end == extended_op_bytes + op_len_bytes);
669 bw.writeByte(DW.LNE.padding) catch unreachable;
670 assert(bw.end >= unit.trailer_len and bw.end <= len);
671 return dwarf.getFile().?.pwriteAll(bw.getWritten(), sec.off(dwarf) + start);
671672 }
672 var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, len);
673 defer trailer.deinit();
673 var trailer_bw: std.io.BufferedWriter = undefined;
674 trailer_bw.initFixed(try dwarf.gpa.alloc(u8, len));
675 defer dwarf.gpa.free(trailer_bw.buffer);
674676 const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: {
675677 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
676 trailer.appendAssumeCapacity(@intFromEnum(AbbrevCode.null));
678 trailer_bw.writeByte(@intFromEnum(AbbrevCode.null)) catch unreachable;
677679 break :fill @intFromEnum(AbbrevCode.null);
678680 } else if (sec == &dwarf.debug_aranges.section) fill: {
679 trailer.appendNTimesAssumeCapacity(0, @intFromEnum(dwarf.address_size) * 2);
681 trailer_bw.splatByteAll(0, @intFromEnum(dwarf.address_size) * 2) catch unreachable;
680682 break :fill 0;
681683 } else if (sec == &dwarf.debug_frame.section) fill: {
682684 switch (dwarf.debug_frame.header.format) {
......@@ -684,49 +686,49 @@ const Unit = struct {
684686 .debug_frame, .eh_frame => |format| {
685687 const unit_len = len - dwarf.unitLengthBytes();
686688 switch (dwarf.format) {
687 .@"32" => std.mem.writeInt(u32, trailer.addManyAsArrayAssumeCapacity(4), @intCast(unit_len), dwarf.endian),
689 .@"32" => trailer_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
688690 .@"64" => {
689 std.mem.writeInt(u32, trailer.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian);
690 std.mem.writeInt(u64, trailer.addManyAsArrayAssumeCapacity(8), unit_len, dwarf.endian);
691 trailer_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable;
692 trailer_bw.writeInt(u64, unit_len, dwarf.endian) catch unreachable;
691693 },
692694 }
693695 switch (format) {
694696 .none => unreachable,
695697 .debug_frame => {
696698 switch (dwarf.format) {
697 .@"32" => std.mem.writeInt(u32, trailer.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian),
698 .@"64" => std.mem.writeInt(u64, trailer.addManyAsArrayAssumeCapacity(8), std.math.maxInt(u64), dwarf.endian),
699 .@"32" => trailer_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable,
700 .@"64" => trailer_bw.writeInt(u64, std.math.maxInt(u64), dwarf.endian) catch unreachable,
699701 }
700 trailer.appendAssumeCapacity(4);
701 trailer.appendSliceAssumeCapacity("\x00");
702 trailer.appendAssumeCapacity(@intFromEnum(dwarf.address_size));
703 trailer.appendAssumeCapacity(0);
702 trailer_bw.writeByte(4) catch unreachable;
703 trailer_bw.writeAll("\x00") catch unreachable;
704 trailer_bw.writeByte(@intFromEnum(dwarf.address_size)) catch unreachable;
705 trailer_bw.writeByte(0) catch unreachable;
704706 },
705707 .eh_frame => {
706 std.mem.writeInt(u32, trailer.addManyAsArrayAssumeCapacity(4), 0, dwarf.endian);
707 trailer.appendAssumeCapacity(1);
708 trailer.appendSliceAssumeCapacity("\x00");
708 trailer_bw.writeInt(u32, 0, dwarf.endian) catch unreachable;
709 trailer_bw.writeByte(1) catch unreachable;
710 trailer_bw.writeAll("\x00") catch unreachable;
709711 },
710712 }
711 uleb128(trailer.fixedWriter(), 1) catch unreachable;
712 sleb128(trailer.fixedWriter(), 1) catch unreachable;
713 uleb128(trailer.fixedWriter(), 0) catch unreachable;
713 trailer_bw.writeUleb128(1) catch unreachable;
714 trailer_bw.writeSleb128(1) catch unreachable;
715 trailer_bw.writeUleb128(0) catch unreachable;
714716 },
715717 }
716 trailer.appendNTimesAssumeCapacity(DW.CFA.nop, unit.trailer_len - trailer.items.len);
718 trailer_bw.splatByteAll(DW.CFA.nop, unit.trailer_len - trailer_bw.end) catch unreachable;
717719 break :fill DW.CFA.nop;
718720 } else if (sec == &dwarf.debug_info.section) fill: {
719721 assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
720 trailer.appendNTimesAssumeCapacity(@intFromEnum(AbbrevCode.null), 2);
722 trailer_bw.splatByteAll(@intFromEnum(AbbrevCode.null), 2) catch unreachable;
721723 break :fill @intFromEnum(AbbrevCode.null);
722724 } else if (sec == &dwarf.debug_rnglists.section) fill: {
723 trailer.appendAssumeCapacity(DW.RLE.end_of_list);
725 trailer_bw.writeByte(DW.RLE.end_of_list) catch unreachable;
724726 break :fill DW.RLE.end_of_list;
725727 } else unreachable;
726 assert(trailer.items.len == unit.trailer_len);
727 trailer.appendNTimesAssumeCapacity(fill_byte, len - unit.trailer_len);
728 assert(trailer.items.len == len);
729 try dwarf.getFile().?.pwriteAll(trailer.items, sec.off(dwarf) + start);
728 assert(trailer_bw.end == unit.trailer_len);
729 trailer_bw.splatByteAll(fill_byte, len - unit.trailer_len) catch unreachable;
730 assert(trailer_bw.end == len);
731 try dwarf.getFile().?.pwriteAll(trailer_bw.buffer, sec.off(dwarf) + start);
730732 }
731733
732734 fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void {
......@@ -805,7 +807,7 @@ const Entry = struct {
805807 }
806808 };
807809
808 fn pad(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void {
810 fn pad(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) anyerror!void {
809811 assert(entry.len > 0);
810812 const start = entry.off + entry.len;
811813 if (sec == &dwarf.debug_frame.section) {
......@@ -833,55 +835,58 @@ const Entry = struct {
833835 1 + uleb128Bytes(std.math.maxInt(u32)) + 1,
834836 )
835837 ]u8 = undefined;
836 var fbs = std.io.fixedBufferStream(&buf);
837 const writer = fbs.writer();
838 var bw: std.io.BufferedWriter = undefined;
839 bw.initFixed(&buf);
838840 if (sec == &dwarf.debug_info.section) switch (len) {
839841 0 => {},
840 1 => uleb128(writer, try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
842 1 => bw.writeLeb128(try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
841843 else => {
842 uleb128(writer, try dwarf.refAbbrevCode(.pad_n)) catch unreachable;
843 const abbrev_code_bytes = fbs.pos;
844 bw.writeLeb128(try dwarf.refAbbrevCode(.pad_n)) catch unreachable;
845 const abbrev_code_bytes = bw.end;
844846 var block_len_bytes: u5 = 1;
845847 while (true) switch (std.math.order(len - abbrev_code_bytes - block_len_bytes, @as(u32, 1) << 7 * block_len_bytes)) {
846 .lt => break uleb128(writer, len - abbrev_code_bytes - block_len_bytes) catch unreachable,
848 .lt => break bw.writeLeb128(len - abbrev_code_bytes - block_len_bytes) catch unreachable,
847849 .eq => {
848850 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
849851 block_len_bytes += 1;
850 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
851 fbs.pos += block_len_bytes;
852 std.leb.writeUnsignedExtended((try bw.writableSlice(block_len_bytes))[0..block_len_bytes], len - abbrev_code_bytes - block_len_bytes);
853 bw.advance(block_len_bytes);
852854 break;
853855 },
854856 .gt => block_len_bytes += 1,
855857 };
856 assert(fbs.pos == abbrev_code_bytes + block_len_bytes);
858 assert(bw.end == abbrev_code_bytes + block_len_bytes);
857859 },
858860 } else if (sec == &dwarf.debug_line.section) switch (len) {
859861 0 => {},
860 1 => writer.writeByte(DW.LNS.const_add_pc) catch unreachable,
862 1 => bw.writeByte(DW.LNS.const_add_pc) catch unreachable,
861863 else => {
862 writer.writeByte(DW.LNS.extended_op) catch unreachable;
863 const extended_op_bytes = fbs.pos;
864 bw.writeByte(DW.LNS.extended_op) catch unreachable;
865 const extended_op_bytes = bw.end;
864866 var op_len_bytes: u5 = 1;
865867 while (true) switch (std.math.order(len - extended_op_bytes - op_len_bytes, @as(u32, 1) << 7 * op_len_bytes)) {
866 .lt => break uleb128(writer, len - extended_op_bytes - op_len_bytes) catch unreachable,
868 .lt => break bw.writeLeb128(len - extended_op_bytes - op_len_bytes) catch unreachable,
867869 .eq => {
868870 // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte
869871 op_len_bytes += 1;
870 std.leb.writeUnsignedExtended(buf[fbs.pos..][0..op_len_bytes], len - extended_op_bytes - op_len_bytes);
871 fbs.pos += op_len_bytes;
872 std.leb.writeUnsignedExtended(
873 (bw.writableSlice(op_len_bytes) catch unreachable)[0..op_len_bytes],
874 len - extended_op_bytes - op_len_bytes,
875 );
876 bw.advance(op_len_bytes);
872877 break;
873878 },
874879 .gt => op_len_bytes += 1,
875880 };
876 assert(fbs.pos == extended_op_bytes + op_len_bytes);
877 if (len > 2) writer.writeByte(DW.LNE.padding) catch unreachable;
881 assert(bw.end == extended_op_bytes + op_len_bytes);
882 if (len > 2) bw.writeByte(DW.LNE.padding) catch unreachable;
878883 },
879884 } else assert(!sec.pad_entries_to_ideal and len == 0);
880 assert(fbs.pos <= len);
881 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start);
885 assert(bw.end <= len);
886 try dwarf.getFile().?.pwriteAll(bw.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start);
882887 }
883888
884 fn resize(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) UpdateError!void {
889 fn resize(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) anyerror!void {
885890 assert(len > 0);
886891 assert(sec.alignment.check(len));
887892 if (entry_ptr.len == len) return;
......@@ -973,7 +978,7 @@ const Entry = struct {
973978 else
974979 .main;
975980 if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry)
976 log.err("missing Type({}({d}))", .{
981 log.err("missing Type({f}({d}))", .{
977982 Type.fromInterned(ty).fmt(.{ .tid = .main, .zcu = zcu }),
978983 @intFromEnum(ty),
979984 });
......@@ -981,7 +986,7 @@ const Entry = struct {
981986 for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| {
982987 const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod.?) catch unreachable;
983988 if (sec.getUnit(nav_unit) == unit and unit.getEntry(other_entry) == entry)
984 log.err("missing Nav({}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) });
989 log.err("missing Nav({f}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) });
985990 }
986991 }
987992 @panic("missing dwarf relocation target");
......@@ -1133,150 +1138,149 @@ pub const Loc = union(enum) {
11331138 };
11341139 }
11351140
1136 fn writeReg(reg: u32, op0: u8, opx: u8, writer: anytype) @TypeOf(writer).Error!void {
1141 fn writeReg(bw: *std.io.BufferedWriter, reg: u32, op0: u8, opx: u8) anyerror!void {
11371142 if (std.math.cast(u5, reg)) |small_reg| {
1138 try writer.writeByte(op0 + small_reg);
1143 try bw.writeByte(op0 + small_reg);
11391144 } else {
1140 try writer.writeByte(opx);
1141 try uleb128(writer, reg);
1145 try bw.writeByte(opx);
1146 try bw.writeLeb128(reg);
11421147 }
11431148 }
11441149
1145 fn write(loc: Loc, adapter: anytype) UpdateError!void {
1146 const writer = adapter.writer();
1150 fn write(loc: Loc, bw: *std.io.BufferedWriter, adapter: anytype) anyerror!void {
11471151 switch (loc) {
11481152 .empty => {},
11491153 .addr_reloc => |sym_index| {
1150 try writer.writeByte(DW.OP.addr);
1154 try bw.writeByte(DW.OP.addr);
11511155 try adapter.addrSym(sym_index);
11521156 },
11531157 .deref => |addr| {
11541158 try addr.write(adapter);
1155 try writer.writeByte(DW.OP.deref);
1159 try bw.writeByte(DW.OP.deref);
11561160 },
11571161 .constu => |constu| if (std.math.cast(u5, constu)) |lit| {
1158 try writer.writeByte(@as(u8, DW.OP.lit0) + lit);
1162 try bw.writeByte(@as(u8, DW.OP.lit0) + lit);
11591163 } else if (std.math.cast(u8, constu)) |const1u| {
1160 try writer.writeAll(&.{ DW.OP.const1u, const1u });
1164 try bw.writeAll(&.{ DW.OP.const1u, const1u });
11611165 } else if (std.math.cast(u16, constu)) |const2u| {
1162 try writer.writeByte(DW.OP.const2u);
1163 try writer.writeInt(u16, const2u, adapter.endian());
1166 try bw.writeByte(DW.OP.const2u);
1167 try bw.writeInt(u16, const2u, adapter.endian());
11641168 } else if (std.math.cast(u21, constu)) |const3u| {
1165 try writer.writeByte(DW.OP.constu);
1166 try uleb128(writer, const3u);
1169 try bw.writeByte(DW.OP.constu);
1170 try bw.writeLeb128(const3u);
11671171 } else if (std.math.cast(u32, constu)) |const4u| {
1168 try writer.writeByte(DW.OP.const4u);
1169 try writer.writeInt(u32, const4u, adapter.endian());
1172 try bw.writeByte(DW.OP.const4u);
1173 try bw.writeInt(u32, const4u, adapter.endian());
11701174 } else if (std.math.cast(u49, constu)) |const7u| {
1171 try writer.writeByte(DW.OP.constu);
1172 try uleb128(writer, const7u);
1175 try bw.writeByte(DW.OP.constu);
1176 try bw.writeLeb128(const7u);
11731177 } else {
1174 try writer.writeByte(DW.OP.const8u);
1175 try writer.writeInt(u64, constu, adapter.endian());
1178 try bw.writeByte(DW.OP.const8u);
1179 try bw.writeInt(u64, constu, adapter.endian());
11761180 },
11771181 .consts => |consts| if (std.math.cast(i8, consts)) |const1s| {
1178 try writer.writeAll(&.{ DW.OP.const1s, @bitCast(const1s) });
1182 try bw.writeAll(&.{ DW.OP.const1s, @bitCast(const1s) });
11791183 } else if (std.math.cast(i16, consts)) |const2s| {
1180 try writer.writeByte(DW.OP.const2s);
1181 try writer.writeInt(i16, const2s, adapter.endian());
1184 try bw.writeByte(DW.OP.const2s);
1185 try bw.writeInt(i16, const2s, adapter.endian());
11821186 } else if (std.math.cast(i21, consts)) |const3s| {
1183 try writer.writeByte(DW.OP.consts);
1184 try sleb128(writer, const3s);
1187 try bw.writeByte(DW.OP.consts);
1188 try bw.writeLeb128(const3s);
11851189 } else if (std.math.cast(i32, consts)) |const4s| {
1186 try writer.writeByte(DW.OP.const4s);
1187 try writer.writeInt(i32, const4s, adapter.endian());
1190 try bw.writeByte(DW.OP.const4s);
1191 try bw.writeInt(i32, const4s, adapter.endian());
11881192 } else if (std.math.cast(i49, consts)) |const7s| {
1189 try writer.writeByte(DW.OP.consts);
1190 try sleb128(writer, const7s);
1193 try bw.writeByte(DW.OP.consts);
1194 try bw.writeLeb128(const7s);
11911195 } else {
1192 try writer.writeByte(DW.OP.const8s);
1193 try writer.writeInt(i64, consts, adapter.endian());
1196 try bw.writeByte(DW.OP.const8s);
1197 try bw.writeInt(i64, consts, adapter.endian());
11941198 },
11951199 .plus => |plus| done: {
11961200 if (plus[0].getConst(u0)) |_| {
1197 try plus[1].write(adapter);
1201 try plus[1].write(bw, adapter);
11981202 break :done;
11991203 }
12001204 if (plus[1].getConst(u0)) |_| {
1201 try plus[0].write(adapter);
1205 try plus[0].write(bw, adapter);
12021206 break :done;
12031207 }
12041208 if (plus[0].getBaseReg()) |breg| {
12051209 if (plus[1].getConst(i65)) |offset| {
1206 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);
1207 try sleb128(writer, offset);
1210 try writeReg(bw, breg, DW.OP.breg0, DW.OP.bregx);
1211 try bw.writeLeb128(offset);
12081212 break :done;
12091213 }
12101214 }
12111215 if (plus[1].getBaseReg()) |breg| {
12121216 if (plus[0].getConst(i65)) |offset| {
1213 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);
1214 try sleb128(writer, offset);
1217 try writeReg(bw, breg, DW.OP.breg0, DW.OP.bregx);
1218 try bw.writeLeb128(offset);
12151219 break :done;
12161220 }
12171221 }
12181222 if (plus[0].getConst(u64)) |uconst| {
1219 try plus[1].write(adapter);
1220 try writer.writeByte(DW.OP.plus_uconst);
1221 try uleb128(writer, uconst);
1223 try plus[1].write(bw, adapter);
1224 try bw.writeByte(DW.OP.plus_uconst);
1225 try bw.writeLeb128(uconst);
12221226 break :done;
12231227 }
12241228 if (plus[1].getConst(u64)) |uconst| {
1225 try plus[0].write(adapter);
1226 try writer.writeByte(DW.OP.plus_uconst);
1227 try uleb128(writer, uconst);
1229 try plus[0].write(bw, adapter);
1230 try bw.writeByte(DW.OP.plus_uconst);
1231 try bw.writeLeb128(uconst);
12281232 break :done;
12291233 }
1230 try plus[0].write(adapter);
1231 try plus[1].write(adapter);
1232 try writer.writeByte(DW.OP.plus);
1234 try plus[0].write(bw, adapter);
1235 try plus[1].write(bw, adapter);
1236 try bw.writeByte(DW.OP.plus);
12331237 },
1234 .reg => |reg| try writeReg(reg, DW.OP.reg0, DW.OP.regx, writer),
1238 .reg => |reg| try writeReg(bw, reg, DW.OP.reg0, DW.OP.regx),
12351239 .breg => |breg| {
1236 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);
1237 try sleb128(writer, 0);
1240 try writeReg(bw, breg, DW.OP.breg0, DW.OP.bregx);
1241 try bw.writeSleb128(0);
12381242 },
1239 .push_object_address => try writer.writeByte(DW.OP.push_object_address),
1243 .push_object_address => try bw.writeByte(DW.OP.push_object_address),
12401244 .call => |call| {
12411245 for (call.args) |arg| try arg.write(adapter);
1242 try writer.writeByte(DW.OP.call_ref);
1246 try bw.writeByte(DW.OP.call_ref);
12431247 try adapter.infoEntry(call.unit, call.entry);
12441248 },
12451249 .form_tls_address => |addr| {
1246 try addr.write(adapter);
1247 try writer.writeByte(DW.OP.form_tls_address);
1250 try addr.write(bw, adapter);
1251 try bw.writeByte(DW.OP.form_tls_address);
12481252 },
12491253 .implicit_value => |value| {
1250 try writer.writeByte(DW.OP.implicit_value);
1251 try uleb128(writer, value.len);
1252 try writer.writeAll(value);
1254 try bw.writeByte(DW.OP.implicit_value);
1255 try bw.writeLeb128(value.len);
1256 try bw.writeAll(value);
12531257 },
12541258 .stack_value => |value| {
1255 try value.write(adapter);
1256 try writer.writeByte(DW.OP.stack_value);
1259 try value.write(bw, adapter);
1260 try bw.writeByte(DW.OP.stack_value);
12571261 },
12581262 .implicit_pointer => |implicit_pointer| {
1259 try writer.writeByte(DW.OP.implicit_pointer);
1260 try adapter.infoEntry(implicit_pointer.unit, implicit_pointer.entry);
1261 try sleb128(writer, implicit_pointer.offset);
1263 try bw.writeByte(DW.OP.implicit_pointer);
1264 try adapter.infoEntry(bw, implicit_pointer.unit, implicit_pointer.entry);
1265 try bw.writeLeb128(implicit_pointer.offset);
12621266 },
12631267 .wasm_ext => |wasm_ext| {
1264 try writer.writeByte(DW.OP.WASM_location);
1268 try bw.writeByte(DW.OP.WASM_location);
12651269 switch (wasm_ext) {
12661270 .local => |local| {
1267 try writer.writeByte(DW.OP.WASM_local);
1268 try uleb128(writer, local);
1271 try bw.writeByte(DW.OP.WASM_local);
1272 try bw.writeLeb128(local);
12691273 },
12701274 .global => |global| if (std.math.cast(u21, global)) |global_u21| {
1271 try writer.writeByte(DW.OP.WASM_global);
1272 try uleb128(writer, global_u21);
1275 try bw.writeByte(DW.OP.WASM_global);
1276 try bw.writeLeb128(global_u21);
12731277 } else {
1274 try writer.writeByte(DW.OP.WASM_global_u32);
1275 try writer.writeInt(u32, global, adapter.endian());
1278 try bw.writeByte(DW.OP.WASM_global_u32);
1279 try bw.writeInt(u32, global, adapter.endian());
12761280 },
12771281 .operand_stack => |operand_stack| {
1278 try writer.writeByte(DW.OP.WASM_operand_stack);
1279 try uleb128(writer, operand_stack);
1282 try bw.writeByte(DW.OP.WASM_operand_stack);
1283 try bw.writeLeb128(operand_stack);
12801284 },
12811285 }
12821286 },
......@@ -1308,22 +1312,22 @@ pub const Cfa = union(enum) {
13081312 const RegOff = struct { reg: u32, off: i64 };
13091313 const RegExpr = struct { reg: u32, expr: Loc };
13101314
1311 fn write(cfa: Cfa, wip_nav: *WipNav) UpdateError!void {
1312 const writer = wip_nav.debug_frame.writer(wip_nav.dwarf.gpa);
1315 fn write(cfa: Cfa, wip_nav: *WipNav) anyerror!void {
1316 const bw = &wip_nav.debug_frame.buffered_writer;
13131317 switch (cfa) {
1314 .nop => try writer.writeByte(DW.CFA.nop),
1318 .nop => try bw.writeByte(DW.CFA.nop),
13151319 .advance_loc => |loc| {
13161320 const delta = @divExact(loc - wip_nav.cfi.loc, wip_nav.dwarf.debug_frame.header.code_alignment_factor);
13171321 if (delta == 0) {} else if (std.math.cast(u6, delta)) |small_delta|
1318 try writer.writeByte(@as(u8, DW.CFA.advance_loc) + small_delta)
1322 try bw.writeByte(@as(u8, DW.CFA.advance_loc) + small_delta)
13191323 else if (std.math.cast(u8, delta)) |ubyte_delta|
1320 try writer.writeAll(&.{ DW.CFA.advance_loc1, ubyte_delta })
1324 try bw.writeAll(&.{ DW.CFA.advance_loc1, ubyte_delta })
13211325 else if (std.math.cast(u16, delta)) |uhalf_delta| {
1322 try writer.writeByte(DW.CFA.advance_loc2);
1323 try writer.writeInt(u16, uhalf_delta, wip_nav.dwarf.endian);
1326 try bw.writeByte(DW.CFA.advance_loc2);
1327 try bw.writeInt(u16, uhalf_delta, wip_nav.dwarf.endian);
13241328 } else if (std.math.cast(u32, delta)) |uword_delta| {
1325 try writer.writeByte(DW.CFA.advance_loc4);
1326 try writer.writeInt(u32, uword_delta, wip_nav.dwarf.endian);
1329 try bw.writeByte(DW.CFA.advance_loc4);
1330 try bw.writeInt(u32, uword_delta, wip_nav.dwarf.endian);
13271331 }
13281332 wip_nav.cfi.loc = loc;
13291333 },
......@@ -1335,41 +1339,41 @@ pub const Cfa = union(enum) {
13351339 }, wip_nav.dwarf.debug_frame.header.data_alignment_factor);
13361340 if (std.math.cast(u63, factored_off)) |unsigned_off| {
13371341 if (std.math.cast(u6, reg_off.reg)) |small_reg| {
1338 try writer.writeByte(@as(u8, DW.CFA.offset) + small_reg);
1342 try bw.writeByte(@as(u8, DW.CFA.offset) + small_reg);
13391343 } else {
1340 try writer.writeByte(DW.CFA.offset_extended);
1341 try uleb128(writer, reg_off.reg);
1344 try bw.writeByte(DW.CFA.offset_extended);
1345 try bw.writeLeb128(reg_off.reg);
13421346 }
1343 try uleb128(writer, unsigned_off);
1347 try bw.writeLeb128(unsigned_off);
13441348 } else {
1345 try writer.writeByte(DW.CFA.offset_extended_sf);
1346 try uleb128(writer, reg_off.reg);
1347 try sleb128(writer, factored_off);
1349 try bw.writeByte(DW.CFA.offset_extended_sf);
1350 try bw.writeLeb128(reg_off.reg);
1351 try bw.writeLeb128(factored_off);
13481352 }
13491353 },
13501354 .restore => |reg| if (std.math.cast(u6, reg)) |small_reg|
1351 try writer.writeByte(@as(u8, DW.CFA.restore) + small_reg)
1355 try bw.writeByte(@as(u8, DW.CFA.restore) + small_reg)
13521356 else {
1353 try writer.writeByte(DW.CFA.restore_extended);
1354 try uleb128(writer, reg);
1357 try bw.writeByte(DW.CFA.restore_extended);
1358 try bw.writeLeb128(reg);
13551359 },
13561360 .undefined => |reg| {
1357 try writer.writeByte(DW.CFA.undefined);
1358 try uleb128(writer, reg);
1361 try bw.writeByte(DW.CFA.undefined);
1362 try bw.writeLeb128(reg);
13591363 },
13601364 .same_value => |reg| {
1361 try writer.writeByte(DW.CFA.same_value);
1362 try uleb128(writer, reg);
1365 try bw.writeByte(DW.CFA.same_value);
1366 try bw.writeLeb128(reg);
13631367 },
13641368 .register => |regs| if (regs[0] != regs[1]) {
1365 try writer.writeByte(DW.CFA.register);
1366 for (regs) |reg| try uleb128(writer, reg);
1369 try bw.writeByte(DW.CFA.register);
1370 for (regs) |reg| try bw.writeLeb128(reg);
13671371 } else {
1368 try writer.writeByte(DW.CFA.same_value);
1369 try uleb128(writer, regs[0]);
1372 try bw.writeByte(DW.CFA.same_value);
1373 try bw.writeLeb128(regs[0]);
13701374 },
1371 .remember_state => try writer.writeByte(DW.CFA.remember_state),
1372 .restore_state => try writer.writeByte(DW.CFA.restore_state),
1375 .remember_state => try bw.writeByte(DW.CFA.remember_state),
1376 .restore_state => try bw.writeByte(DW.CFA.restore_state),
13731377 .def_cfa, .def_cfa_register, .def_cfa_offset, .adjust_cfa_offset => {
13741378 const reg_off: RegOff = switch (cfa) {
13751379 else => unreachable,
......@@ -1382,51 +1386,51 @@ pub const Cfa = union(enum) {
13821386 const unsigned_off = std.math.cast(u63, reg_off.off);
13831387 if (reg_off.off == wip_nav.cfi.cfa.off) {
13841388 if (changed_reg) {
1385 try writer.writeByte(DW.CFA.def_cfa_register);
1386 try uleb128(writer, reg_off.reg);
1389 try bw.writeByte(DW.CFA.def_cfa_register);
1390 try bw.writeLeb128(reg_off.reg);
13871391 }
13881392 } else if (switch (wip_nav.dwarf.debug_frame.header.data_alignment_factor) {
13891393 0 => unreachable,
13901394 1 => unsigned_off != null,
13911395 else => |data_alignment_factor| @rem(reg_off.off, data_alignment_factor) != 0,
13921396 }) {
1393 try writer.writeByte(if (changed_reg) DW.CFA.def_cfa else DW.CFA.def_cfa_offset);
1394 if (changed_reg) try uleb128(writer, reg_off.reg);
1395 try uleb128(writer, unsigned_off.?);
1397 try bw.writeByte(if (changed_reg) DW.CFA.def_cfa else DW.CFA.def_cfa_offset);
1398 if (changed_reg) try bw.writeLeb128(reg_off.reg);
1399 try bw.writeLeb128(unsigned_off.?);
13961400 } else {
1397 try writer.writeByte(if (changed_reg) DW.CFA.def_cfa_sf else DW.CFA.def_cfa_offset_sf);
1398 if (changed_reg) try uleb128(writer, reg_off.reg);
1399 try sleb128(writer, @divExact(reg_off.off, wip_nav.dwarf.debug_frame.header.data_alignment_factor));
1401 try bw.writeByte(if (changed_reg) DW.CFA.def_cfa_sf else DW.CFA.def_cfa_offset_sf);
1402 if (changed_reg) try bw.writeLeb128(reg_off.reg);
1403 try bw.writeLeb128(@divExact(reg_off.off, wip_nav.dwarf.debug_frame.header.data_alignment_factor));
14001404 }
14011405 wip_nav.cfi.cfa = reg_off;
14021406 },
14031407 .def_cfa_expression => |expr| {
1404 try writer.writeByte(DW.CFA.def_cfa_expression);
1408 try bw.writeByte(DW.CFA.def_cfa_expression);
14051409 try wip_nav.frameExprLoc(expr);
14061410 },
14071411 .expression => |reg_expr| {
1408 try writer.writeByte(DW.CFA.expression);
1409 try uleb128(writer, reg_expr.reg);
1412 try bw.writeByte(DW.CFA.expression);
1413 try bw.writeLeb128(reg_expr.reg);
14101414 try wip_nav.frameExprLoc(reg_expr.expr);
14111415 },
14121416 .val_offset => |reg_off| {
14131417 const factored_off = @divExact(reg_off.off, wip_nav.dwarf.debug_frame.header.data_alignment_factor);
14141418 if (std.math.cast(u63, factored_off)) |unsigned_off| {
1415 try writer.writeByte(DW.CFA.val_offset);
1416 try uleb128(writer, reg_off.reg);
1417 try uleb128(writer, unsigned_off);
1419 try bw.writeByte(DW.CFA.val_offset);
1420 try bw.writeLeb128(reg_off.reg);
1421 try bw.writeLeb128(unsigned_off);
14181422 } else {
1419 try writer.writeByte(DW.CFA.val_offset_sf);
1420 try uleb128(writer, reg_off.reg);
1421 try sleb128(writer, factored_off);
1423 try bw.writeByte(DW.CFA.val_offset_sf);
1424 try bw.writeLeb128(reg_off.reg);
1425 try bw.writeLeb128(factored_off);
14221426 }
14231427 },
14241428 .val_expression => |reg_expr| {
1425 try writer.writeByte(DW.CFA.val_expression);
1426 try uleb128(writer, reg_expr.reg);
1429 try bw.writeByte(DW.CFA.val_expression);
1430 try bw.writeLeb128(reg_expr.reg);
14271431 try wip_nav.frameExprLoc(reg_expr.expr);
14281432 },
1429 .escape => |bytes| try writer.writeAll(bytes),
1433 .escape => |bytes| try bw.writeAll(bytes),
14301434 }
14311435 }
14321436};
......@@ -1449,19 +1453,27 @@ pub const WipNav = struct {
14491453 loc: u32,
14501454 cfa: Cfa.RegOff,
14511455 },
1452 debug_frame: std.ArrayListUnmanaged(u8),
1453 debug_info: std.ArrayListUnmanaged(u8),
1454 debug_line: std.ArrayListUnmanaged(u8),
1455 debug_loclists: std.ArrayListUnmanaged(u8),
1456 debug_frame: std.io.AllocatingWriter,
1457 debug_info: std.io.AllocatingWriter,
1458 debug_line: std.io.AllocatingWriter,
1459 debug_loclists: std.io.AllocatingWriter,
14561460 pending_lazy: PendingLazy,
14571461
1462 pub fn init(wip_nav: *WipNav) void {
1463 const gpa = wip_nav.dwarf.gpa;
1464 wip_nav.debug_frame.init(gpa);
1465 wip_nav.debug_info.init(gpa);
1466 wip_nav.debug_line.init(gpa);
1467 wip_nav.debug_loclists.init(gpa);
1468 }
1469
14581470 pub fn deinit(wip_nav: *WipNav) void {
14591471 const gpa = wip_nav.dwarf.gpa;
14601472 if (wip_nav.func != .none) wip_nav.blocks.deinit(gpa);
1461 wip_nav.debug_frame.deinit(gpa);
1462 wip_nav.debug_info.deinit(gpa);
1463 wip_nav.debug_line.deinit(gpa);
1464 wip_nav.debug_loclists.deinit(gpa);
1473 wip_nav.debug_frame.deinit();
1474 wip_nav.debug_info.deinit();
1475 wip_nav.debug_line.deinit();
1476 wip_nav.debug_loclists.deinit();
14651477 wip_nav.pending_lazy.types.deinit(gpa);
14661478 wip_nav.pending_lazy.values.deinit(gpa);
14671479 }
......@@ -1470,8 +1482,8 @@ pub const WipNav = struct {
14701482 assert(wip_nav.func != .none);
14711483 if (wip_nav.dwarf.debug_frame.header.format == .none) return;
14721484 const loc_cfa: Cfa = .{ .advance_loc = loc };
1473 try loc_cfa.write(wip_nav);
1474 try cfa.write(wip_nav);
1485 loc_cfa.write(wip_nav) catch |err| return @errorCast(err);
1486 cfa.write(wip_nav) catch |err| return @errorCast(err);
14751487 }
14761488
14771489 pub const LocalVarTag = enum { arg, local_var };
......@@ -1529,7 +1541,7 @@ pub const WipNav = struct {
15291541
15301542 pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void {
15311543 assert(wip_nav.func != .none);
1532 try wip_nav.abbrevCode(.is_var_args);
1544 wip_nav.abbrevCode(.is_var_args) catch |err| return @errorCast(err);
15331545 wip_nav.any_children = true;
15341546 }
15351547
......@@ -1538,7 +1550,7 @@ pub const WipNav = struct {
15381550 delta_line: i33,
15391551 delta_pc: u64,
15401552 ) error{OutOfMemory}!void {
1541 const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
1553 const dlbw = &wip_nav.debug_line.buffered_writer;
15421554
15431555 const header = wip_nav.dwarf.debug_line.header;
15441556 assert(header.maximum_operations_per_instruction == 1);
......@@ -1548,8 +1560,8 @@ pub const WipNav = struct {
15481560 delta_line - header.line_base >= header.line_range)
15491561 remaining: {
15501562 assert(delta_line != 0);
1551 try dlw.writeByte(DW.LNS.advance_line);
1552 try sleb128(dlw, delta_line);
1563 dlbw.writeByte(DW.LNS.advance_line) catch |err| return @errorCast(err);
1564 dlbw.writeLeb128(delta_line) catch |err| return @errorCast(err);
15531565 break :remaining 0;
15541566 } else delta_line);
15551567
......@@ -1557,68 +1569,68 @@ pub const WipNav = struct {
15571569 header.maximum_operations_per_instruction + delta_op;
15581570 const max_op_advance: u9 = (std.math.maxInt(u8) - header.opcode_base) / header.line_range;
15591571 const remaining_op_advance: u8 = @intCast(if (op_advance >= 2 * max_op_advance) remaining: {
1560 try dlw.writeByte(DW.LNS.advance_pc);
1561 try uleb128(dlw, op_advance);
1572 dlbw.writeByte(DW.LNS.advance_pc) catch |err| return @errorCast(err);
1573 dlbw.writeLeb128(op_advance) catch |err| return @errorCast(err);
15621574 break :remaining 0;
15631575 } else if (op_advance >= max_op_advance) remaining: {
1564 try dlw.writeByte(DW.LNS.const_add_pc);
1576 dlbw.writeByte(DW.LNS.const_add_pc) catch |err| return @errorCast(err);
15651577 break :remaining op_advance - max_op_advance;
15661578 } else op_advance);
15671579
1568 if (remaining_delta_line == 0 and remaining_op_advance == 0)
1569 try dlw.writeByte(DW.LNS.copy)
1570 else
1571 try dlw.writeByte(@intCast((remaining_delta_line - header.line_base) +
1572 (header.line_range * remaining_op_advance) + header.opcode_base));
1580 dlbw.writeByte(
1581 if (remaining_delta_line == 0 and remaining_op_advance == 0)
1582 DW.LNS.copy
1583 else
1584 @intCast((remaining_delta_line - header.line_base) +
1585 (header.line_range * remaining_op_advance) + header.opcode_base),
1586 ) catch |err| return @errorCast(err);
15731587 }
15741588
1575 pub fn setColumn(wip_nav: *WipNav, column: u32) error{OutOfMemory}!void {
1576 const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
1577 try dlw.writeByte(DW.LNS.set_column);
1578 try uleb128(dlw, column + 1);
1589 pub fn setColumn(wip_nav: *WipNav, column: u32) std.mem.Allocator.Error!void {
1590 const dlbw = &wip_nav.debug_line.buffered_writer;
1591 dlbw.writeByte(DW.LNS.set_column) catch |err| return @errorCast(err);
1592 dlbw.writeLeb128(column + 1) catch |err| return @errorCast(err);
15791593 }
15801594
1581 pub fn negateStmt(wip_nav: *WipNav) error{OutOfMemory}!void {
1582 const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
1583 try dlw.writeByte(DW.LNS.negate_stmt);
1595 pub fn negateStmt(wip_nav: *WipNav) std.mem.Allocator.Error!void {
1596 return @errorCast(wip_nav.debug_line.buffered_writer.writeByte(DW.LNS.negate_stmt));
15841597 }
15851598
1586 pub fn setPrologueEnd(wip_nav: *WipNav) error{OutOfMemory}!void {
1587 const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
1588 try dlw.writeByte(DW.LNS.set_prologue_end);
1599 pub fn setPrologueEnd(wip_nav: *WipNav) std.mem.Allocator.Error!void {
1600 return @errorCast(wip_nav.debug_line.buffered_writer.writeByte(DW.LNS.set_prologue_end));
15891601 }
15901602
1591 pub fn setEpilogueBegin(wip_nav: *WipNav) error{OutOfMemory}!void {
1592 const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
1593 try dlw.writeByte(DW.LNS.set_epilogue_begin);
1603 pub fn setEpilogueBegin(wip_nav: *WipNav) std.mem.Allocator.Error!void {
1604 return @errorCast(wip_nav.debug_line.buffered_writer.writeByte(DW.LNS.set_epilogue_begin));
15941605 }
15951606
1596 pub fn enterBlock(wip_nav: *WipNav, code_off: u64) UpdateError!void {
1607 pub fn enterBlock(wip_nav: *WipNav, code_off: u64) anyerror!void {
15971608 const dwarf = wip_nav.dwarf;
1598 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1609 const dibw = &wip_nav.debug_info.buffered_writer;
15991610 const block = try wip_nav.blocks.addOne(dwarf.gpa);
16001611
1601 block.abbrev_code = @intCast(wip_nav.debug_info.items.len);
1612 block.abbrev_code = @intCast(dibw.count);
16021613 try wip_nav.abbrevCode(.block);
16031614 block.low_pc_off = code_off;
16041615 try wip_nav.infoAddrSym(wip_nav.func_sym_index, code_off);
1605 block.high_pc = @intCast(wip_nav.debug_info.items.len);
1606 try diw.writeInt(u32, 0, dwarf.endian);
1616 block.high_pc = @intCast(dibw.count);
1617 try dibw.writeInt(u32, 0, dwarf.endian);
16071618 wip_nav.any_children = false;
16081619 }
16091620
1610 pub fn leaveBlock(wip_nav: *WipNav, code_off: u64) UpdateError!void {
1621 pub fn leaveBlock(wip_nav: *WipNav, code_off: u64) anyerror!void {
16111622 const block_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.block));
16121623 const block = wip_nav.blocks.pop().?;
1624 const dib = wip_nav.debug_info.getWritten();
16131625 if (wip_nav.any_children)
1614 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))
1626 try wip_nav.debug_info.buffered_writer.writeLeb128(@intFromEnum(AbbrevCode.null))
16151627 else
16161628 std.leb.writeUnsignedFixed(
16171629 block_bytes,
1618 wip_nav.debug_info.items[block.abbrev_code..][0..block_bytes],
1630 dib[block.abbrev_code..][0..block_bytes],
16191631 try wip_nav.dwarf.refAbbrevCode(.empty_block),
16201632 );
1621 std.mem.writeInt(u32, wip_nav.debug_info.items[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
1633 std.mem.writeInt(u32, dib[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
16221634 wip_nav.any_children = true;
16231635 }
16241636
......@@ -1628,42 +1640,43 @@ pub const WipNav = struct {
16281640 code_off: u64,
16291641 line: u32,
16301642 column: u32,
1631 ) UpdateError!void {
1643 ) anyerror!void {
16321644 const dwarf = wip_nav.dwarf;
16331645 const zcu = wip_nav.pt.zcu;
1634 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1646 const dibw = &wip_nav.debug_info.buffered_writer;
16351647 const block = try wip_nav.blocks.addOne(dwarf.gpa);
16361648
1637 block.abbrev_code = @intCast(wip_nav.debug_info.items.len);
1649 block.abbrev_code = @intCast(dibw.count);
16381650 try wip_nav.abbrevCode(.inlined_func);
16391651 try wip_nav.refNav(zcu.funcInfo(func).owner_nav);
1640 try uleb128(diw, zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
1641 try uleb128(diw, column + 1);
1652 try dibw.writeLeb128(zcu.navSrcLine(zcu.funcInfo(wip_nav.func).owner_nav) + line + 1);
1653 try dibw.writeLeb128(column + 1);
16421654 block.low_pc_off = code_off;
16431655 try wip_nav.infoAddrSym(wip_nav.func_sym_index, code_off);
1644 block.high_pc = @intCast(wip_nav.debug_info.items.len);
1645 try diw.writeInt(u32, 0, dwarf.endian);
1656 block.high_pc = @intCast(dibw.count);
1657 try dibw.writeInt(u32, 0, dwarf.endian);
16461658 try wip_nav.setInlineFunc(func);
16471659 wip_nav.any_children = false;
16481660 }
16491661
1650 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) UpdateError!void {
1662 pub fn leaveInlineFunc(wip_nav: *WipNav, func: InternPool.Index, code_off: u64) anyerror!void {
16511663 const inlined_func_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.inlined_func));
16521664 const block = wip_nav.blocks.pop().?;
1665 const dib = wip_nav.debug_info.getWritten();
16531666 if (wip_nav.any_children)
1654 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), @intFromEnum(AbbrevCode.null))
1667 try wip_nav.debug_info.buffered_writer.writeLeb128(@intFromEnum(AbbrevCode.null))
16551668 else
16561669 std.leb.writeUnsignedFixed(
16571670 inlined_func_bytes,
1658 wip_nav.debug_info.items[block.abbrev_code..][0..inlined_func_bytes],
1671 dib[block.abbrev_code..][0..inlined_func_bytes],
16591672 try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func),
16601673 );
1661 std.mem.writeInt(u32, wip_nav.debug_info.items[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
1674 std.mem.writeInt(u32, dib[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
16621675 try wip_nav.setInlineFunc(func);
16631676 wip_nav.any_children = true;
16641677 }
16651678
1666 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void {
1679 pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) anyerror!void {
16671680 const zcu = wip_nav.pt.zcu;
16681681 const dwarf = wip_nav.dwarf;
16691682 if (wip_nav.func == func) return;
......@@ -1672,22 +1685,22 @@ pub const WipNav = struct {
16721685 const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav);
16731686 const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod.?);
16741687
1675 const dlw = wip_nav.debug_line.writer(dwarf.gpa);
1688 const dlbw = &wip_nav.debug_line.buffered_writer;
16761689 if (dwarf.incremental()) {
16771690 const new_nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, new_func_info.owner_nav);
16781691 errdefer _ = if (!new_nav_gop.found_existing) dwarf.navs.pop();
16791692 if (!new_nav_gop.found_existing) new_nav_gop.value_ptr.* = try dwarf.addCommonEntry(new_unit);
16801693
1681 try dlw.writeByte(DW.LNS.extended_op);
1682 try uleb128(dlw, 1 + dwarf.sectionOffsetBytes());
1683 try dlw.writeByte(DW.LNE.ZIG_set_decl);
1694 try dlbw.writeByte(DW.LNS.extended_op);
1695 try dlbw.writeLeb128(1 + dwarf.sectionOffsetBytes());
1696 try dlbw.writeByte(DW.LNE.ZIG_set_decl);
16841697 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(dwarf.gpa, .{
1685 .source_off = @intCast(wip_nav.debug_line.items.len),
1698 .source_off = @intCast(dlbw.count),
16861699 .target_sec = .debug_info,
16871700 .target_unit = new_unit,
16881701 .target_entry = new_nav_gop.value_ptr.toOptional(),
16891702 });
1690 try dlw.writeByteNTimes(0, dwarf.sectionOffsetBytes());
1703 try dlbw.splatByteAll(0, dwarf.sectionOffsetBytes());
16911704 return;
16921705 }
16931706
......@@ -1698,15 +1711,15 @@ pub const WipNav = struct {
16981711 try mod_info.dirs.put(dwarf.gpa, new_unit, {});
16991712 const file_gop = try mod_info.files.getOrPut(dwarf.gpa, new_file);
17001713
1701 try dlw.writeByte(DW.LNS.set_file);
1702 try uleb128(dlw, file_gop.index);
1714 try dlbw.writeByte(DW.LNS.set_file);
1715 try dlbw.writeLeb128(file_gop.index);
17031716 }
17041717
17051718 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
17061719 const new_src_line: i33 = zcu.navSrcLine(new_func_info.owner_nav);
17071720 if (new_src_line != old_src_line) {
1708 try dlw.writeByte(DW.LNS.advance_line);
1709 try sleb128(dlw, new_src_line - old_src_line);
1721 try dlbw.writeByte(DW.LNS.advance_line);
1722 try dlbw.writeLeb128(new_src_line - old_src_line);
17101723 }
17111724
17121725 wip_nav.func = func;
......@@ -1724,16 +1737,23 @@ pub const WipNav = struct {
17241737 try wip_nav.externalReloc(&wip_nav.dwarf.debug_frame.section, reloc);
17251738 }
17261739
1727 fn abbrevCode(wip_nav: *WipNav, abbrev_code: AbbrevCode) UpdateError!void {
1728 try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), try wip_nav.dwarf.refAbbrevCode(abbrev_code));
1740 fn abbrevCode(wip_nav: *WipNav, abbrev_code: AbbrevCode) anyerror!void {
1741 try wip_nav.debug_info.buffered_writer.writeLeb128(try wip_nav.dwarf.refAbbrevCode(abbrev_code));
17291742 }
17301743
1731 fn sectionOffset(wip_nav: *WipNav, comptime sec: Section.Index, target_sec: Section.Index, target_unit: Unit.Index, target_entry: Entry.Index, target_off: u32) UpdateError!void {
1744 fn sectionOffset(
1745 wip_nav: *WipNav,
1746 comptime sec: Section.Index,
1747 target_sec: Section.Index,
1748 target_unit: Unit.Index,
1749 target_entry: Entry.Index,
1750 target_off: u32,
1751 ) anyerror!void {
17321752 const dwarf = wip_nav.dwarf;
17331753 const gpa = dwarf.gpa;
17341754 const entry_ptr = @field(dwarf, @tagName(sec)).section.getUnit(wip_nav.unit).getEntry(wip_nav.entry);
1735 const bytes = &@field(wip_nav, @tagName(sec));
1736 const source_off: u32 = @intCast(bytes.items.len);
1755 const bw = &@field(wip_nav, @tagName(sec)).buffered_writer;
1756 const source_off: u32 = @intCast(bw.count);
17371757 if (target_sec != sec) {
17381758 try entry_ptr.cross_section_relocs.append(gpa, .{
17391759 .source_off = source_off,
......@@ -1756,112 +1776,108 @@ pub const WipNav = struct {
17561776 .target_off = target_off,
17571777 });
17581778 }
1759 try bytes.appendNTimes(gpa, 0, dwarf.sectionOffsetBytes());
1779 try bw.splatByteAll(0, dwarf.sectionOffsetBytes());
17601780 }
17611781
1762 fn infoSectionOffset(wip_nav: *WipNav, target_sec: Section.Index, target_unit: Unit.Index, target_entry: Entry.Index, target_off: u32) UpdateError!void {
1782 fn infoSectionOffset(wip_nav: *WipNav, target_sec: Section.Index, target_unit: Unit.Index, target_entry: Entry.Index, target_off: u32) anyerror!void {
17631783 try wip_nav.sectionOffset(.debug_info, target_sec, target_unit, target_entry, target_off);
17641784 }
17651785
1766 fn strp(wip_nav: *WipNav, str: []const u8) UpdateError!void {
1786 fn strp(wip_nav: *WipNav, str: []const u8) anyerror!void {
17671787 try wip_nav.infoSectionOffset(.debug_str, StringSection.unit, try wip_nav.dwarf.debug_str.addString(wip_nav.dwarf, str), 0);
17681788 }
17691789
17701790 const ExprLocCounter = struct {
1771 stream: *std.io.BufferedWriter,
17721791 section_offset_bytes: u32,
17731792 address_size: AddressSize,
1774 counter: usize,
1775 fn init(dwarf: *Dwarf, stream: *std.io.BufferedWriter) ExprLocCounter {
1793 fn init(dwarf: *Dwarf) ExprLocCounter {
17761794 return .{
1777 .stream = stream,
17781795 .section_offset_bytes = dwarf.sectionOffsetBytes(),
17791796 .address_size = dwarf.address_size,
17801797 };
17811798 }
1782 fn writer(counter: *ExprLocCounter) *std.io.BufferedWriter {
1783 return counter.stream;
1784 }
17851799 fn endian(_: ExprLocCounter) std.builtin.Endian {
17861800 return @import("builtin").cpu.arch.endian();
17871801 }
1788 fn addrSym(counter: *ExprLocCounter, _: u32) error{}!void {
1789 counter.count += @intFromEnum(counter.address_size);
1802 fn addrSym(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: u32) error{}!void {
1803 bw.count += @intFromEnum(counter.address_size);
17901804 }
1791 fn infoEntry(counter: *ExprLocCounter, _: Unit.Index, _: Entry.Index) error{}!void {
1792 counter.count += counter.section_offset_bytes;
1805 fn infoEntry(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: Unit.Index, _: Entry.Index) error{}!void {
1806 bw.count += counter.section_offset_bytes;
17931807 }
17941808 };
17951809
1796 fn infoExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
1797 var buffer: [std.atomic.cache_line]u8 = undefined;
1798 var counter_bw = std.io.Writer.null.buffered(&buffer);
1799 var counter: ExprLocCounter = .init(wip_nav.dwarf, &counter_bw);
1800 counter.count += try loc.write(&counter);
1810 fn infoExprLoc(wip_nav: *WipNav, loc: Loc) anyerror!void {
1811 const bw = &wip_nav.debug_info.buffered_writer;
1812 const counter: ExprLocCounter = .init(wip_nav.dwarf);
1813 const start = bw.count;
1814 try loc.write(bw, counter);
1815 const len = bw.count - start;
1816 bw.count = start;
1817 wip_nav.debug_info.shrinkRetainingCapacity(start);
18011818
18021819 const adapter: struct {
18031820 wip_nav: *WipNav,
1804 fn writer(ctx: @This()) std.ArrayListUnmanaged(u8).Writer {
1805 return ctx.wip_nav.debug_info.writer(ctx.wip_nav.dwarf.gpa);
1806 }
18071821 fn endian(ctx: @This()) std.builtin.Endian {
18081822 return ctx.wip_nav.dwarf.endian;
18091823 }
1810 fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void {
1824 fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) anyerror!void {
18111825 try ctx.wip_nav.infoAddrSym(sym_index, 0);
18121826 }
1813 fn infoEntry(ctx: @This(), unit: Unit.Index, entry: Entry.Index) UpdateError!void {
1827 fn infoEntry(ctx: @This(), _: *std.io.BufferedWriter, unit: Unit.Index, entry: Entry.Index) anyerror!void {
18141828 try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
18151829 }
18161830 } = .{ .wip_nav = wip_nav };
1817 try uleb128(adapter.writer(), counter.count);
1818 _ = try loc.write(adapter);
1831 try bw.writeLeb128(len);
1832 try loc.write(bw, adapter);
18191833 }
18201834
1821 fn infoAddrSym(wip_nav: *WipNav, sym_index: u32, sym_off: u64) UpdateError!void {
1835 fn infoAddrSym(wip_nav: *WipNav, sym_index: u32, sym_off: u64) anyerror!void {
1836 const dibw = &wip_nav.debug_info.buffered_writer;
18221837 try wip_nav.infoExternalReloc(.{
1823 .source_off = @intCast(wip_nav.debug_info.items.len),
1838 .source_off = @intCast(dibw.count),
18241839 .target_sym = sym_index,
18251840 .target_off = sym_off,
18261841 });
1827 try wip_nav.debug_info.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));
1842 try dibw.splatByteAll(0, @intFromEnum(wip_nav.dwarf.address_size));
18281843 }
18291844
18301845 fn frameExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
1831 var buffer: [std.atomic.cache_line]u8 = undefined;
1832 var counter_bw = std.io.Writer.null.buffered(&buffer);
1833 var counter: ExprLocCounter = .init(wip_nav.dwarf, &counter_bw);
1834 counter.count += try loc.write(&counter);
1846 const bw = &wip_nav.debug_frame.buffered_writer;
1847 const counter: ExprLocCounter = .init(wip_nav.dwarf);
1848 const start = bw.count;
1849 try loc.write(bw, counter);
1850 const len = bw.count - start;
1851 bw.count = start;
1852 wip_nav.debug_frame.shrinkRetainingCapacity(start);
18351853
18361854 const adapter: struct {
18371855 wip_nav: *WipNav,
1838 fn writer(ctx: @This()) std.ArrayListUnmanaged(u8).Writer {
1839 return ctx.wip_nav.debug_frame.writer(ctx.wip_nav.dwarf.gpa);
1840 }
18411856 fn endian(ctx: @This()) std.builtin.Endian {
18421857 return ctx.wip_nav.dwarf.endian;
18431858 }
1844 fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void {
1859 fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) anyerror!void {
18451860 try ctx.wip_nav.frameAddrSym(sym_index, 0);
18461861 }
1847 fn infoEntry(ctx: @This(), unit: Unit.Index, entry: Entry.Index) UpdateError!void {
1862 fn infoEntry(ctx: @This(), _: *std.io.BufferedWriter, unit: Unit.Index, entry: Entry.Index) anyerror!void {
18481863 try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0);
18491864 }
18501865 } = .{ .wip_nav = wip_nav };
1851 try uleb128(adapter.writer(), counter.count);
1852 _ = try loc.write(adapter);
1866 try bw.writeLeb128(len);
1867 try loc.write(bw, adapter);
18531868 }
18541869
1855 fn frameAddrSym(wip_nav: *WipNav, sym_index: u32, sym_off: u64) UpdateError!void {
1870 fn frameAddrSym(wip_nav: *WipNav, sym_index: u32, sym_off: u64) anyerror!void {
1871 const dfbw = &wip_nav.debug_frame.buffered_writer;
18561872 try wip_nav.frameExternalReloc(.{
1857 .source_off = @intCast(wip_nav.debug_frame.items.len),
1873 .source_off = @intCast(dfbw.count),
18581874 .target_sym = sym_index,
18591875 .target_off = sym_off,
18601876 });
1861 try wip_nav.debug_frame.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size));
1877 try dfbw.splatByteAll(0, @intFromEnum(wip_nav.dwarf.address_size));
18621878 }
18631879
1864 fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } {
1880 fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) anyerror!struct { Unit.Index, Entry.Index } {
18651881 const zcu = wip_nav.pt.zcu;
18661882 const ip = &zcu.intern_pool;
18671883 const nav = ip.getNav(nav_index);
......@@ -1873,12 +1889,12 @@ pub const WipNav = struct {
18731889 return .{ unit, entry };
18741890 }
18751891
1876 fn refNav(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!void {
1892 fn refNav(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) anyerror!void {
18771893 const unit, const entry = try wip_nav.getNavEntry(nav_index);
18781894 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
18791895 }
18801896
1881 fn getTypeEntry(wip_nav: *WipNav, ty: Type) UpdateError!struct { Unit.Index, Entry.Index } {
1897 fn getTypeEntry(wip_nav: *WipNav, ty: Type) anyerror!struct { Unit.Index, Entry.Index } {
18821898 const zcu = wip_nav.pt.zcu;
18831899 const ip = &zcu.intern_pool;
18841900 const maybe_inst_index = ty.typeDeclInst(zcu);
......@@ -1900,12 +1916,12 @@ pub const WipNav = struct {
19001916 return .{ unit, entry };
19011917 }
19021918
1903 fn refType(wip_nav: *WipNav, ty: Type) UpdateError!void {
1919 fn refType(wip_nav: *WipNav, ty: Type) anyerror!void {
19041920 const unit, const entry = try wip_nav.getTypeEntry(ty);
19051921 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
19061922 }
19071923
1908 fn getValueEntry(wip_nav: *WipNav, value: Value) UpdateError!struct { Unit.Index, Entry.Index } {
1924 fn getValueEntry(wip_nav: *WipNav, value: Value) anyerror!struct { Unit.Index, Entry.Index } {
19091925 const zcu = wip_nav.pt.zcu;
19101926 const ip = &zcu.intern_pool;
19111927 const ty = value.typeOf(zcu);
......@@ -1921,47 +1937,50 @@ pub const WipNav = struct {
19211937 return .{ unit, entry };
19221938 }
19231939
1924 fn refValue(wip_nav: *WipNav, value: Value) UpdateError!void {
1940 fn refValue(wip_nav: *WipNav, value: Value) anyerror!void {
19251941 const unit, const entry = try wip_nav.getValueEntry(value);
19261942 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
19271943 }
19281944
1929 fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 {
1945 fn refForward(wip_nav: *WipNav) anyerror!u32 {
19301946 const dwarf = wip_nav.dwarf;
1947 const dibw = &wip_nav.debug_info.buffered_writer;
19311948 const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs;
19321949 const reloc_index: u32 = @intCast(cross_entry_relocs.items.len);
19331950 try cross_entry_relocs.append(dwarf.gpa, .{
1934 .source_off = @intCast(wip_nav.debug_info.items.len),
1951 .source_off = @intCast(dibw.count),
19351952 .target_entry = undefined,
19361953 .target_off = undefined,
19371954 });
1938 try wip_nav.debug_info.appendNTimes(dwarf.gpa, 0, dwarf.sectionOffsetBytes());
1955 try dibw.splatByteAll(0, dwarf.sectionOffsetBytes());
19391956 return reloc_index;
19401957 }
19411958
19421959 fn finishForward(wip_nav: *WipNav, reloc_index: u32) void {
19431960 const reloc = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs.items[reloc_index];
19441961 reloc.target_entry = wip_nav.entry.toOptional();
1945 reloc.target_off = @intCast(wip_nav.debug_info.items.len);
1962 reloc.target_off = @intCast(wip_nav.debug_info.buffered_writer.count);
19461963 }
19471964
1948 fn blockValue(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc, val: Value) UpdateError!void {
1965 fn blockValue(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc, val: Value) anyerror!void {
19491966 const ty = val.typeOf(wip_nav.pt.zcu);
1950 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
1967 const dibw = &wip_nav.debug_info.buffered_writer;
19511968 const bytes = if (ty.hasRuntimeBits(wip_nav.pt.zcu)) ty.abiSize(wip_nav.pt.zcu) else 0;
1952 try uleb128(diw, bytes);
1969 try dibw.writeLeb128(bytes);
19531970 if (bytes == 0) return;
1954 const old_len = wip_nav.debug_info.items.len;
1971 var dial = wip_nav.debug_info.toArrayList();
1972 defer _ = wip_nav.debug_info.fromArrayList(wip_nav.dwarf.gpa, &dial);
1973 const old_len = dial.items.len;
19551974 try codegen.generateSymbol(
19561975 wip_nav.dwarf.bin_file,
19571976 wip_nav.pt,
19581977 src_loc,
19591978 val,
1960 &wip_nav.debug_info,
1979 &dial,
19611980 .{ .debug_output = .{ .dwarf = wip_nav } },
19621981 );
19631982 if (old_len + bytes != wip_nav.debug_info.items.len) {
1964 std.debug.print("{} [{}]: {} != {}\n", .{ ty.fmt(wip_nav.pt), ty.toIntern(), bytes, wip_nav.debug_info.items.len - old_len });
1983 std.debug.print("{f} [{}]: {} != {}\n", .{ ty.fmt(wip_nav.pt), ty.toIntern(), bytes, wip_nav.debug_info.items.len - old_len });
19651984 unreachable;
19661985 }
19671986 }
......@@ -1977,9 +1996,9 @@ pub const WipNav = struct {
19771996 abbrev_code: AbbrevCodeForForm,
19781997 ty: Type,
19791998 big_int: std.math.big.int.Const,
1980 ) UpdateError!void {
1999 ) anyerror!void {
19812000 const zcu = wip_nav.pt.zcu;
1982 const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa);
2001 const dibw = &wip_nav.debug_info.buffered_writer;
19832002 const signedness = switch (ty.toIntern()) {
19842003 .comptime_int_type, .comptime_float_type => .signed,
19852004 else => ty.intInfo(zcu).signedness,
......@@ -1990,7 +2009,7 @@ pub const WipNav = struct {
19902009 .signed => abbrev_code.sdata,
19912010 .unsigned => abbrev_code.udata,
19922011 });
1993 try wip_nav.debug_info.ensureUnusedCapacity(wip_nav.dwarf.gpa, std.math.divCeil(usize, bits, 7) catch unreachable);
2012 _ = try dibw.writableSlice(std.math.divCeil(usize, bits, 7) catch unreachable);
19942013 var bit: usize = 0;
19952014 var carry: u1 = 1;
19962015 while (bit < bits) {
......@@ -2007,16 +2026,17 @@ pub const WipNav = struct {
20072026 break :twos_comp_part twos_comp_part;
20082027 };
20092028 bit += 7;
2010 wip_nav.debug_info.appendAssumeCapacity(@as(u8, if (bit < bits) 0x80 else 0x00) | twos_comp_part);
2029 dibw.writeByte(@as(u8, if (bit < bits) 0x80 else 0x00) | twos_comp_part) catch unreachable;
20112030 }
20122031 } else {
20132032 try wip_nav.abbrevCode(abbrev_code.block);
20142033 const bytes = @max(ty.abiSize(zcu), std.math.divCeil(usize, bits, 8) catch unreachable);
2015 try uleb128(diw, bytes);
2034 try dibw.writeLeb128(bytes);
20162035 big_int.writeTwosComplement(
2017 try wip_nav.debug_info.addManyAsSlice(wip_nav.dwarf.gpa, @intCast(bytes)),
2036 try dibw.writableSlice(@intCast(bytes)),
20182037 wip_nav.dwarf.endian,
20192038 );
2039 dibw.advance(@intCast(bytes));
20202040 }
20212041 }
20222042
......@@ -2025,7 +2045,7 @@ pub const WipNav = struct {
20252045 loaded_enum: InternPool.LoadedEnumType,
20262046 abbrev_code: AbbrevCodeForForm,
20272047 field_index: usize,
2028 ) UpdateError!void {
2048 ) anyerror!void {
20292049 const zcu = wip_nav.pt.zcu;
20302050 const ip = &zcu.intern_pool;
20312051 var big_int_space: Value.BigIntSpace = undefined;
......@@ -2045,11 +2065,11 @@ pub const WipNav = struct {
20452065 nav: *const InternPool.Nav,
20462066 file: Zcu.File.Index,
20472067 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
2048 ) UpdateError!void {
2068 ) anyerror!void {
20492069 const zcu = wip_nav.pt.zcu;
20502070 const ip = &zcu.intern_pool;
20512071 const dwarf = wip_nav.dwarf;
2052 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2072 const dibw = &wip_nav.debug_info.buffered_writer;
20532073
20542074 const orig_entry = wip_nav.entry;
20552075 defer wip_nav.entry = orig_entry;
......@@ -2100,15 +2120,15 @@ pub const WipNav = struct {
21002120 try wip_nav.abbrevCode(if (is_generic_decl) abbrev_code.generic_decl else abbrev_code.decl);
21012121 try wip_nav.refType((if (is_generic_decl) null else parent_type) orelse
21022122 .fromInterned(zcu.fileRootType(file)));
2103 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2104 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2105 try uleb128(diw, decl.src_column + 1);
2106 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2123 assert(dibw.count == DebugInfo.declEntryLineOff(dwarf));
2124 try dibw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2125 try dibw.writeLeb128(decl.src_column + 1);
2126 try dibw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
21072127 try wip_nav.strp(nav.name.toSlice(ip));
21082128
21092129 if (!is_generic_decl) return;
21102130 const generic_decl_entry = wip_nav.entry;
2111 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, generic_decl_entry, dwarf, wip_nav.debug_info.items);
2131 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, generic_decl_entry, dwarf, wip_nav.debug_info.getWritten());
21122132 wip_nav.debug_info.clearRetainingCapacity();
21132133 wip_nav.entry = orig_entry;
21142134 try wip_nav.abbrevCode(abbrev_code.decl_instance);
......@@ -2123,7 +2143,7 @@ pub const WipNav = struct {
21232143 const empty: PendingLazy = .{ .types = .empty, .values = .empty };
21242144 };
21252145
2126 fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void {
2146 fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) anyerror!void {
21272147 while (true) if (wip_nav.pending_lazy.types.pop()) |pending_ty|
21282148 try wip_nav.dwarf.updateLazyType(wip_nav.pt, src_loc, pending_ty, &wip_nav.pending_lazy)
21292149 else if (wip_nav.pending_lazy.values.pop()) |pending_val|
......@@ -2346,7 +2366,7 @@ pub fn deinit(dwarf: *Dwarf) void {
23462366 dwarf.* = undefined;
23472367}
23482368
2349fn getUnit(dwarf: *Dwarf, mod: *Module) !Unit.Index {
2369fn getUnit(dwarf: *Dwarf, mod: *Module) anyerror!Unit.Index {
23502370 const mod_gop = try dwarf.mods.getOrPut(dwarf.gpa, mod);
23512371 const unit: Unit.Index = @enumFromInt(mod_gop.index);
23522372 if (!mod_gop.found_existing) {
......@@ -2412,18 +2432,69 @@ pub fn initWipNav(
24122432 nav_index: InternPool.Nav.Index,
24132433 sym_index: u32,
24142434) error{ OutOfMemory, CodegenFail }!?WipNav {
2415 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
2435 return dwarf.initWipNavInner(pt, nav_index, sym_index) catch |err| switch (@as(UpdateError, @errorCast(err))) {
2436 error.OutOfMemory => return error.OutOfMemory,
2437 else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf nav: {s}", .{@errorName(e)}),
2438 };
2439}
2440
2441pub fn finishWipNavFunc(
2442 dwarf: *Dwarf,
2443 pt: Zcu.PerThread,
2444 nav_index: InternPool.Nav.Index,
2445 code_size: u64,
2446 wip_nav: *WipNav,
2447) error{ OutOfMemory, CodegenFail }!void {
2448 return dwarf.finishWipNavFuncInner(pt, nav_index, code_size, wip_nav) catch |err| switch (@as(UpdateError, @errorCast(err))) {
24162449 error.OutOfMemory => return error.OutOfMemory,
2417 else => |e| return pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
2450 else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf func nav: {s}", .{@errorName(e)}),
24182451 };
24192452}
24202453
2454pub fn finishWipNav(
2455 dwarf: *Dwarf,
2456 pt: Zcu.PerThread,
2457 nav_index: InternPool.Nav.Index,
2458 wip_nav: *WipNav,
2459) error{ OutOfMemory, CodegenFail }!void {
2460 return dwarf.finishWipNavInner(pt, nav_index, wip_nav) catch |err| switch (@as(UpdateError, @errorCast(err))) {
2461 error.OutOfMemory => return error.OutOfMemory,
2462 else => |e| return pt.zcu.codegenFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
2463 };
2464}
2465
2466pub fn updateComptimeNav(
2467 dwarf: *Dwarf,
2468 pt: Zcu.PerThread,
2469 nav_index: InternPool.Nav.Index,
2470) error{ OutOfMemory, CodegenFail }!void {
2471 return dwarf.updateComptimeNavInner(pt, nav_index) catch |err| switch (@as(UpdateError, @errorCast(err))) {
2472 error.OutOfMemory => return error.OutOfMemory,
2473 else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf comptime nav: {s}", .{@errorName(e)}),
2474 };
2475}
2476
2477pub fn updateContainerType(
2478 dwarf: *Dwarf,
2479 pt: Zcu.PerThread,
2480 type_index: InternPool.Index,
2481) error{ OutOfMemory, CodegenFail }!void {
2482 return dwarf.updateContainerType(pt, type_index) catch |err| switch (@as(UpdateError, @errorCast(err))) {
2483 error.OutOfMemory => return error.OutOfMemory,
2484 else => |e| return pt.zcu.codegenFailType(type_index, "failed to update dwarf comptime nav: {s}", .{@errorName(e)}),
2485 };
2486}
2487
2488pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
2489 return @errorCast(dwarf.flushModuleInner(pt));
2490}
2491
24212492fn initWipNavInner(
24222493 dwarf: *Dwarf,
24232494 pt: Zcu.PerThread,
24242495 nav_index: InternPool.Nav.Index,
24252496 sym_index: u32,
2426) !?WipNav {
2497) anyerror!?WipNav {
24272498 const zcu = pt.zcu;
24282499 const ip = &zcu.intern_pool;
24292500
......@@ -2431,7 +2502,7 @@ fn initWipNavInner(
24312502 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
24322503 const file = zcu.fileByIndex(inst_info.file);
24332504 const decl = file.zir.?.getDeclaration(inst_info.inst);
2434 log.debug("initWipNav({s}:{d}:{d} %{d} = {})", .{
2505 log.debug("initWipNav({s}:{d}:{d} %{d} = {f})", .{
24352506 file.sub_file_path,
24362507 decl.src_line + 1,
24372508 decl.src_column + 1,
......@@ -2472,17 +2543,17 @@ fn initWipNavInner(
24722543 .func_high_pc = undefined,
24732544 .blocks = undefined,
24742545 .cfi = undefined,
2475 .debug_frame = .empty,
2476 .debug_info = .empty,
2477 .debug_line = .empty,
2478 .debug_loclists = .empty,
2546 .debug_frame = undefined,
2547 .debug_info = undefined,
2548 .debug_line = undefined,
2549 .debug_loclists = undefined,
24792550 .pending_lazy = .empty,
24802551 };
24812552 errdefer wip_nav.deinit();
24822553
24832554 switch (nav_key) {
24842555 else => {
2485 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2556 const dibw = &wip_nav.debug_info.buffered_writer;
24862557 try wip_nav.declCommon(.{
24872558 .decl = .decl_var,
24882559 .generic_decl = .generic_decl_var,
......@@ -2497,9 +2568,9 @@ fn initWipNavInner(
24972568 .@"const" => {
24982569 const const_ty_reloc_index = try wip_nav.refForward();
24992570 try wip_nav.infoExprLoc(loc);
2500 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
2571 try dibw.writeLeb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
25012572 ty.abiAlignment(zcu).toByteUnits().?);
2502 try diw.writeByte(@intFromBool(decl.linkage != .normal));
2573 try dibw.writeByte(@intFromBool(decl.linkage != .normal));
25032574 wip_nav.finishForward(const_ty_reloc_index);
25042575 try wip_nav.abbrevCode(.is_const);
25052576 try wip_nav.refType(ty);
......@@ -2507,9 +2578,9 @@ fn initWipNavInner(
25072578 .@"var" => {
25082579 try wip_nav.refType(ty);
25092580 try wip_nav.infoExprLoc(loc);
2510 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
2581 try dibw.writeLeb128(dibw, nav.status.fully_resolved.alignment.toByteUnits() orelse
25112582 ty.abiAlignment(zcu).toByteUnits().?);
2512 try diw.writeByte(@intFromBool(decl.linkage != .normal));
2583 try dibw.writeByte(@intFromBool(decl.linkage != .normal));
25132584 },
25142585 }
25152586 },
......@@ -2534,39 +2605,39 @@ fn initWipNavInner(
25342605 .none => {},
25352606 .debug_frame, .eh_frame => |format| {
25362607 const entry = dwarf.debug_frame.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry);
2537 const dfw = wip_nav.debug_frame.writer(dwarf.gpa);
2608 const dfbw = &wip_nav.debug_frame.buffered_writer;
25382609 switch (dwarf.format) {
2539 .@"32" => try dfw.writeInt(u32, undefined, dwarf.endian),
2610 .@"32" => try dfbw.writeInt(u32, undefined, dwarf.endian),
25402611 .@"64" => {
2541 try dfw.writeInt(u32, std.math.maxInt(u32), dwarf.endian);
2542 try dfw.writeInt(u64, undefined, dwarf.endian);
2612 try dfbw.writeInt(u32, std.math.maxInt(u32), dwarf.endian);
2613 try dfbw.writeInt(u64, undefined, dwarf.endian);
25432614 },
25442615 }
25452616 switch (format) {
25462617 .none => unreachable,
25472618 .debug_frame => {
25482619 try entry.cross_entry_relocs.append(dwarf.gpa, .{
2549 .source_off = @intCast(wip_nav.debug_frame.items.len),
2620 .source_off = @intCast(dfbw.count),
25502621 });
2551 try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes());
2622 try dfbw.splatByteAll(0, dwarf.sectionOffsetBytes());
25522623 try wip_nav.frameAddrSym(sym_index, 0);
2553 try dfw.writeByteNTimes(undefined, @intFromEnum(dwarf.address_size));
2624 try dfbw.splatByteAll(undefined, @intFromEnum(dwarf.address_size));
25542625 },
25552626 .eh_frame => {
2556 try dfw.writeInt(u32, undefined, dwarf.endian);
2627 try dfbw.writeInt(u32, undefined, dwarf.endian);
25572628 try wip_nav.frameExternalReloc(.{
2558 .source_off = @intCast(wip_nav.debug_frame.items.len),
2629 .source_off = @intCast(dfbw.count),
25592630 .target_sym = sym_index,
25602631 });
2561 try dfw.writeInt(u32, 0, dwarf.endian);
2562 try dfw.writeInt(u32, undefined, dwarf.endian);
2563 try uleb128(dfw, 0);
2632 try dfbw.writeInt(u32, 0, dwarf.endian);
2633 try dfbw.writeInt(u32, undefined, dwarf.endian);
2634 try dfbw.writeUleb128(0);
25642635 },
25652636 }
25662637 },
25672638 }
25682639
2569 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2640 const dibw = &wip_nav.debug_info.buffered_writer;
25702641 try wip_nav.declCommon(.{
25712642 .decl = .decl_func,
25722643 .generic_decl = .generic_decl_func,
......@@ -2576,47 +2647,47 @@ fn initWipNavInner(
25762647 try wip_nav.refType(.fromInterned(func_type.return_type));
25772648 try wip_nav.infoAddrSym(sym_index, 0);
25782649 wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len);
2579 try diw.writeInt(u32, 0, dwarf.endian);
2650 try dibw.writeInt(u32, 0, dwarf.endian);
25802651 const target = &mod.resolved_target.result;
2581 try uleb128(diw, switch (nav.status.fully_resolved.alignment) {
2652 try dibw.writeLeb128(switch (nav.status.fully_resolved.alignment) {
25822653 .none => target_info.defaultFunctionAlignment(target),
25832654 else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
25842655 }.toByteUnits().?);
2585 try diw.writeByte(@intFromBool(decl.linkage != .normal));
2586 try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type));
2656 try dibw.writeByte(@intFromBool(decl.linkage != .normal));
2657 try dibw.writeByte(@intFromBool(func_type.return_type == .noreturn_type));
25872658
2588 const dlw = wip_nav.debug_line.writer(dwarf.gpa);
2589 try dlw.writeByte(DW.LNS.extended_op);
2659 const dlbw = &wip_nav.debug_line.buffered_writer;
2660 try dlbw.writeByte(DW.LNS.extended_op);
25902661 if (dwarf.incremental()) {
2591 try uleb128(dlw, 1 + dwarf.sectionOffsetBytes());
2592 try dlw.writeByte(DW.LNE.ZIG_set_decl);
2662 try dlbw.writeLeb128(1 + dwarf.sectionOffsetBytes());
2663 try dlbw.writeByte(DW.LNE.ZIG_set_decl);
25932664 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_section_relocs.append(dwarf.gpa, .{
2594 .source_off = @intCast(wip_nav.debug_line.items.len),
2665 .source_off = @intCast(dlbw.count),
25952666 .target_sec = .debug_info,
25962667 .target_unit = wip_nav.unit,
25972668 .target_entry = wip_nav.entry.toOptional(),
25982669 });
2599 try dlw.writeByteNTimes(0, dwarf.sectionOffsetBytes());
2670 try dlbw.splatByteAll(0, dwarf.sectionOffsetBytes());
26002671
2601 try dlw.writeByte(DW.LNS.set_column);
2602 try uleb128(dlw, func.lbrace_column + 1);
2672 try dlbw.writeByte(DW.LNS.set_column);
2673 try dlbw.writeLeb128(func.lbrace_column + 1);
26032674
26042675 try wip_nav.advancePCAndLine(func.lbrace_line, 0);
26052676 } else {
2606 try uleb128(dlw, 1 + @intFromEnum(dwarf.address_size));
2607 try dlw.writeByte(DW.LNE.set_address);
2677 try dlbw.writeLeb128(1 + @intFromEnum(dwarf.address_size));
2678 try dlbw.writeByte(DW.LNE.set_address);
26082679 try dwarf.debug_line.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{
2609 .source_off = @intCast(wip_nav.debug_line.items.len),
2680 .source_off = @intCast(dlbw.count),
26102681 .target_sym = sym_index,
26112682 });
2612 try dlw.writeByteNTimes(0, @intFromEnum(dwarf.address_size));
2683 try dlbw.splatByteAll(0, @intFromEnum(dwarf.address_size));
26132684
26142685 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
2615 try dlw.writeByte(DW.LNS.set_file);
2616 try uleb128(dlw, file_gop.index);
2686 try dlbw.writeByte(DW.LNS.set_file);
2687 try dlbw.writeLeb128(file_gop.index);
26172688
2618 try dlw.writeByte(DW.LNS.set_column);
2619 try uleb128(dlw, func.lbrace_column + 1);
2689 try dlbw.writeByte(DW.LNS.set_column);
2690 try dlbw.writeLeb128(func.lbrace_column + 1);
26202691
26212692 try wip_nav.advancePCAndLine(@intCast(decl.src_line + func.lbrace_line), 0);
26222693 }
......@@ -2625,18 +2696,18 @@ fn initWipNavInner(
26252696 return wip_nav;
26262697}
26272698
2628pub fn finishWipNavFunc(
2699fn finishWipNavFuncInner(
26292700 dwarf: *Dwarf,
26302701 pt: Zcu.PerThread,
26312702 nav_index: InternPool.Nav.Index,
26322703 code_size: u64,
26332704 wip_nav: *WipNav,
2634) UpdateError!void {
2705) anyerror!void {
26352706 const zcu = pt.zcu;
26362707 const ip = &zcu.intern_pool;
26372708 const nav = ip.getNav(nav_index);
26382709 assert(wip_nav.func != .none);
2639 log.debug("finishWipNavFunc({})", .{nav.fqn.fmt(ip)});
2710 log.debug("finishWipNavFunc({f})", .{nav.fqn.fmt(ip)});
26402711
26412712 {
26422713 const external_relocs = &dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
......@@ -2654,12 +2725,9 @@ pub fn finishWipNavFunc(
26542725 switch (dwarf.debug_frame.header.format) {
26552726 .none => {},
26562727 .debug_frame, .eh_frame => |format| {
2657 try wip_nav.debug_frame.appendNTimes(
2658 dwarf.gpa,
2659 DW.CFA.nop,
2660 @intCast(dwarf.debug_frame.section.alignment.forward(wip_nav.debug_frame.items.len) - wip_nav.debug_frame.items.len),
2661 );
2662 const contents = wip_nav.debug_frame.items;
2728 const dfbw = &wip_nav.debug_frame.buffered_writer;
2729 try dfbw.splatByteAll(DW.CFA.nop, @intCast(dwarf.debug_frame.section.alignment.forward(dfbw.count) - dfbw.count));
2730 const contents = wip_nav.debug_frame.getWritten();
26632731 try dwarf.debug_frame.section.resizeEntry(wip_nav.unit, wip_nav.entry, dwarf, @intCast(contents.len));
26642732 const unit = dwarf.debug_frame.section.getUnit(wip_nav.unit);
26652733 const entry = unit.getEntry(wip_nav.entry);
......@@ -2686,14 +2754,15 @@ pub fn finishWipNavFunc(
26862754 },
26872755 }
26882756 {
2689 std.mem.writeInt(u32, wip_nav.debug_info.items[wip_nav.func_high_pc..][0..4], @intCast(code_size), dwarf.endian);
2757 std.mem.writeInt(u32, wip_nav.debug_info.getWritten()[wip_nav.func_high_pc..][0..4], @intCast(code_size), dwarf.endian);
26902758 if (wip_nav.any_children) {
2691 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2692 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2759 const dibw = &wip_nav.debug_info.buffered_writer;
2760 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
26932761 } else {
2694 const abbrev_code_buf = wip_nav.debug_info.items[0..AbbrevCode.decl_bytes];
2695 var abbrev_code_fbs = std.io.fixedBufferStream(abbrev_code_buf);
2696 const abbrev_code: AbbrevCode = @enumFromInt(std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable);
2762 const abbrev_code_buf = wip_nav.debug_info.getWritten()[0..AbbrevCode.decl_bytes];
2763 var abbrev_code_br: std.io.BufferedReader = undefined;
2764 abbrev_code_br.initFixed(abbrev_code_buf);
2765 const abbrev_code: AbbrevCode = @enumFromInt(abbrev_code_br.takeLeb128(@typeInfo(AbbrevCode).@"enum".tag_type) catch unreachable);
26972766 std.leb.writeUnsignedFixed(
26982767 AbbrevCode.decl_bytes,
26992768 abbrev_code_buf,
......@@ -2725,41 +2794,35 @@ pub fn finishWipNavFunc(
27252794 );
27262795 }
27272796
2728 try dwarf.finishWipNav(pt, nav_index, wip_nav);
2797 try dwarf.finishWipNavInner(pt, nav_index, wip_nav);
27292798}
27302799
2731pub fn finishWipNav(
2800fn finishWipNavInner(
27322801 dwarf: *Dwarf,
27332802 pt: Zcu.PerThread,
27342803 nav_index: InternPool.Nav.Index,
27352804 wip_nav: *WipNav,
2736) UpdateError!void {
2805) anyerror!void {
27372806 const zcu = pt.zcu;
27382807 const ip = &zcu.intern_pool;
27392808 const nav = ip.getNav(nav_index);
2740 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
2741
2742 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
2743 if (wip_nav.debug_line.items.len > 0) {
2744 const dlw = wip_nav.debug_line.writer(dwarf.gpa);
2745 try dlw.writeByte(DW.LNS.extended_op);
2746 try uleb128(dlw, 1);
2747 try dlw.writeByte(DW.LNE.end_sequence);
2748 try dwarf.debug_line.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_line.items);
2809 log.debug("finishWipNav({f})", .{nav.fqn.fmt(ip)});
2810
2811 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.getWritten());
2812 const debug_line = wip_nav.debug_line.getWritten();
2813 if (debug_line.len > 0) {
2814 const dlbw = &wip_nav.debug_line.buffered_writer;
2815 try dlbw.writeByte(DW.LNS.extended_op);
2816 try dlbw.writeUleb128(1);
2817 try dlbw.writeByte(DW.LNE.end_sequence);
2818 try dwarf.debug_line.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_line.getWritten());
27492819 }
2750 try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.items);
2820 try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.getWritten());
27512821
27522822 try wip_nav.updateLazy(zcu.navSrcLoc(nav_index));
27532823}
27542824
2755pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {
2756 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
2757 error.OutOfMemory => return error.OutOfMemory,
2758 else => |e| return pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
2759 };
2760}
2761
2762fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
2825fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) anyerror!void {
27632826 const zcu = pt.zcu;
27642827 const ip = &zcu.intern_pool;
27652828 const nav_src_loc = zcu.navSrcLoc(nav_index);
......@@ -2769,7 +2832,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
27692832 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
27702833 const file = zcu.fileByIndex(inst_info.file);
27712834 const decl = file.zir.?.getDeclaration(inst_info.inst);
2772 log.debug("updateComptimeNav({s}:{d}:{d} %{d} = {})", .{
2835 log.debug("updateComptimeNav({s}:{d}:{d} %{d} = {f})", .{
27732836 file.sub_file_path,
27742837 decl.src_line + 1,
27752838 decl.src_column + 1,
......@@ -2797,12 +2860,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
27972860 .func_high_pc = undefined,
27982861 .blocks = undefined,
27992862 .cfi = undefined,
2800 .debug_frame = .empty,
2801 .debug_info = .empty,
2802 .debug_line = .empty,
2803 .debug_loclists = .empty,
2863 .debug_frame = undefined,
2864 .debug_info = undefined,
2865 .debug_line = undefined,
2866 .debug_loclists = undefined,
28042867 .pending_lazy = .empty,
28052868 };
2869 wip_nav.init();
28062870 defer wip_nav.deinit();
28072871
28082872 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
......@@ -2846,7 +2910,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
28462910 }
28472911 wip_nav.entry = nav_gop.value_ptr.*;
28482912
2849 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2913 const dibw = &wip_nav.debug_info.buffered_writer;
28502914
28512915 switch (loaded_struct.layout) {
28522916 .auto, .@"extern" => {
......@@ -2859,9 +2923,9 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
28592923 .generic_decl = .generic_decl_const,
28602924 .decl_instance = .decl_instance_struct,
28612925 }, &nav, inst_info.file, &decl);
2862 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
2863 try uleb128(diw, nav_val.toType().abiSize(zcu));
2864 try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
2926 if (loaded_struct.field_types.len == 0) try dibw.writeByte(@intFromBool(false)) else {
2927 try dibw.writeLeb128(nav_val.toType().abiSize(zcu));
2928 try dibw.writeLeb128(nav_val.toType().abiAlignment(zcu).toByteUnits().?);
28652929 for (0..loaded_struct.field_types.len) |field_index| {
28662930 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
28672931 const field_init = loaded_struct.fieldInit(ip, field_index);
......@@ -2897,8 +2961,8 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
28972961 }
28982962 try wip_nav.refType(field_type);
28992963 if (!is_comptime) {
2900 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
2901 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
2964 try dibw.writeLeb128(loaded_struct.offsets.get(ip)[field_index]);
2965 try dibw.writeLeb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
29022966 field_type.abiAlignment(zcu).toByteUnits().?);
29032967 }
29042968 if (has_comptime_state)
......@@ -2906,7 +2970,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
29062970 else if (has_runtime_bits)
29072971 try wip_nav.blockValue(nav_src_loc, .fromInterned(field_init));
29082972 }
2909 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2973 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
29102974 }
29112975 },
29122976 .@"packed" => {
......@@ -2922,10 +2986,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
29222986 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
29232987 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
29242988 try wip_nav.refType(field_type);
2925 try uleb128(diw, field_bit_offset);
2989 try dibw.writeLeb128(field_bit_offset);
29262990 field_bit_offset += @intCast(field_type.bitSize(zcu));
29272991 }
2928 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2992 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
29292993 },
29302994 }
29312995 break :tag .done;
......@@ -2948,7 +3012,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
29483012 type_gop.value_ptr.* = nav_gop.value_ptr.*;
29493013 }
29503014 wip_nav.entry = nav_gop.value_ptr.*;
2951 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3015 const dibw = &wip_nav.debug_info.buffered_writer;
29523016 try wip_nav.declCommon(if (loaded_enum.names.len > 0) .{
29533017 .decl = .decl_enum,
29543018 .generic_decl = .generic_decl_const,
......@@ -2967,7 +3031,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
29673031 }, field_index);
29683032 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
29693033 }
2970 if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
3034 if (loaded_enum.names.len > 0) try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
29713035 break :tag .done;
29723036 },
29733037 .union_type => tag: {
......@@ -2987,15 +3051,15 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
29873051 type_gop.value_ptr.* = nav_gop.value_ptr.*;
29883052 }
29893053 wip_nav.entry = nav_gop.value_ptr.*;
2990 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3054 const dibw = &wip_nav.debug_info.buffered_writer;
29913055 try wip_nav.declCommon(.{
29923056 .decl = .decl_union,
29933057 .generic_decl = .generic_decl_const,
29943058 .decl_instance = .decl_instance_union,
29953059 }, &nav, inst_info.file, &decl);
29963060 const union_layout = Type.getUnionLayout(loaded_union, zcu);
2997 try uleb128(diw, union_layout.abi_size);
2998 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
3061 try dibw.writeLeb128(union_layout.abi_size);
3062 try dibw.writeLeb128(union_layout.abi_align.toByteUnits().?);
29993063 const loaded_tag = loaded_union.loadTagType(ip);
30003064 if (loaded_union.hasTag(ip)) {
30013065 try wip_nav.abbrevCode(.tagged_union);
......@@ -3003,13 +3067,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
30033067 .debug_info,
30043068 wip_nav.unit,
30053069 wip_nav.entry,
3006 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
3070 @intCast(dibw.count + dwarf.sectionOffsetBytes()),
30073071 );
30083072 {
30093073 try wip_nav.abbrevCode(.generated_field);
30103074 try wip_nav.strp("tag");
30113075 try wip_nav.refType(.fromInterned(loaded_union.enum_tag_ty));
3012 try uleb128(diw, union_layout.tagOffset());
3076 try dibw.writeLeb128(union_layout.tagOffset());
30133077
30143078 for (0..loaded_union.field_types.len) |field_index| {
30153079 try wip_nav.enumConstValue(loaded_tag, .{
......@@ -3022,23 +3086,23 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
30223086 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
30233087 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
30243088 try wip_nav.refType(field_type);
3025 try uleb128(diw, union_layout.payloadOffset());
3026 try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
3089 try dibw.writeLeb128(union_layout.payloadOffset());
3090 try dibw.writeLeb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
30273091 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
30283092 }
3029 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3093 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
30303094 }
30313095 }
3032 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3096 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
30333097 } else for (0..loaded_union.field_types.len) |field_index| {
30343098 try wip_nav.abbrevCode(.untagged_union_field);
30353099 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
30363100 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
30373101 try wip_nav.refType(field_type);
3038 try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
3102 try dibw.writeLeb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
30393103 field_type.abiAlignment(zcu).toByteUnits().?);
30403104 }
3041 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3105 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
30423106 break :tag .done;
30433107 },
30443108 .opaque_type => tag: {
......@@ -3058,13 +3122,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
30583122 type_gop.value_ptr.* = nav_gop.value_ptr.*;
30593123 }
30603124 wip_nav.entry = nav_gop.value_ptr.*;
3061 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3125 const dibw = &wip_nav.debug_info.buffered_writer;
30623126 try wip_nav.declCommon(.{
30633127 .decl = .decl_namespace_struct,
30643128 .generic_decl = .generic_decl_const,
30653129 .decl_instance = .decl_instance_namespace_struct,
30663130 }, &nav, inst_info.file, &decl);
3067 try diw.writeByte(@intFromBool(true));
3131 try dibw.writeByte(@intFromBool(true));
30683132 break :tag .done;
30693133 },
30703134 .undef,
......@@ -3102,7 +3166,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31023166 const is_nullary = !func_type.is_var_args and for (0..func_type.param_types.len) |param_index| {
31033167 if (!func_type.paramIsComptime(std.math.cast(u5, param_index) orelse break false)) break false;
31043168 } else true;
3105 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3169 const dibw = &wip_nav.debug_info.buffered_writer;
31063170 try wip_nav.declCommon(if (is_nullary) .{
31073171 .decl = .decl_nullary_func_generic,
31083172 .generic_decl = .generic_decl_func,
......@@ -3121,7 +3185,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31213185 try wip_nav.refType(.fromInterned(func_type.param_types.get(ip)[param_index]));
31223186 }
31233187 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
3124 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3188 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
31253189 }
31263190 break :tag .done;
31273191 },
......@@ -3146,7 +3210,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31463210 try wip_nav.refType(nav_val.toType());
31473211 },
31483212 .decl_var => {
3149 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3213 const dibw = &wip_nav.debug_info.buffered_writer;
31503214 try wip_nav.declCommon(.{
31513215 .decl = .decl_var,
31523216 .generic_decl = .generic_decl_var,
......@@ -3156,12 +3220,12 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31563220 const nav_ty = nav_val.typeOf(zcu);
31573221 try wip_nav.refType(nav_ty);
31583222 try wip_nav.blockValue(nav_src_loc, nav_val);
3159 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
3223 try dibw.writeLeb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
31603224 nav_ty.abiAlignment(zcu).toByteUnits().?);
3161 try diw.writeByte(@intFromBool(decl.linkage != .normal));
3225 try dibw.writeByte(@intFromBool(decl.linkage != .normal));
31623226 },
31633227 .decl_const => {
3164 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3228 const dibw = &wip_nav.debug_info.buffered_writer;
31653229 const nav_ty = nav_val.typeOf(zcu);
31663230 const has_runtime_bits = nav_ty.hasRuntimeBits(zcu);
31673231 const has_comptime_state = nav_ty.comptimeOnly(zcu) and try nav_ty.onePossibleValue(pt) == null;
......@@ -3184,9 +3248,9 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31843248 }, &nav, inst_info.file, &decl);
31853249 try wip_nav.strp(nav.fqn.toSlice(ip));
31863250 const nav_ty_reloc_index = try wip_nav.refForward();
3187 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
3251 try dibw.writeLeb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
31883252 nav_ty.abiAlignment(zcu).toByteUnits().?);
3189 try diw.writeByte(@intFromBool(decl.linkage != .normal));
3253 try dibw.writeByte(@intFromBool(decl.linkage != .normal));
31903254 if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val);
31913255 if (has_comptime_state) try wip_nav.refValue(nav_val);
31923256 wip_nav.finishForward(nav_ty_reloc_index);
......@@ -3202,7 +3266,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
32023266 try wip_nav.refNav(owner_nav);
32033267 },
32043268 }
3205 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
3269 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.getWritten());
32063270 try wip_nav.updateLazy(nav_src_loc);
32073271}
32083272
......@@ -3212,14 +3276,14 @@ fn updateLazyType(
32123276 src_loc: Zcu.LazySrcLoc,
32133277 type_index: InternPool.Index,
32143278 pending_lazy: *WipNav.PendingLazy,
3215) UpdateError!void {
3279) anyerror!void {
32163280 const zcu = pt.zcu;
32173281 const ip = &zcu.intern_pool;
32183282 assert(ip.typeOf(type_index) == .type_type);
32193283 const ty: Type = .fromInterned(type_index);
32203284 switch (type_index) {
32213285 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),
3222 else => log.debug("updateLazyType({})", .{ty.fmt(pt)}),
3286 else => log.debug("updateLazyType({f})", .{ty.fmt(pt)}),
32233287 }
32243288
32253289 var wip_nav: WipNav = .{
......@@ -3233,21 +3297,22 @@ fn updateLazyType(
32333297 .func_high_pc = undefined,
32343298 .blocks = undefined,
32353299 .cfi = undefined,
3236 .debug_frame = .empty,
3237 .debug_info = .empty,
3238 .debug_line = .empty,
3239 .debug_loclists = .empty,
3300 .debug_frame = undefined,
3301 .debug_info = undefined,
3302 .debug_line = undefined,
3303 .debug_loclists = undefined,
32403304 .pending_lazy = pending_lazy.*,
32413305 };
3306 wip_nav.init();
32423307 defer {
32433308 pending_lazy.* = wip_nav.pending_lazy;
32443309 wip_nav.pending_lazy = .empty;
32453310 wip_nav.deinit();
32463311 }
3247 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3312 const dibw = &wip_nav.debug_info.buffered_writer;
32483313 const name = switch (type_index) {
32493314 .generic_poison_type => "",
3250 else => try std.fmt.allocPrint(dwarf.gpa, "{}", .{ty.fmt(pt)}),
3315 else => try std.fmt.allocPrint(dwarf.gpa, "{f}", .{ty.fmt(pt)}),
32513316 };
32523317 defer dwarf.gpa.free(name);
32533318
......@@ -3259,12 +3324,12 @@ fn updateLazyType(
32593324 .int_type => |int_type| {
32603325 try wip_nav.abbrevCode(.numeric_type);
32613326 try wip_nav.strp(name);
3262 try diw.writeByte(switch (int_type.signedness) {
3327 try dibw.writeByte(switch (int_type.signedness) {
32633328 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
32643329 });
3265 try uleb128(diw, int_type.bits);
3266 try uleb128(diw, ty.abiSize(zcu));
3267 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3330 try dibw.writeLeb128(int_type.bits);
3331 try dibw.writeLeb128(ty.abiSize(zcu));
3332 try dibw.writeLeb128(ty.abiAlignment(zcu).toByteUnits().?);
32683333 },
32693334 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
32703335 .one, .many, .c => {
......@@ -3272,14 +3337,14 @@ fn updateLazyType(
32723337 try wip_nav.abbrevCode(if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type);
32733338 try wip_nav.strp(name);
32743339 if (ptr_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(ptr_type.sentinel));
3275 try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse
3340 try dibw.writeLeb128(ptr_type.flags.alignment.toByteUnits() orelse
32763341 ptr_child_type.abiAlignment(zcu).toByteUnits().?);
3277 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));
3342 try dibw.writeByte(@intFromEnum(ptr_type.flags.address_space));
32783343 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
32793344 .debug_info,
32803345 wip_nav.unit,
32813346 wip_nav.entry,
3282 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
3347 @intCast(dibw.count + dwarf.sectionOffsetBytes()),
32833348 ) else try wip_nav.refType(ptr_child_type);
32843349 if (ptr_type.flags.is_const) {
32853350 try wip_nav.abbrevCode(.is_const);
......@@ -3287,7 +3352,7 @@ fn updateLazyType(
32873352 .debug_info,
32883353 wip_nav.unit,
32893354 wip_nav.entry,
3290 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
3355 @intCast(dibw.count + dwarf.sectionOffsetBytes()),
32913356 ) else try wip_nav.refType(ptr_child_type);
32923357 }
32933358 if (ptr_type.flags.is_volatile) {
......@@ -3298,19 +3363,19 @@ fn updateLazyType(
32983363 .slice => {
32993364 try wip_nav.abbrevCode(.generated_struct_type);
33003365 try wip_nav.strp(name);
3301 try uleb128(diw, ty.abiSize(zcu));
3302 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3366 try dibw.writeLeb128(ty.abiSize(zcu));
3367 try dibw.writeLeb128(ty.abiAlignment(zcu).toByteUnits().?);
33033368 try wip_nav.abbrevCode(.generated_field);
33043369 try wip_nav.strp("ptr");
33053370 const ptr_field_type = ty.slicePtrFieldType(zcu);
33063371 try wip_nav.refType(ptr_field_type);
3307 try uleb128(diw, 0);
3372 try dibw.writeUleb128(0);
33083373 try wip_nav.abbrevCode(.generated_field);
33093374 try wip_nav.strp("len");
33103375 const len_field_type: Type = .usize;
33113376 try wip_nav.refType(len_field_type);
3312 try uleb128(diw, len_field_type.abiAlignment(zcu).forward(ptr_field_type.abiSize(zcu)));
3313 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3377 try dibw.writeLeb128(len_field_type.abiAlignment(zcu).forward(ptr_field_type.abiSize(zcu)));
3378 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
33143379 },
33153380 },
33163381 .array_type => |array_type| {
......@@ -3321,8 +3386,8 @@ fn updateLazyType(
33213386 try wip_nav.refType(array_child_type);
33223387 try wip_nav.abbrevCode(.array_index);
33233388 try wip_nav.refType(.usize);
3324 try uleb128(diw, array_type.len);
3325 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3389 try dibw.writeLeb128(array_type.len);
3390 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
33263391 },
33273392 .vector_type => |vector_type| {
33283393 try wip_nav.abbrevCode(.vector_type);
......@@ -3330,22 +3395,22 @@ fn updateLazyType(
33303395 try wip_nav.refType(.fromInterned(vector_type.child));
33313396 try wip_nav.abbrevCode(.array_index);
33323397 try wip_nav.refType(.usize);
3333 try uleb128(diw, vector_type.len);
3334 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3398 try dibw.writeLeb128(vector_type.len);
3399 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
33353400 },
33363401 .opt_type => |opt_child_type_index| {
33373402 const opt_child_type: Type = .fromInterned(opt_child_type_index);
33383403 const opt_repr = optRepr(opt_child_type, zcu);
33393404 try wip_nav.abbrevCode(.generated_union_type);
33403405 try wip_nav.strp(name);
3341 try uleb128(diw, ty.abiSize(zcu));
3342 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3406 try dibw.writeLeb128(ty.abiSize(zcu));
3407 try dibw.writeLeb128(ty.abiAlignment(zcu).toByteUnits().?);
33433408 switch (opt_repr) {
33443409 .opv_null => {
33453410 try wip_nav.abbrevCode(.generated_field);
33463411 try wip_nav.strp("null");
33473412 try wip_nav.refType(.null);
3348 try uleb128(diw, 0);
3413 try dibw.writeUleb128(0);
33493414 },
33503415 .unpacked, .error_set, .pointer => {
33513416 try wip_nav.abbrevCode(.tagged_union);
......@@ -3353,7 +3418,7 @@ fn updateLazyType(
33533418 .debug_info,
33543419 wip_nav.unit,
33553420 wip_nav.entry,
3356 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
3421 @intCast(dibw.count + dwarf.sectionOffsetBytes()),
33573422 );
33583423 {
33593424 try wip_nav.abbrevCode(.generated_field);
......@@ -3362,7 +3427,7 @@ fn updateLazyType(
33623427 .opv_null => unreachable,
33633428 .unpacked => {
33643429 try wip_nav.refType(.bool);
3365 try uleb128(diw, if (opt_child_type.hasRuntimeBits(zcu))
3430 try dibw.writeLeb128(if (opt_child_type.hasRuntimeBits(zcu))
33663431 opt_child_type.abiSize(zcu)
33673432 else
33683433 0);
......@@ -3372,37 +3437,37 @@ fn updateLazyType(
33723437 .signedness = .unsigned,
33733438 .bits = zcu.errorSetBits(),
33743439 } })));
3375 try uleb128(diw, 0);
3440 try dibw.writeUleb128(0);
33763441 },
33773442 .pointer => {
33783443 try wip_nav.refType(.usize);
3379 try uleb128(diw, 0);
3444 try dibw.writeUleb128(0);
33803445 },
33813446 }
33823447
33833448 try wip_nav.abbrevCode(.unsigned_tagged_union_field);
3384 try uleb128(diw, 0);
3449 try dibw.writeUleb128(0);
33853450 {
33863451 try wip_nav.abbrevCode(.generated_field);
33873452 try wip_nav.strp("null");
33883453 try wip_nav.refType(.null);
3389 try uleb128(diw, 0);
3454 try dibw.writeUleb128(0);
33903455 }
3391 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3456 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
33923457
33933458 try wip_nav.abbrevCode(.tagged_union_default_field);
33943459 {
33953460 try wip_nav.abbrevCode(.generated_field);
33963461 try wip_nav.strp("?");
33973462 try wip_nav.refType(opt_child_type);
3398 try uleb128(diw, 0);
3463 try dibw.writeUleb128(0);
33993464 }
3400 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3465 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34013466 }
3402 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3467 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34033468 },
34043469 }
3405 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3470 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34063471 },
34073472 .anyframe_type => unreachable,
34083473 .error_union_type => |error_union_type| {
......@@ -3421,11 +3486,11 @@ fn updateLazyType(
34213486 if (error_union_type.error_set_type != .generic_poison_type and
34223487 error_union_type.payload_type != .generic_poison_type)
34233488 {
3424 try uleb128(diw, ty.abiSize(zcu));
3425 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3489 try dibw.writeLeb128(ty.abiSize(zcu));
3490 try dibw.writeLeb128(ty.abiAlignment(zcu).toByteUnits().?);
34263491 } else {
3427 try uleb128(diw, 0);
3428 try uleb128(diw, 1);
3492 try dibw.writeUleb128(0);
3493 try dibw.writeUleb128(1);
34293494 }
34303495 {
34313496 try wip_nav.abbrevCode(.tagged_union);
......@@ -3433,7 +3498,7 @@ fn updateLazyType(
34333498 .debug_info,
34343499 wip_nav.unit,
34353500 wip_nav.entry,
3436 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
3501 @intCast(dibw.count + dwarf.sectionOffsetBytes()),
34373502 );
34383503 {
34393504 try wip_nav.abbrevCode(.generated_field);
......@@ -3442,30 +3507,30 @@ fn updateLazyType(
34423507 .signedness = .unsigned,
34433508 .bits = zcu.errorSetBits(),
34443509 } })));
3445 try uleb128(diw, error_union_error_set_offset);
3510 try dibw.writeLeb128(error_union_error_set_offset);
34463511
34473512 try wip_nav.abbrevCode(.unsigned_tagged_union_field);
3448 try uleb128(diw, 0);
3513 try dibw.writeUleb128(0);
34493514 {
34503515 try wip_nav.abbrevCode(.generated_field);
34513516 try wip_nav.strp("value");
34523517 try wip_nav.refType(error_union_payload_type);
3453 try uleb128(diw, error_union_payload_offset);
3518 try dibw.writeLeb128(error_union_payload_offset);
34543519 }
3455 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3520 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34563521
34573522 try wip_nav.abbrevCode(.tagged_union_default_field);
34583523 {
34593524 try wip_nav.abbrevCode(.generated_field);
34603525 try wip_nav.strp("error");
34613526 try wip_nav.refType(error_union_error_set_type);
3462 try uleb128(diw, error_union_error_set_offset);
3527 try dibw.writeLeb128(error_union_error_set_offset);
34633528 }
3464 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3529 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34653530 }
3466 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3531 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34673532 }
3468 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3533 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
34693534 },
34703535 .simple_type => |simple_type| switch (simple_type) {
34713536 .f16,
......@@ -3489,7 +3554,7 @@ fn updateLazyType(
34893554 => {
34903555 try wip_nav.abbrevCode(.numeric_type);
34913556 try wip_nav.strp(name);
3492 try diw.writeByte(if (type_index == .bool_type)
3557 try dibw.writeByte(if (type_index == .bool_type)
34933558 DW.ATE.boolean
34943559 else if (ty.isRuntimeFloat())
34953560 DW.ATE.float
......@@ -3499,9 +3564,9 @@ fn updateLazyType(
34993564 DW.ATE.unsigned
35003565 else
35013566 unreachable);
3502 try uleb128(diw, ty.bitSize(zcu));
3503 try uleb128(diw, ty.abiSize(zcu));
3504 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3567 try dibw.writeLeb128(ty.bitSize(zcu));
3568 try dibw.writeLeb128(ty.abiSize(zcu));
3569 try dibw.writeLeb128(ty.abiAlignment(zcu).toByteUnits().?);
35053570 },
35063571 .anyopaque,
35073572 .void,
......@@ -3527,12 +3592,12 @@ fn updateLazyType(
35273592 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
35283593 try wip_nav.abbrevCode(.generated_empty_struct_type);
35293594 try wip_nav.strp(name);
3530 try diw.writeByte(@intFromBool(false));
3595 try dibw.writeByte(@intFromBool(false));
35313596 } else {
35323597 try wip_nav.abbrevCode(.generated_struct_type);
35333598 try wip_nav.strp(name);
3534 try uleb128(diw, ty.abiSize(zcu));
3535 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
3599 try dibw.writeLeb128(ty.abiSize(zcu));
3600 try dibw.writeLeb128(ty.abiAlignment(zcu).toByteUnits().?);
35363601 var field_byte_offset: u64 = 0;
35373602 for (0..tuple_type.types.len) |field_index| {
35383603 const comptime_value = tuple_type.values.get(ip)[field_index];
......@@ -3561,8 +3626,8 @@ fn updateLazyType(
35613626 if (comptime_value == .none) {
35623627 const field_align = field_type.abiAlignment(zcu);
35633628 field_byte_offset = field_align.forward(field_byte_offset);
3564 try uleb128(diw, field_byte_offset);
3565 try uleb128(diw, field_type.abiAlignment(zcu).toByteUnits().?);
3629 try dibw.writeLeb128(field_byte_offset);
3630 try dibw.writeLeb128(field_type.abiAlignment(zcu).toByteUnits().?);
35663631 field_byte_offset += field_type.abiSize(zcu);
35673632 }
35683633 if (has_comptime_state)
......@@ -3570,7 +3635,7 @@ fn updateLazyType(
35703635 else if (has_runtime_bits)
35713636 try wip_nav.blockValue(src_loc, .fromInterned(comptime_value));
35723637 }
3573 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3638 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
35743639 },
35753640 .enum_type => {
35763641 const loaded_enum = ip.loadEnumType(type_index);
......@@ -3585,7 +3650,7 @@ fn updateLazyType(
35853650 }, field_index);
35863651 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
35873652 }
3588 if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
3653 if (loaded_enum.names.len > 0) try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
35893654 },
35903655 .func_type => |func_type| {
35913656 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
......@@ -3653,7 +3718,7 @@ fn updateLazyType(
36533718 else => .nocall,
36543719 };
36553720 };
3656 try diw.writeByte(@intFromEnum(cc));
3721 try dibw.writeByte(@intFromEnum(cc));
36573722 try wip_nav.refType(.fromInterned(func_type.return_type));
36583723 if (!is_nullary) {
36593724 for (0..func_type.param_types.len) |param_index| {
......@@ -3661,7 +3726,7 @@ fn updateLazyType(
36613726 try wip_nav.refType(.fromInterned(func_type.param_types.get(ip)[param_index]));
36623727 }
36633728 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
3664 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3729 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
36653730 }
36663731 },
36673732 .error_set_type => |error_set_type| {
......@@ -3674,10 +3739,10 @@ fn updateLazyType(
36743739 for (0..error_set_type.names.len) |field_index| {
36753740 const field_name = error_set_type.names.get(ip)[field_index];
36763741 try wip_nav.abbrevCode(.unsigned_enum_field);
3677 try uleb128(diw, ip.getErrorValueIfExists(field_name).?);
3742 try dibw.writeLeb128(ip.getErrorValueIfExists(field_name).?);
36783743 try wip_nav.strp(field_name.toSlice(ip));
36793744 }
3680 if (error_set_type.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
3745 if (error_set_type.names.len > 0) try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
36813746 },
36823747 .inferred_error_set_type => |func| {
36833748 try wip_nav.abbrevCode(.inferred_error_set_type);
......@@ -3709,7 +3774,7 @@ fn updateLazyType(
37093774 .memoized_call,
37103775 => unreachable,
37113776 }
3712 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
3777 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.getWritten());
37133778}
37143779
37153780fn updateLazyValue(
......@@ -3718,11 +3783,11 @@ fn updateLazyValue(
37183783 src_loc: Zcu.LazySrcLoc,
37193784 value_index: InternPool.Index,
37203785 pending_lazy: *WipNav.PendingLazy,
3721) UpdateError!void {
3786) anyerror!void {
37223787 const zcu = pt.zcu;
37233788 const ip = &zcu.intern_pool;
37243789 assert(ip.typeOf(value_index) != .type_type);
3725 log.debug("updateLazyValue(@as({}, {}))", .{
3790 log.debug("updateLazyValue(@as({f}, {f}))", .{
37263791 Value.fromInterned(value_index).typeOf(zcu).fmt(pt),
37273792 Value.fromInterned(value_index).fmtValue(pt),
37283793 });
......@@ -3737,18 +3802,19 @@ fn updateLazyValue(
37373802 .func_high_pc = undefined,
37383803 .blocks = undefined,
37393804 .cfi = undefined,
3740 .debug_frame = .empty,
3741 .debug_info = .empty,
3742 .debug_line = .empty,
3743 .debug_loclists = .empty,
3805 .debug_frame = undefined,
3806 .debug_info = undefined,
3807 .debug_line = undefined,
3808 .debug_loclists = undefined,
37443809 .pending_lazy = pending_lazy.*,
37453810 };
3811 wip_nav.init();
37463812 defer {
37473813 pending_lazy.* = wip_nav.pending_lazy;
37483814 wip_nav.pending_lazy = .empty;
37493815 wip_nav.deinit();
37503816 }
3751 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3817 const dibw = &wip_nav.debug_info.buffered_writer;
37523818 var big_int_space: Value.BigIntSpace = undefined;
37533819 switch (ip.indexToKey(value_index)) {
37543820 .int_type,
......@@ -3786,7 +3852,7 @@ fn updateLazyValue(
37863852 .err => |err| {
37873853 try wip_nav.abbrevCode(.udata_comptime_value);
37883854 try wip_nav.refType(.fromInterned(err.ty));
3789 try uleb128(diw, try pt.getErrorValue(err.name));
3855 try dibw.writeLeb128(try pt.getErrorValue(err.name));
37903856 },
37913857 .error_union => |error_union| {
37923858 try wip_nav.abbrevCode(.aggregate_comptime_value);
......@@ -3798,8 +3864,8 @@ fn updateLazyValue(
37983864 {
37993865 try wip_nav.abbrevCode(.comptime_value_field_runtime_bits);
38003866 try wip_nav.strp("is_error");
3801 try uleb128(diw, err_abi_size);
3802 dwarf.writeInt(try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, err_abi_size), err_value);
3867 try dibw.writeLeb128(err_abi_size);
3868 try dwarf.writeIntTo(dibw, err_abi_size, err_value);
38033869 }
38043870 payload_field: switch (error_union.val) {
38053871 .err_name => {},
......@@ -3823,8 +3889,8 @@ fn updateLazyValue(
38233889 {
38243890 try wip_nav.abbrevCode(.comptime_value_field_runtime_bits);
38253891 try wip_nav.strp("error");
3826 try uleb128(diw, err_abi_size);
3827 dwarf.writeInt(try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, err_abi_size), err_value);
3892 try dibw.writeLeb128(err_abi_size);
3893 try dwarf.writeIntTo(dibw, err_abi_size, err_value);
38283894 }
38293895 switch (error_union.val) {
38303896 .err_name => {},
......@@ -3834,7 +3900,7 @@ fn updateLazyValue(
38343900 },
38353901 }
38363902 try wip_nav.refType(.fromInterned(error_union.ty));
3837 try uleb128(diw, @intFromEnum(AbbrevCode.null));
3903 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
38383904 },
38393905 .enum_literal => |enum_literal| {
38403906 try wip_nav.abbrevCode(.string_comptime_value);
......@@ -3855,24 +3921,24 @@ fn updateLazyValue(
38553921 switch (float.storage) {
38563922 .f16 => |f16_val| {
38573923 try wip_nav.abbrevCode(.data2_comptime_value);
3858 try diw.writeInt(u16, @bitCast(f16_val), dwarf.endian);
3924 try dibw.writeInt(u16, @bitCast(f16_val), dwarf.endian);
38593925 },
38603926 .f32 => |f32_val| {
38613927 try wip_nav.abbrevCode(.data4_comptime_value);
3862 try diw.writeInt(u32, @bitCast(f32_val), dwarf.endian);
3928 try dibw.writeInt(u32, @bitCast(f32_val), dwarf.endian);
38633929 },
38643930 .f64 => |f64_val| {
38653931 try wip_nav.abbrevCode(.data8_comptime_value);
3866 try diw.writeInt(u64, @bitCast(f64_val), dwarf.endian);
3932 try dibw.writeInt(u64, @bitCast(f64_val), dwarf.endian);
38673933 },
38683934 .f80 => |f80_val| {
38693935 try wip_nav.abbrevCode(.block_comptime_value);
3870 try uleb128(diw, @divExact(80, 8));
3871 try diw.writeInt(u80, @bitCast(f80_val), dwarf.endian);
3936 try dibw.writeUleb128(@divExact(80, 8));
3937 try dibw.writeInt(u80, @bitCast(f80_val), dwarf.endian);
38723938 },
38733939 .f128 => |f128_val| {
38743940 try wip_nav.abbrevCode(.data16_comptime_value);
3875 try diw.writeInt(u128, @bitCast(f128_val), dwarf.endian);
3941 try dibw.writeInt(u128, @bitCast(f128_val), dwarf.endian);
38763942 },
38773943 }
38783944 try wip_nav.refType(.fromInterned(float.ty));
......@@ -3889,14 +3955,14 @@ fn updateLazyValue(
38893955 const uav_ty: Type = .fromInterned(ip.typeOf(uav.val));
38903956 if (try uav_ty.onePossibleValue(pt)) |_| {
38913957 try wip_nav.abbrevCode(.udata_comptime_value);
3892 try uleb128(diw, ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment.toByteUnits() orelse
3958 try dibw.writeLeb128(ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment.toByteUnits() orelse
38933959 uav_ty.abiAlignment(zcu).toByteUnits().?);
38943960 break :location;
38953961 } else break try wip_nav.getValueEntry(.fromInterned(uav.val));
38963962 },
38973963 .int => {
38983964 try wip_nav.abbrevCode(.udata_comptime_value);
3899 try uleb128(diw, byte_offset);
3965 try dibw.writeLeb128(byte_offset);
39003966 break :location;
39013967 },
39023968 .eu_payload => |eu_ptr| {
......@@ -3935,7 +4001,7 @@ fn updateLazyValue(
39354001 try wip_nav.strp("len");
39364002 try wip_nav.blockValue(src_loc, .fromInterned(slice.len));
39374003 }
3938 try uleb128(diw, @intFromEnum(AbbrevCode.null));
4004 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
39394005 },
39404006 .opt => |opt| {
39414007 const opt_child_type: Type = .fromInterned(ip.indexToKey(opt.ty).opt_type);
......@@ -3945,7 +4011,7 @@ fn updateLazyValue(
39454011 try wip_nav.abbrevCode(.comptime_value_field_runtime_bits);
39464012 try wip_nav.strp("has_value");
39474013 switch (optRepr(opt_child_type, zcu)) {
3948 .opv_null => try uleb128(diw, 0),
4014 .opv_null => try dibw.writeUleb128(0),
39494015 .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)),
39504016 .error_set => try wip_nav.blockValue(src_loc, .fromInterned(value_index)),
39514017 .pointer => if (opt_child_type.comptimeOnly(zcu)) {
......@@ -3955,8 +4021,8 @@ fn updateLazyValue(
39554021 .none => 0,
39564022 else => opt_child_type.ptrAlignment(zcu).toByteUnits().?,
39574023 });
3958 try uleb128(diw, bytes.len);
3959 try diw.writeAll(bytes);
4024 try dibw.writeLeb128(bytes.len);
4025 try dibw.writeAll(bytes);
39604026 } else try wip_nav.blockValue(src_loc, .fromInterned(value_index)),
39614027 }
39624028 }
......@@ -3975,7 +4041,7 @@ fn updateLazyValue(
39754041 else
39764042 try wip_nav.blockValue(src_loc, .fromInterned(opt.val));
39774043 }
3978 try uleb128(diw, @intFromEnum(AbbrevCode.null));
4044 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
39794045 },
39804046 .aggregate => |aggregate| {
39814047 try wip_nav.abbrevCode(.aggregate_comptime_value);
......@@ -4060,7 +4126,7 @@ fn updateLazyValue(
40604126 },
40614127 else => unreachable,
40624128 }
4063 try uleb128(diw, @intFromEnum(AbbrevCode.null));
4129 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
40644130 },
40654131 .un => |un| {
40664132 try wip_nav.abbrevCode(.aggregate_comptime_value);
......@@ -4085,11 +4151,11 @@ fn updateLazyValue(
40854151 else
40864152 try wip_nav.blockValue(src_loc, .fromInterned(un.val));
40874153 }
4088 try uleb128(diw, @intFromEnum(AbbrevCode.null));
4154 try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
40894155 },
40904156 .memoized_call => unreachable, // not a value
40914157 }
4092 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
4158 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.getWritten());
40934159}
40944160
40954161fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum {
......@@ -4109,12 +4175,12 @@ fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum {
41094175 };
41104176}
41114177
4112pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternPool.Index) UpdateError!void {
4178fn updateContainerTypeInner(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternPool.Index) anyerror!void {
41134179 const zcu = pt.zcu;
41144180 const ip = &zcu.intern_pool;
41154181 const ty: Type = .fromInterned(type_index);
41164182 const ty_src_loc = ty.srcLoc(zcu);
4117 log.debug("updateContainerType({})", .{ty.fmt(pt)});
4183 log.debug("updateContainerType({f})", .{ty.fmt(pt)});
41184184
41194185 const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?;
41204186 const file = zcu.fileByIndex(inst_info.file);
......@@ -4432,29 +4498,31 @@ pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {
44324498 _ = nav_index;
44334499}
44344500
4435fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(AbbrevCode).@"enum".tag_type {
4501fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) anyerror!@typeInfo(AbbrevCode).@"enum".tag_type {
44364502 assert(abbrev_code != .null);
44374503 const entry: Entry.Index = @enumFromInt(@intFromEnum(abbrev_code));
44384504 if (dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).getEntry(entry).len > 0) return @intFromEnum(abbrev_code);
4439 var debug_abbrev: std.ArrayList(u8) = .init(dwarf.gpa);
4440 defer debug_abbrev.deinit();
4441 const daw = debug_abbrev.writer();
4505 var daaw: std.io.AllocatingWriter = undefined;
4506 daaw.init(dwarf.gpa);
4507 defer daaw.deinit();
4508 const dabw = &daaw.buffered_writer;
44424509 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
4443 try uleb128(daw, @intFromEnum(abbrev_code));
4444 try uleb128(daw, @intFromEnum(abbrev.tag));
4445 try daw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
4446 for (abbrev.attrs) |*attr| inline for (attr) |info| try uleb128(daw, @intFromEnum(info));
4447 for (0..2) |_| try uleb128(daw, 0);
4448 try dwarf.debug_abbrev.section.replaceEntry(DebugAbbrev.unit, entry, dwarf, debug_abbrev.items);
4510 try dabw.writeLeb128(@intFromEnum(abbrev_code));
4511 try dabw.writeLeb128(@intFromEnum(abbrev.tag));
4512 try dabw.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
4513 for (abbrev.attrs) |*attr| inline for (attr) |info| try dabw.writeLeb128(@intFromEnum(info));
4514 for (0..2) |_| try dabw.writeUleb128(0);
4515 try dwarf.debug_abbrev.section.replaceEntry(DebugAbbrev.unit, entry, dwarf, daaw.getWritten());
44494516 return @intFromEnum(abbrev_code);
44504517}
44514518
44524519pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
4520 const gpa = dwarf.gpa;
44534521 const zcu = pt.zcu;
44544522 const ip = &zcu.intern_pool;
44554523
44564524 {
4457 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type);
4525 const type_gop = try dwarf.types.getOrPut(gpa, .anyerror_type);
44584526 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main);
44594527 var wip_nav: WipNav = .{
44604528 .dwarf = dwarf,
......@@ -4467,14 +4535,15 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
44674535 .func_high_pc = undefined,
44684536 .blocks = undefined,
44694537 .cfi = undefined,
4470 .debug_frame = .empty,
4471 .debug_info = .empty,
4472 .debug_line = .empty,
4473 .debug_loclists = .empty,
4538 .debug_frame = undefined,
4539 .debug_info = undefined,
4540 .debug_line = undefined,
4541 .debug_loclists = undefined,
44744542 .pending_lazy = .empty,
44754543 };
4544 wip_nav.init();
44764545 defer wip_nav.deinit();
4477 const diw = wip_nav.debug_info.writer(dwarf.gpa);
4546 const dibw = &wip_nav.debug_info.buffered_writer;
44784547 const global_error_set_names = ip.global_error_set.getNamesFromMainThread();
44794548 try wip_nav.abbrevCode(if (global_error_set_names.len == 0) .generated_empty_enum_type else .generated_enum_type);
44804549 try wip_nav.strp("anyerror");
......@@ -4484,50 +4553,52 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
44844553 } })));
44854554 for (global_error_set_names, 1..) |name, value| {
44864555 try wip_nav.abbrevCode(.unsigned_enum_field);
4487 try uleb128(diw, value);
4556 try dibw.writeLeb128(value);
44884557 try wip_nav.strp(name.toSlice(ip));
44894558 }
4490 if (global_error_set_names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
4491 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
4559 if (global_error_set_names.len > 0) try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
4560 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, dibw.getWritten());
44924561 try wip_nav.updateLazy(.unneeded);
44934562 }
44944563
44954564 for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
4496 const root_dir_path = try mod.root.toAbsolute(zcu.comp.dirs, dwarf.gpa);
4497 defer dwarf.gpa.free(root_dir_path);
4565 const root_dir_path = try mod.root.toAbsolute(zcu.comp.dirs, gpa);
4566 defer gpa.free(root_dir_path);
44984567 mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path);
44994568 }
45004569
4501 var header: std.ArrayList(u8) = .init(dwarf.gpa);
4502 defer header.deinit();
4570 var header: std.ArrayListUnmanaged(u8) = .empty;
4571 defer header.deinit(gpa);
4572 var header_bw: std.io.BufferedWriter = undefined;
45034573 if (dwarf.debug_aranges.section.dirty) {
45044574 for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
45054575 const unit: Unit.Index = @enumFromInt(unit_index);
45064576 unit_ptr.clear();
4507 try unit_ptr.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 1);
4508 header.clearRetainingCapacity();
4509 try header.ensureTotalCapacity(unit_ptr.header_len);
4577 try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 1);
4578 try header.resize(gpa, unit_ptr.header_len);
4579 header_bw.initFixed(header.items);
45104580 const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
45114581 dwarf.debug_aranges.section.getUnit(next_unit).off
45124582 else
45134583 dwarf.debug_aranges.section.len) - unit_ptr.off - dwarf.unitLengthBytes();
45144584 switch (dwarf.format) {
4515 .@"32" => std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), @intCast(unit_len), dwarf.endian),
4585 .@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
45164586 .@"64" => {
4517 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian);
4518 std.mem.writeInt(u64, header.addManyAsArrayAssumeCapacity(8), unit_len, dwarf.endian);
4587 header_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable;
4588 header_bw.writeInt(u64, unit_len, dwarf.endian) catch unreachable;
45194589 },
45204590 }
4521 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(2), 2, dwarf.endian);
4591 header_bw.writeInt(u16, 2, dwarf.endian) catch unreachable;
45224592 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4523 .source_off = @intCast(header.items.len),
4593 .source_off = @intCast(header_bw.end),
45244594 .target_sec = .debug_info,
45254595 .target_unit = unit,
45264596 });
4527 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4528 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
4529 header.appendNTimesAssumeCapacity(0, unit_ptr.header_len - header.items.len);
4530 try unit_ptr.replaceHeader(&dwarf.debug_aranges.section, dwarf, header.items);
4597 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
4598 header_bw.writeAll(&.{ @intFromEnum(dwarf.address_size), 0 }) catch unreachable;
4599 header_bw.splatByteAll(0, unit_ptr.header_len - header_bw.end) catch unreachable;
4600 assert(header_bw.end == header_bw.buffer.len);
4601 try unit_ptr.replaceHeader(&dwarf.debug_aranges.section, dwarf, header_bw.buffer);
45314602 try unit_ptr.writeTrailer(&dwarf.debug_aranges.section, dwarf);
45324603 }
45334604 dwarf.debug_aranges.section.dirty = false;
......@@ -4542,31 +4613,33 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
45424613 dev.check(.x86_64_backend);
45434614 const Register = @import("../arch/x86_64/bits.zig").Register;
45444615 for (dwarf.debug_frame.section.units.items) |*unit| {
4545 header.clearRetainingCapacity();
4546 try header.ensureTotalCapacity(unit.header_len);
4616 try header.resize(gpa, unit.header_len);
4617 header_bw.initFixed(header.items);
45474618 const unit_len = unit.header_len - dwarf.unitLengthBytes();
45484619 switch (dwarf.format) {
4549 .@"32" => std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), @intCast(unit_len), dwarf.endian),
4620 .@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
45504621 .@"64" => {
4551 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian);
4552 std.mem.writeInt(u64, header.addManyAsArrayAssumeCapacity(8), unit_len, dwarf.endian);
4622 header_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable;
4623 header_bw.writeInt(u64, unit_len, dwarf.endian) catch unreachable;
45534624 },
45544625 }
4555 header.appendNTimesAssumeCapacity(0, 4);
4556 header.appendAssumeCapacity(1);
4557 header.appendSliceAssumeCapacity("zR\x00");
4558 uleb128(header.fixedWriter(), dwarf.debug_frame.header.code_alignment_factor) catch unreachable;
4559 sleb128(header.fixedWriter(), dwarf.debug_frame.header.data_alignment_factor) catch unreachable;
4560 uleb128(header.fixedWriter(), dwarf.debug_frame.header.return_address_register) catch unreachable;
4561 uleb128(header.fixedWriter(), 1) catch unreachable;
4562 header.appendAssumeCapacity(DW.EH.PE.pcrel | DW.EH.PE.sdata4);
4563 header.appendAssumeCapacity(DW.CFA.def_cfa_sf);
4564 uleb128(header.fixedWriter(), Register.rsp.dwarfNum()) catch unreachable;
4565 sleb128(header.fixedWriter(), -1) catch unreachable;
4566 header.appendAssumeCapacity(@as(u8, DW.CFA.offset) + Register.rip.dwarfNum());
4567 uleb128(header.fixedWriter(), 1) catch unreachable;
4568 header.appendNTimesAssumeCapacity(DW.CFA.nop, unit.header_len - header.items.len);
4569 try unit.replaceHeader(&dwarf.debug_frame.section, dwarf, header.items);
4626 header_bw.splatByteAll(0, 4) catch unreachable;
4627 header_bw.writeByte(1) catch unreachable;
4628 header_bw.writeAll("zR\x00") catch unreachable;
4629 header_bw.writeLeb128(dwarf.debug_frame.header.code_alignment_factor) catch unreachable;
4630 header_bw.writeLeb128(dwarf.debug_frame.header.data_alignment_factor) catch unreachable;
4631 header_bw.writeLeb128(dwarf.debug_frame.header.return_address_register) catch unreachable;
4632 header_bw.writeUleb128(1) catch unreachable;
4633 header_bw.writeByte(DW.EH.PE.pcrel | DW.EH.PE.sdata4) catch unreachable;
4634 header_bw.writeByte(DW.CFA.def_cfa_sf) catch unreachable;
4635 header_bw.writeUleb128(1) catch unreachable;
4636 header_bw.writeLeb128(Register.rsp.dwarfNum()) catch unreachable;
4637 header_bw.writeSleb128(-1) catch unreachable;
4638 header_bw.writeByte(@as(u8, DW.CFA.offset) + Register.rip.dwarfNum()) catch unreachable;
4639 header_bw.writeUleb128(1) catch unreachable;
4640 header_bw.splatByteAll(DW.CFA.nop, unit.header_len - header_bw.end) catch unreachable;
4641 assert(header_bw.end == header_bw.buffer.len);
4642 try unit.replaceHeader(&dwarf.debug_frame.section, dwarf, header_bw.buffer);
45704643 try unit.writeTrailer(&dwarf.debug_frame.section, dwarf);
45714644 }
45724645 },
......@@ -4579,83 +4652,84 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
45794652 for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| {
45804653 const unit: Unit.Index = @enumFromInt(unit_index);
45814654 unit_ptr.clear();
4582 try unit_ptr.cross_unit_relocs.ensureTotalCapacity(dwarf.gpa, 1);
4583 try unit_ptr.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, 7);
4584 header.clearRetainingCapacity();
4585 try header.ensureTotalCapacity(unit_ptr.header_len);
4655 try unit_ptr.cross_unit_relocs.ensureTotalCapacity(gpa, 1);
4656 try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 7);
4657 try header.resize(gpa, unit_ptr.header_len);
4658 header_bw.initFixed(header.items);
45864659 const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
45874660 dwarf.debug_info.section.getUnit(next_unit).off
45884661 else
45894662 dwarf.debug_info.section.len) - unit_ptr.off - dwarf.unitLengthBytes();
45904663 switch (dwarf.format) {
4591 .@"32" => std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), @intCast(unit_len), dwarf.endian),
4664 .@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
45924665 .@"64" => {
4593 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian);
4594 std.mem.writeInt(u64, header.addManyAsArrayAssumeCapacity(8), unit_len, dwarf.endian);
4666 header_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable;
4667 header_bw.writeInt(u64, unit_len, dwarf.endian) catch unreachable;
45954668 },
45964669 }
4597 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(2), 5, dwarf.endian);
4598 header.appendSliceAssumeCapacity(&.{ DW.UT.compile, @intFromEnum(dwarf.address_size) });
4670 header_bw.writeInt(u16, 5, dwarf.endian) catch unreachable;
4671 header_bw.writeAll(&.{ DW.UT.compile, @intFromEnum(dwarf.address_size) }) catch unreachable;
45994672 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4600 .source_off = @intCast(header.items.len),
4673 .source_off = @intCast(header_bw.end),
46014674 .target_sec = .debug_abbrev,
46024675 .target_unit = DebugAbbrev.unit,
46034676 });
4604 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4605 const compile_unit_off: u32 = @intCast(header.items.len);
4606 uleb128(header.fixedWriter(), try dwarf.refAbbrevCode(.compile_unit)) catch unreachable;
4607 header.appendAssumeCapacity(DW.LANG.Zig);
4677 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
4678 const compile_unit_off: u32 = @intCast(header_bw.end);
4679 header_bw.writeLeb128(try dwarf.refAbbrevCode(.compile_unit)) catch unreachable;
4680 header_bw.writeByte(DW.LANG.Zig) catch unreachable;
46084681 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4609 .source_off = @intCast(header.items.len),
4682 .source_off = @intCast(header_bw.end),
46104683 .target_sec = .debug_line_str,
46114684 .target_unit = StringSection.unit,
46124685 .target_entry = (try dwarf.debug_line_str.addString(dwarf, "zig " ++ @import("build_options").version)).toOptional(),
46134686 });
4614 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4687 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
46154688 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4616 .source_off = @intCast(header.items.len),
4689 .source_off = @intCast(header_bw.end),
46174690 .target_sec = .debug_line_str,
46184691 .target_unit = StringSection.unit,
46194692 .target_entry = mod_info.root_dir_path.toOptional(),
46204693 });
4621 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4694 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
46224695 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4623 .source_off = @intCast(header.items.len),
4696 .source_off = @intCast(header_bw.end),
46244697 .target_sec = .debug_line_str,
46254698 .target_unit = StringSection.unit,
46264699 .target_entry = (try dwarf.debug_line_str.addString(dwarf, mod.root_src_path)).toOptional(),
46274700 });
4628 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4701 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
46294702 unit_ptr.cross_unit_relocs.appendAssumeCapacity(.{
4630 .source_off = @intCast(header.items.len),
4703 .source_off = @intCast(header_bw.end),
46314704 .target_unit = .main,
46324705 .target_off = compile_unit_off,
46334706 });
4634 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4707 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
46354708 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4636 .source_off = @intCast(header.items.len),
4709 .source_off = @intCast(header_bw.end),
46374710 .target_sec = .debug_line,
46384711 .target_unit = unit,
46394712 });
4640 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4713 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
46414714 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4642 .source_off = @intCast(header.items.len),
4715 .source_off = @intCast(header_bw.end),
46434716 .target_sec = .debug_rnglists,
46444717 .target_unit = unit,
46454718 .target_off = DebugRngLists.baseOffset(dwarf),
46464719 });
4647 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4648 uleb128(header.fixedWriter(), 0) catch unreachable;
4649 uleb128(header.fixedWriter(), try dwarf.refAbbrevCode(.module)) catch unreachable;
4720 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
4721 header_bw.writeUleb128(0) catch unreachable;
4722 header_bw.writeLeb128(try dwarf.refAbbrevCode(.module)) catch unreachable;
46504723 unit_ptr.cross_section_relocs.appendAssumeCapacity(.{
4651 .source_off = @intCast(header.items.len),
4724 .source_off = @intCast(header_bw.end),
46524725 .target_sec = .debug_str,
46534726 .target_unit = StringSection.unit,
46544727 .target_entry = (try dwarf.debug_str.addString(dwarf, mod.fully_qualified_name)).toOptional(),
46554728 });
4656 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4657 uleb128(header.fixedWriter(), 0) catch unreachable;
4658 try unit_ptr.replaceHeader(&dwarf.debug_info.section, dwarf, header.items);
4729 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
4730 header_bw.writeUleb128(0) catch unreachable;
4731 assert(header_bw.end == header_bw.buffer.len);
4732 try unit_ptr.replaceHeader(&dwarf.debug_info.section, dwarf, header_bw.buffer);
46594733 try unit_ptr.writeTrailer(&dwarf.debug_info.section, dwarf);
46604734 }
46614735 dwarf.debug_info.section.dirty = false;
......@@ -4679,33 +4753,37 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
46794753 );
46804754 for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| {
46814755 unit.clear();
4682 try unit.cross_section_relocs.ensureTotalCapacity(dwarf.gpa, mod_info.dirs.count() + 2 * (mod_info.files.count()));
4683 header.clearRetainingCapacity();
4684 try header.ensureTotalCapacity(unit.header_len);
4756 try unit.cross_section_relocs.ensureTotalCapacity(gpa, mod_info.dirs.count() + 2 * (mod_info.files.count()));
4757 try header.resize(gpa, unit.header_len);
4758 header_bw.initFixed(header.items);
46854759 const unit_len = (if (unit.next.unwrap()) |next_unit|
46864760 dwarf.debug_line.section.getUnit(next_unit).off
46874761 else
46884762 dwarf.debug_line.section.len) - unit.off - dwarf.unitLengthBytes();
46894763 switch (dwarf.format) {
4690 .@"32" => std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), @intCast(unit_len), dwarf.endian),
4764 .@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
46914765 .@"64" => {
4692 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian);
4693 std.mem.writeInt(u64, header.addManyAsArrayAssumeCapacity(8), unit_len, dwarf.endian);
4766 header_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable;
4767 header_bw.writeInt(u64, unit_len, dwarf.endian) catch unreachable;
46944768 },
46954769 }
4696 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(2), 5, dwarf.endian);
4697 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
4698 dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), unit.header_len - header.items.len);
4770 header_bw.writeInt(u16, 5, dwarf.endian) catch unreachable;
4771 header_bw.writeAll(&.{ @intFromEnum(dwarf.address_size), 0 }) catch unreachable;
4772 dwarf.writeIntTo(
4773 &header_bw,
4774 dwarf.sectionOffsetBytes(),
4775 unit.header_len - header_bw.end,
4776 ) catch unreachable;
46994777 const StandardOpcode = DeclValEnum(DW.LNS);
4700 header.appendSliceAssumeCapacity(&[_]u8{
4778 header_bw.writeAll(&.{
47014779 dwarf.debug_line.header.minimum_instruction_length,
47024780 dwarf.debug_line.header.maximum_operations_per_instruction,
47034781 @intFromBool(dwarf.debug_line.header.default_is_stmt),
47044782 @bitCast(dwarf.debug_line.header.line_base),
47054783 dwarf.debug_line.header.line_range,
47064784 dwarf.debug_line.header.opcode_base,
4707 });
4708 header.appendSliceAssumeCapacity(std.enums.EnumArray(StandardOpcode, u8).init(.{
4785 }) catch unreachable;
4786 header_bw.writeAll(std.enums.EnumArray(StandardOpcode, u8).init(.{
47094787 .extended_op = undefined,
47104788 .copy = 0,
47114789 .advance_pc = 1,
......@@ -4719,44 +4797,45 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
47194797 .set_prologue_end = 0,
47204798 .set_epilogue_begin = 0,
47214799 .set_isa = 1,
4722 }).values[1..dwarf.debug_line.header.opcode_base]);
4723 header.appendAssumeCapacity(1);
4724 uleb128(header.fixedWriter(), DW.LNCT.path) catch unreachable;
4725 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
4726 uleb128(header.fixedWriter(), mod_info.dirs.count()) catch unreachable;
4800 }).values[1..dwarf.debug_line.header.opcode_base]) catch unreachable;
4801 header_bw.writeByte(1) catch unreachable;
4802 header_bw.writeLeb128(@as(u14, DW.LNCT.path)) catch unreachable;
4803 header_bw.writeLeb128(@as(u13, DW.FORM.line_strp)) catch unreachable;
4804 header_bw.writeLeb128(mod_info.dirs.count()) catch unreachable;
47274805 for (mod_info.dirs.keys()) |dir_unit| {
47284806 unit.cross_section_relocs.appendAssumeCapacity(.{
4729 .source_off = @intCast(header.items.len),
4807 .source_off = @intCast(header_bw.end),
47304808 .target_sec = .debug_line_str,
47314809 .target_unit = StringSection.unit,
47324810 .target_entry = dwarf.getModInfo(dir_unit).root_dir_path.toOptional(),
47334811 });
4734 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4812 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
47354813 }
47364814 const dir_index_info = DebugLine.dirIndexInfo(@intCast(mod_info.dirs.count()));
4737 header.appendAssumeCapacity(3);
4738 uleb128(header.fixedWriter(), DW.LNCT.path) catch unreachable;
4739 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
4740 uleb128(header.fixedWriter(), DW.LNCT.directory_index) catch unreachable;
4741 uleb128(header.fixedWriter(), @intFromEnum(dir_index_info.form)) catch unreachable;
4742 uleb128(header.fixedWriter(), DW.LNCT.LLVM_source) catch unreachable;
4743 uleb128(header.fixedWriter(), DW.FORM.line_strp) catch unreachable;
4744 uleb128(header.fixedWriter(), mod_info.files.count()) catch unreachable;
4815 header_bw.writeByte(3) catch unreachable;
4816 header_bw.writeLeb128(@as(u14, DW.LNCT.path)) catch unreachable;
4817 header_bw.writeLeb128(@as(u13, DW.FORM.line_strp)) catch unreachable;
4818 header_bw.writeLeb128(@as(u14, DW.LNCT.directory_index)) catch unreachable;
4819 header_bw.writeLeb128(@intFromEnum(dir_index_info.form)) catch unreachable;
4820 header_bw.writeLeb128(@as(u14, DW.LNCT.LLVM_source)) catch unreachable;
4821 header_bw.writeLeb128(@as(u13, DW.FORM.line_strp)) catch unreachable;
4822 header_bw.writeLeb128(mod_info.files.count()) catch unreachable;
47454823 for (mod_info.files.keys()) |file_index| {
47464824 const file = zcu.fileByIndex(file_index);
47474825 unit.cross_section_relocs.appendAssumeCapacity(.{
4748 .source_off = @intCast(header.items.len),
4826 .source_off = @intCast(header_bw.end),
47494827 .target_sec = .debug_line_str,
47504828 .target_unit = StringSection.unit,
47514829 .target_entry = (try dwarf.debug_line_str.addString(dwarf, file.sub_file_path)).toOptional(),
47524830 });
47534831 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4754 dwarf.writeInt(
4755 header.addManyAsSliceAssumeCapacity(dir_index_info.bytes),
4832 dwarf.writeIntTo(
4833 &header_bw,
4834 dir_index_info.bytes,
47564835 mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod.?).?) orelse 0,
47574836 );
47584837 unit.cross_section_relocs.appendAssumeCapacity(.{
4759 .source_off = @intCast(header.items.len),
4838 .source_off = @intCast(header_bw.end),
47604839 .target_sec = .debug_line_str,
47614840 .target_unit = StringSection.unit,
47624841 .target_entry = (try dwarf.debug_line_str.addString(
......@@ -4764,9 +4843,10 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
47644843 if (file.is_builtin) file.source.? else "",
47654844 )).toOptional(),
47664845 });
4767 header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes());
4846 header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable;
47684847 }
4769 try unit.replaceHeader(&dwarf.debug_line.section, dwarf, header.items);
4848 assert(header_bw.end == header_bw.buffer.len);
4849 try unit.replaceHeader(&dwarf.debug_line.section, dwarf, header_bw.buffer);
47704850 try unit.writeTrailer(&dwarf.debug_line.section, dwarf);
47714851 }
47724852 dwarf.debug_line.section.dirty = false;
......@@ -4782,24 +4862,25 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
47824862 }
47834863 if (dwarf.debug_rnglists.section.dirty) {
47844864 for (dwarf.debug_rnglists.section.units.items) |*unit| {
4785 header.clearRetainingCapacity();
4786 try header.ensureTotalCapacity(unit.header_len);
4865 try header.resize(gpa, unit.header_len);
4866 header_bw.initFixed(header.items);
47874867 const unit_len = (if (unit.next.unwrap()) |next_unit|
47884868 dwarf.debug_rnglists.section.getUnit(next_unit).off
47894869 else
47904870 dwarf.debug_rnglists.section.len) - unit.off - dwarf.unitLengthBytes();
47914871 switch (dwarf.format) {
4792 .@"32" => std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), @intCast(unit_len), dwarf.endian),
4872 .@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
47934873 .@"64" => {
4794 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), std.math.maxInt(u32), dwarf.endian);
4795 std.mem.writeInt(u64, header.addManyAsArrayAssumeCapacity(8), unit_len, dwarf.endian);
4874 header_bw.writeInt(u32, std.math.maxInt(u32), dwarf.endian) catch unreachable;
4875 header_bw.writeInt(u64, unit_len, dwarf.endian) catch unreachable;
47964876 },
47974877 }
4798 std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(2), 5, dwarf.endian);
4799 header.appendSliceAssumeCapacity(&.{ @intFromEnum(dwarf.address_size), 0 });
4800 std.mem.writeInt(u32, header.addManyAsArrayAssumeCapacity(4), 1, dwarf.endian);
4801 dwarf.writeInt(header.addManyAsSliceAssumeCapacity(dwarf.sectionOffsetBytes()), dwarf.sectionOffsetBytes() * 1);
4802 try unit.replaceHeader(&dwarf.debug_rnglists.section, dwarf, header.items);
4878 header_bw.writeInt(u16, 5, dwarf.endian) catch unreachable;
4879 header_bw.writeAll(&.{ @intFromEnum(dwarf.address_size), 0 }) catch unreachable;
4880 header_bw.writeInt(u32, 1, dwarf.endian) catch unreachable;
4881 dwarf.writeIntTo(&header_bw, dwarf.sectionOffsetBytes(), dwarf.sectionOffsetBytes() * 1) catch unreachable;
4882 assert(header_bw.end == header_bw.buffer.len);
4883 try unit.replaceHeader(&dwarf.debug_rnglists.section, dwarf, header_bw.buffer);
48034884 try unit.writeTrailer(&dwarf.debug_rnglists.section, dwarf);
48044885 }
48054886 dwarf.debug_rnglists.section.dirty = false;
......@@ -4815,6 +4896,9 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
48154896 assert(!dwarf.debug_str.section.dirty);
48164897}
48174898
4899const sleb128 = {};
4900const uleb128 = {};
4901
48184902pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void {
48194903 for ([_]*Section{
48204904 &dwarf.debug_abbrev.section,
......@@ -5979,7 +6063,7 @@ fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {
59796063 return entry;
59806064}
59816065
5982fn freeCommonEntry(dwarf: *Dwarf, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
6066fn freeCommonEntry(dwarf: *Dwarf, unit: Unit.Index, entry: Entry.Index) anyerror!void {
59836067 try dwarf.debug_aranges.section.freeEntry(unit, entry, dwarf);
59846068 try dwarf.debug_frame.section.freeEntry(unit, entry, dwarf);
59856069 try dwarf.debug_info.section.freeEntry(unit, entry, dwarf);
......@@ -5998,6 +6082,11 @@ fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void {
59986082 }
59996083}
60006084
6085fn writeIntTo(dwarf: *Dwarf, bw: *std.io.BufferedWriter, len: usize, int: u64) anyerror!void {
6086 dwarf.writeInt((try bw.writableSlice(len))[0..len], int);
6087 bw.advance(len);
6088}
6089
60016090fn resolveReloc(dwarf: *Dwarf, source: u64, target: u64, size: u32) RelocError!void {
60026091 var buf: [8]u8 = undefined;
60036092 dwarf.writeInt(buf[0..size], target);
......@@ -6019,21 +6108,34 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 {
60196108}
60206109
60216110fn uleb128Bytes(value: anytype) u32 {
6022 var buffer: [std.atomic.cache_line]u8 = undefined;
6023 var bw: std.io.BufferedWriter = .{
6024 .unbuffered_writer = .null,
6025 .buffer = .initBuffer(&buffer),
6026 };
6027 return try std.leb.writeUleb128Count(&bw, value);
6111 return leb128Bytes(switch (@typeInfo(@TypeOf(value))) {
6112 .comptime_int => @as(std.math.IntFittingRange(0, @abs(value)), value),
6113 .int => |value_info| switch (value_info.signedness) {
6114 .signed => @as(@Type(.{ .int = .{ .signedness = .unsigned, .bits = value_info.bits -| 1 } }), @intCast(value)),
6115 .unsigned => value,
6116 },
6117 else => comptime unreachable,
6118 });
60286119}
6029
60306120fn sleb128Bytes(value: anytype) u32 {
6031 var buffer: [std.atomic.cache_line]u8 = undefined;
6032 var bw: std.io.BufferedWriter = .{
6033 .unbuffered_writer = .null,
6034 .buffer = .initBuffer(&buffer),
6035 };
6036 return try std.leb.writeIleb128Count(&bw, value);
6121 return leb128Bytes(switch (@typeInfo(@TypeOf(value))) {
6122 .comptime_int => @as(std.math.IntFittingRange(@min(value, -1), @max(0, value)), value),
6123 .int => |value_info| switch (value_info.signedness) {
6124 .signed => value,
6125 .unsigned => @as(@Type(.{ .int = .{ .signedness = .signed, .bits = value_info.bits + 1 } }), value),
6126 },
6127 else => comptime unreachable,
6128 });
6129}
6130fn leb128Bytes(value: anytype) u32 {
6131 const value_info = @typeInfo(@TypeOf(value)).int;
6132 var buffer: [
6133 std.math.divCeil(u16, @intFromBool(value_info.signedness == .signed) + value_info.bits, 7) catch unreachable
6134 ]u8 = undefined;
6135 var bw: std.io.BufferedWriter = undefined;
6136 bw.initFixed(&buffer);
6137 bw.writeLeb128(value) catch unreachable;
6138 return @intCast(bw.end);
60376139}
60386140
60396141/// overrides `-fno-incremental` for testing incremental debug info until `-fincremental` is functional
......@@ -6055,7 +6157,5 @@ const codegen = @import("../codegen.zig");
60556157const dev = @import("../dev.zig");
60566158const link = @import("../link.zig");
60576159const log = std.log.scoped(.dwarf);
6058const sleb128 = std.leb.writeIleb128;
60596160const std = @import("std");
60606161const target_info = @import("../target.zig");
6061const uleb128 = std.leb.writeUleb128;
src/link/Elf.zig+132-143
......@@ -702,7 +702,7 @@ pub fn allocateChunk(self: *Elf, args: struct {
702702 shdr.sh_addr + res.value,
703703 shdr.sh_offset + res.value,
704704 });
705 log.debug(" placement {}, {s}", .{
705 log.debug(" placement {f}, {s}", .{
706706 res.placement,
707707 if (self.atom(res.placement)) |atom_ptr| atom_ptr.name(self) else "",
708708 });
......@@ -869,7 +869,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
869869 // Dump the state for easy debugging.
870870 // State can be dumped via `--debug-log link_state`.
871871 if (build_options.enable_logging) {
872 state_log.debug("{}", .{self.dumpState()});
872 state_log.debug("{f}", .{self.dumpState()});
873873 }
874874
875875 // Beyond this point, everything has been allocated a virtual address and we can resolve
......@@ -1849,7 +1849,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void {
18491849
18501850pub fn writeMergeSections(self: *Elf) !void {
18511851 const gpa = self.base.comp.gpa;
1852 var buffer = std.ArrayList(u8).init(gpa);
1852 var buffer: std.ArrayList(u8) = .init(gpa);
18531853 defer buffer.deinit();
18541854
18551855 for (self.merge_sections.items) |*msec| {
......@@ -2996,7 +2996,7 @@ fn allocateSpecialPhdrs(self: *Elf) void {
29962996 }
29972997}
29982998
2999fn writeAtoms(self: *Elf) !void {
2999fn writeAtoms(self: *Elf) anyerror!void {
30003000 const gpa = self.base.comp.gpa;
30013001
30023002 var undefs: std.AutoArrayHashMap(SymbolResolver.Index, std.ArrayList(Ref)) = .init(gpa);
......@@ -3005,7 +3005,7 @@ fn writeAtoms(self: *Elf) !void {
30053005 undefs.deinit();
30063006 }
30073007
3008 var buffer = std.ArrayList(u8).init(gpa);
3008 var buffer: std.ArrayList(u8) = .init(gpa);
30093009 defer buffer.deinit();
30103010
30113011 const slice = self.sections.slice();
......@@ -3028,14 +3028,14 @@ fn writeAtoms(self: *Elf) !void {
30283028
30293029 if (self.requiresThunks()) {
30303030 for (self.thunks.items) |th| {
3031 const thunk_size = th.size(self);
3032 try buffer.ensureUnusedCapacity(thunk_size);
3031 try buffer.resize(th.size(self));
3032 var bw: std.io.BufferedWriter = undefined;
3033 bw.initFixed(buffer.items);
30333034 const shdr = slice.items(.shdr)[th.output_section_index];
30343035 const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset;
3035 try th.write(self, buffer.writer());
3036 assert(buffer.items.len == thunk_size);
3037 try self.pwriteAll(buffer.items, offset);
3038 buffer.clearRetainingCapacity();
3036 try th.write(self, &bw);
3037 assert(bw.end == bw.buffer.len);
3038 try self.pwriteAll(bw.buffer, offset);
30393039 }
30403040 }
30413041}
......@@ -3130,32 +3130,36 @@ pub fn updateSymtabSize(self: *Elf) !void {
31303130 strtab.sh_size = strsize + 1;
31313131}
31323132
3133fn writeSyntheticSections(self: *Elf) !void {
3133fn writeSyntheticSections(self: *Elf) anyerror!void {
31343134 const gpa = self.base.comp.gpa;
31353135 const slice = self.sections.slice();
31363136
3137 var buffer: std.ArrayListUnmanaged(u8) = .empty;
3138 defer buffer.deinit(gpa);
3139 var bw: std.io.BufferedWriter = undefined;
3140
31373141 if (self.section_indexes.interp) |shndx| {
3138 var buffer: [256]u8 = undefined;
3139 const interp = self.getTarget().dynamic_linker.get().?;
3140 @memcpy(buffer[0..interp.len], interp);
3141 buffer[interp.len] = 0;
3142 const contents = buffer[0 .. interp.len + 1];
31433142 const shdr = slice.items(.shdr)[shndx];
3144 assert(shdr.sh_size == contents.len);
3145 try self.pwriteAll(contents, shdr.sh_offset);
3143 const interp = self.getTarget().dynamic_linker.get().?;
3144 assert(shdr.sh_size == interp.len + 1);
3145 try buffer.resize(gpa, shdr.sh_size);
3146 @memcpy(buffer.items[0..interp.len], interp);
3147 buffer.items[interp.len] = 0;
3148 try self.pwriteAll(buffer.items, shdr.sh_offset);
31463149 }
31473150
31483151 if (self.section_indexes.hash) |shndx| {
31493152 const shdr = slice.items(.shdr)[shndx];
3150 try self.pwriteAll(self.hash.buffer.items, shdr.sh_offset);
3153 try self.pwriteAll(@ptrCast(self.hash.buffer), shdr.sh_offset);
31513154 }
31523155
31533156 if (self.section_indexes.gnu_hash) |shndx| {
31543157 const shdr = slice.items(.shdr)[shndx];
3155 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size());
3156 defer buffer.deinit();
3157 try self.gnu_hash.write(self, buffer.writer());
3158 try self.pwriteAll(buffer.items, shdr.sh_offset);
3158 try buffer.resize(gpa, self.gnu_hash.size());
3159 bw.initFixed(buffer.items);
3160 try self.gnu_hash.write(self, &bw);
3161 assert(bw.end == bw.buffer.len);
3162 try self.pwriteAll(bw.buffer, shdr.sh_offset);
31593163 }
31603164
31613165 if (self.section_indexes.versym) |shndx| {
......@@ -3165,26 +3169,29 @@ fn writeSyntheticSections(self: *Elf) !void {
31653169
31663170 if (self.section_indexes.verneed) |shndx| {
31673171 const shdr = slice.items(.shdr)[shndx];
3168 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size());
3169 defer buffer.deinit();
3170 try self.verneed.write(buffer.writer());
3171 try self.pwriteAll(buffer.items, shdr.sh_offset);
3172 try buffer.resize(gpa, self.verneed.size());
3173 bw.initFixed(buffer.items);
3174 try self.verneed.write(&bw);
3175 assert(bw.end == bw.buffer.len);
3176 try self.pwriteAll(bw.buffer, shdr.sh_offset);
31723177 }
31733178
31743179 if (self.section_indexes.dynamic) |shndx| {
31753180 const shdr = slice.items(.shdr)[shndx];
3176 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self));
3177 defer buffer.deinit();
3178 try self.dynamic.write(self, buffer.writer());
3179 try self.pwriteAll(buffer.items, shdr.sh_offset);
3181 try buffer.resize(gpa, self.dynamic.size(self));
3182 bw.initFixed(buffer.items);
3183 try self.dynamic.write(self, &bw);
3184 assert(bw.end == bw.buffer.len);
3185 try self.pwriteAll(bw.buffer, shdr.sh_offset);
31803186 }
31813187
31823188 if (self.section_indexes.dynsymtab) |shndx| {
31833189 const shdr = slice.items(.shdr)[shndx];
3184 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size());
3185 defer buffer.deinit();
3186 try self.dynsym.write(self, buffer.writer());
3187 try self.pwriteAll(buffer.items, shdr.sh_offset);
3190 try buffer.resize(gpa, self.dynsym.size());
3191 bw.initFixed(buffer.items);
3192 try self.dynsym.write(self, &bw);
3193 assert(bw.end == bw.buffer.len);
3194 try self.pwriteAll(bw.buffer, shdr.sh_offset);
31883195 }
31893196
31903197 if (self.section_indexes.dynstrtab) |shndx| {
......@@ -3200,28 +3207,30 @@ fn writeSyntheticSections(self: *Elf) !void {
32003207 };
32013208 const shdr = slice.items(.shdr)[shndx];
32023209 const sh_size = try self.cast(usize, shdr.sh_size);
3203 var buffer = try std.ArrayList(u8).initCapacity(gpa, @intCast(sh_size - existing_size));
3204 defer buffer.deinit();
3205 try eh_frame.writeEhFrame(self, buffer.writer());
3206 assert(buffer.items.len == sh_size - existing_size);
3207 try self.pwriteAll(buffer.items, shdr.sh_offset + existing_size);
3210 try buffer.resize(gpa, @intCast(sh_size - existing_size));
3211 bw.initFixed(buffer.items);
3212 try eh_frame.writeEhFrame(self, &bw);
3213 assert(bw.end == bw.buffer.len);
3214 try self.pwriteAll(bw.buffer, shdr.sh_offset + existing_size);
32083215 }
32093216
32103217 if (self.section_indexes.eh_frame_hdr) |shndx| {
32113218 const shdr = slice.items(.shdr)[shndx];
32123219 const sh_size = try self.cast(usize, shdr.sh_size);
3213 var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
3214 defer buffer.deinit();
3215 try eh_frame.writeEhFrameHdr(self, buffer.writer());
3216 try self.pwriteAll(buffer.items, shdr.sh_offset);
3220 try buffer.resize(gpa, sh_size);
3221 bw.initFixed(buffer.items);
3222 try eh_frame.writeEhFrameHdr(self, &bw);
3223 assert(bw.end == bw.buffer.len);
3224 try self.pwriteAll(bw.buffer, shdr.sh_offset);
32173225 }
32183226
32193227 if (self.section_indexes.got) |index| {
32203228 const shdr = slice.items(.shdr)[index];
3221 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self));
3222 defer buffer.deinit();
3223 try self.got.write(self, buffer.writer());
3224 try self.pwriteAll(buffer.items, shdr.sh_offset);
3229 try buffer.resize(gpa, self.got.size(self));
3230 bw.initFixed(buffer.items);
3231 try self.got.write(self, &bw);
3232 assert(bw.end == bw.buffer.len);
3233 try self.pwriteAll(bw.buffer, shdr.sh_offset);
32253234 }
32263235
32273236 if (self.section_indexes.rela_dyn) |shndx| {
......@@ -3234,26 +3243,29 @@ fn writeSyntheticSections(self: *Elf) !void {
32343243
32353244 if (self.section_indexes.plt) |shndx| {
32363245 const shdr = slice.items(.shdr)[shndx];
3237 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self));
3238 defer buffer.deinit();
3239 try self.plt.write(self, buffer.writer());
3240 try self.pwriteAll(buffer.items, shdr.sh_offset);
3246 try buffer.resize(gpa, self.plt.size(self));
3247 bw.initFixed(buffer.items);
3248 try self.plt.write(self, &bw);
3249 assert(bw.end == bw.buffer.len);
3250 try self.pwriteAll(bw.buffer, shdr.sh_offset);
32413251 }
32423252
32433253 if (self.section_indexes.got_plt) |shndx| {
32443254 const shdr = slice.items(.shdr)[shndx];
3245 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self));
3246 defer buffer.deinit();
3247 try self.got_plt.write(self, buffer.writer());
3248 try self.pwriteAll(buffer.items, shdr.sh_offset);
3255 try buffer.resize(gpa, self.got_plt.size(self));
3256 bw.initFixed(buffer.items);
3257 try self.got_plt.write(self, &bw);
3258 assert(bw.end == bw.buffer.len);
3259 try self.pwriteAll(bw.buffer, shdr.sh_offset);
32493260 }
32503261
32513262 if (self.section_indexes.plt_got) |shndx| {
32523263 const shdr = slice.items(.shdr)[shndx];
3253 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self));
3254 defer buffer.deinit();
3255 try self.plt_got.write(self, buffer.writer());
3256 try self.pwriteAll(buffer.items, shdr.sh_offset);
3264 try buffer.resize(gpa, self.plt_got.size(self));
3265 bw.initFixed(buffer.items);
3266 try self.plt_got.write(self, &bw);
3267 assert(bw.end == bw.buffer.len);
3268 try self.pwriteAll(bw.buffer, shdr.sh_offset);
32573269 }
32583270
32593271 if (self.section_indexes.rela_plt) |shndx| {
......@@ -3544,7 +3556,7 @@ pub fn addRelaDyn(self: *Elf, opts: RelaDyn) !void {
35443556}
35453557
35463558pub fn addRelaDynAssumeCapacity(self: *Elf, opts: RelaDyn) void {
3547 relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{
3559 relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{
35483560 relocation.fmtRelocType(opts.type, self.getTarget().cpu.arch),
35493561 opts.offset,
35503562 opts.sym,
......@@ -3754,9 +3766,8 @@ fn shString(
37543766
37553767pub fn insertShString(self: *Elf, name: [:0]const u8) error{OutOfMemory}!u32 {
37563768 const gpa = self.base.comp.gpa;
3757 const off = @as(u32, @intCast(self.shstrtab.items.len));
3758 try self.shstrtab.ensureUnusedCapacity(gpa, name.len + 1);
3759 self.shstrtab.writer(gpa).print("{s}\x00", .{name}) catch unreachable;
3769 const off: u32 = @intCast(self.shstrtab.items.len);
3770 try self.shstrtab.print(gpa, "{s}\x00", .{name});
37603771 return off;
37613772}
37623773
......@@ -3769,7 +3780,7 @@ pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 {
37693780 const gpa = self.base.comp.gpa;
37703781 const off = @as(u32, @intCast(self.dynstrtab.items.len));
37713782 try self.dynstrtab.ensureUnusedCapacity(gpa, name.len + 1);
3772 self.dynstrtab.writer(gpa).print("{s}\x00", .{name}) catch unreachable;
3783 self.dynstrtab.print(gpa, "{s}\x00", .{name}) catch unreachable;
37733784 return off;
37743785}
37753786
......@@ -3791,7 +3802,7 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
37913802 for (refs.items[0..nrefs]) |ref| {
37923803 const atom_ptr = self.atom(ref).?;
37933804 const file_ptr = atom_ptr.file(self).?;
3794 err.addNote("referenced by {s}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });
3805 err.addNote("referenced by {f}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });
37953806 }
37963807
37973808 if (refs.items.len > max_notes) {
......@@ -3813,12 +3824,12 @@ fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemor
38133824
38143825 var err = try diags.addErrorWithNotes(nnotes + 1);
38153826 try err.addMsg("duplicate symbol definition: {s}", .{sym.name(self)});
3816 err.addNote("defined by {}", .{sym.file(self).?.fmtPath()});
3827 err.addNote("defined by {f}", .{sym.file(self).?.fmtPath()});
38173828
38183829 var inote: usize = 0;
38193830 while (inote < @min(notes.items.len, max_notes)) : (inote += 1) {
38203831 const file_ptr = self.file(notes.items[inote]).?;
3821 err.addNote("defined by {}", .{file_ptr.fmtPath()});
3832 err.addNote("defined by {f}", .{file_ptr.fmtPath()});
38223833 }
38233834
38243835 if (notes.items.len > max_notes) {
......@@ -3847,7 +3858,7 @@ pub fn addFileError(
38473858 const diags = &self.base.comp.link_diags;
38483859 var err = try diags.addErrorWithNotes(1);
38493860 try err.addMsg(format, args);
3850 err.addNote("while parsing {}", .{self.file(file_index).?.fmtPath()});
3861 err.addNote("while parsing {f}", .{self.file(file_index).?.fmtPath()});
38513862}
38523863
38533864pub fn failFile(
......@@ -3872,16 +3883,10 @@ fn fmtShdr(self: *Elf, shdr: elf.Elf64_Shdr) std.fmt.Formatter(formatShdr) {
38723883 } };
38733884}
38743885
3875fn formatShdr(
3876 ctx: FormatShdrCtx,
3877 comptime unused_fmt_string: []const u8,
3878 options: std.fmt.FormatOptions,
3879 writer: anytype,
3880) !void {
3881 _ = options;
3886fn formatShdr(ctx: FormatShdrCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
38823887 _ = unused_fmt_string;
38833888 const shdr = ctx.shdr;
3884 try writer.print("{s} : @{x} ({x}) : align({x}) : size({x}) : entsize({x}) : flags({})", .{
3889 try bw.print("{s} : @{x} ({x}) : align({x}) : size({x}) : entsize({x}) : flags({f})", .{
38853890 ctx.elf_file.getShString(shdr.sh_name), shdr.sh_offset,
38863891 shdr.sh_addr, shdr.sh_addralign,
38873892 shdr.sh_size, shdr.sh_entsize,
......@@ -3893,55 +3898,49 @@ pub fn fmtShdrFlags(sh_flags: u64) std.fmt.Formatter(formatShdrFlags) {
38933898 return .{ .data = sh_flags };
38943899}
38953900
3896fn formatShdrFlags(
3897 sh_flags: u64,
3898 comptime unused_fmt_string: []const u8,
3899 options: std.fmt.FormatOptions,
3900 writer: anytype,
3901) !void {
3901fn formatShdrFlags(sh_flags: u64, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) !void {
39023902 _ = unused_fmt_string;
3903 _ = options;
39043903 if (elf.SHF_WRITE & sh_flags != 0) {
3905 try writer.writeAll("W");
3904 try bw.writeByte('W');
39063905 }
39073906 if (elf.SHF_ALLOC & sh_flags != 0) {
3908 try writer.writeAll("A");
3907 try bw.writeByte('A');
39093908 }
39103909 if (elf.SHF_EXECINSTR & sh_flags != 0) {
3911 try writer.writeAll("X");
3910 try bw.writeByte('X');
39123911 }
39133912 if (elf.SHF_MERGE & sh_flags != 0) {
3914 try writer.writeAll("M");
3913 try bw.writeByte('M');
39153914 }
39163915 if (elf.SHF_STRINGS & sh_flags != 0) {
3917 try writer.writeAll("S");
3916 try bw.writeByte('S');
39183917 }
39193918 if (elf.SHF_INFO_LINK & sh_flags != 0) {
3920 try writer.writeAll("I");
3919 try bw.writeByte('I');
39213920 }
39223921 if (elf.SHF_LINK_ORDER & sh_flags != 0) {
3923 try writer.writeAll("L");
3922 try bw.writeByte('L');
39243923 }
39253924 if (elf.SHF_EXCLUDE & sh_flags != 0) {
3926 try writer.writeAll("E");
3925 try bw.writeByte('E');
39273926 }
39283927 if (elf.SHF_COMPRESSED & sh_flags != 0) {
3929 try writer.writeAll("C");
3928 try bw.writeByte('C');
39303929 }
39313930 if (elf.SHF_GROUP & sh_flags != 0) {
3932 try writer.writeAll("G");
3931 try bw.writeByte('G');
39333932 }
39343933 if (elf.SHF_OS_NONCONFORMING & sh_flags != 0) {
3935 try writer.writeAll("O");
3934 try bw.writeByte('O');
39363935 }
39373936 if (elf.SHF_TLS & sh_flags != 0) {
3938 try writer.writeAll("T");
3937 try bw.writeByte('T');
39393938 }
39403939 if (elf.SHF_X86_64_LARGE & sh_flags != 0) {
3941 try writer.writeAll("l");
3940 try bw.writeByte('l');
39423941 }
39433942 if (elf.SHF_MIPS_ADDR & sh_flags != 0 or elf.SHF_ARM_PURECODE & sh_flags != 0) {
3944 try writer.writeAll("p");
3943 try bw.writeByte('p');
39453944 }
39463945}
39473946
......@@ -3959,11 +3958,9 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Formatter(formatPhdr) {
39593958
39603959fn formatPhdr(
39613960 ctx: FormatPhdrCtx,
3961 bw: *std.io.BufferedWriter,
39623962 comptime unused_fmt_string: []const u8,
3963 options: std.fmt.FormatOptions,
3964 writer: anytype,
39653963) !void {
3966 _ = options;
39673964 _ = unused_fmt_string;
39683965 const phdr = ctx.phdr;
39693966 const write = phdr.p_flags & elf.PF_W != 0;
......@@ -3985,7 +3982,7 @@ fn formatPhdr(
39853982 elf.PT_NOTE => "NOTE",
39863983 else => "UNKNOWN",
39873984 };
3988 try writer.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{
3985 try bw.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{
39893986 p_type, flags, phdr.p_offset, phdr.p_vaddr,
39903987 phdr.p_align, phdr.p_filesz, phdr.p_memsz,
39913988 });
......@@ -3997,30 +3994,28 @@ pub fn dumpState(self: *Elf) std.fmt.Formatter(fmtDumpState) {
39973994
39983995fn fmtDumpState(
39993996 self: *Elf,
3997 bw: *std.io.BufferedWriter,
40003998 comptime unused_fmt_string: []const u8,
4001 options: std.fmt.FormatOptions,
4002 writer: anytype,
40033999) !void {
40044000 _ = unused_fmt_string;
4005 _ = options;
40064001
40074002 const shared_objects = self.shared_objects.values();
40084003
40094004 if (self.zigObjectPtr()) |zig_object| {
4010 try writer.print("zig_object({d}) : {s}\n", .{ zig_object.index, zig_object.basename });
4011 try writer.print("{}{}", .{
4005 try bw.print("zig_object({d}) : {s}\n", .{ zig_object.index, zig_object.basename });
4006 try bw.print("{f}{f}", .{
40124007 zig_object.fmtAtoms(self),
40134008 zig_object.fmtSymtab(self),
40144009 });
4015 try writer.writeByte('\n');
4010 try bw.writeByte('\n');
40164011 }
40174012
40184013 for (self.objects.items) |index| {
40194014 const object = self.file(index).?.object;
4020 try writer.print("object({d}) : {}", .{ index, object.fmtPath() });
4021 if (!object.alive) try writer.writeAll(" : [*]");
4022 try writer.writeByte('\n');
4023 try writer.print("{}{}{}{}{}\n", .{
4015 try bw.print("object({d}) : {f}", .{ index, object.fmtPath() });
4016 if (!object.alive) try bw.writeAll(" : [*]");
4017 try bw.writeByte('\n');
4018 try bw.print("{f}{f}{f}{f}{f}\n", .{
40244019 object.fmtAtoms(self),
40254020 object.fmtCies(self),
40264021 object.fmtFdes(self),
......@@ -4031,59 +4026,59 @@ fn fmtDumpState(
40314026
40324027 for (shared_objects) |index| {
40334028 const shared_object = self.file(index).?.shared_object;
4034 try writer.print("shared_object({d}) : {} : needed({})", .{
4029 try bw.print("shared_object({d}) : {f} : needed({})", .{
40354030 index, shared_object.path, shared_object.needed,
40364031 });
4037 if (!shared_object.alive) try writer.writeAll(" : [*]");
4038 try writer.writeByte('\n');
4039 try writer.print("{}\n", .{shared_object.fmtSymtab(self)});
4032 if (!shared_object.alive) try bw.writeAll(" : [*]");
4033 try bw.writeByte('\n');
4034 try bw.print("{f}\n", .{shared_object.fmtSymtab(self)});
40404035 }
40414036
40424037 if (self.linker_defined_index) |index| {
40434038 const linker_defined = self.file(index).?.linker_defined;
4044 try writer.print("linker_defined({d}) : (linker defined)\n", .{index});
4045 try writer.print("{}\n", .{linker_defined.fmtSymtab(self)});
4039 try bw.print("linker_defined({d}) : (linker defined)\n", .{index});
4040 try bw.print("{f}\n", .{linker_defined.fmtSymtab(self)});
40464041 }
40474042
40484043 const slice = self.sections.slice();
40494044 {
4050 try writer.writeAll("atom lists\n");
4045 try bw.writeAll("atom lists\n");
40514046 for (slice.items(.shdr), slice.items(.atom_list_2), 0..) |shdr, atom_list, shndx| {
4052 try writer.print("shdr({d}) : {s} : {}\n", .{ shndx, self.getShString(shdr.sh_name), atom_list.fmt(self) });
4047 try bw.print("shdr({d}) : {s} : {f}\n", .{ shndx, self.getShString(shdr.sh_name), atom_list.fmt(self) });
40534048 }
40544049 }
40554050
40564051 if (self.requiresThunks()) {
4057 try writer.writeAll("thunks\n");
4052 try bw.writeAll("thunks\n");
40584053 for (self.thunks.items, 0..) |th, index| {
4059 try writer.print("thunk({d}) : {}\n", .{ index, th.fmt(self) });
4054 try bw.print("thunk({d}) : {f}\n", .{ index, th.fmt(self) });
40604055 }
40614056 }
40624057
4063 try writer.print("{}\n", .{self.got.fmt(self)});
4064 try writer.print("{}\n", .{self.plt.fmt(self)});
4058 try bw.print("{f}\n", .{self.got.fmt(self)});
4059 try bw.print("{f}\n", .{self.plt.fmt(self)});
40654060
4066 try writer.writeAll("Output groups\n");
4061 try bw.writeAll("Output groups\n");
40674062 for (self.group_sections.items) |cg| {
4068 try writer.print(" shdr({d}) : GROUP({})\n", .{ cg.shndx, cg.cg_ref });
4063 try bw.print(" shdr({d}) : GROUP({f})\n", .{ cg.shndx, cg.cg_ref });
40694064 }
40704065
4071 try writer.writeAll("\nOutput merge sections\n");
4066 try bw.writeAll("\nOutput merge sections\n");
40724067 for (self.merge_sections.items) |msec| {
4073 try writer.print(" shdr({d}) : {}\n", .{ msec.output_section_index, msec.fmt(self) });
4068 try bw.print(" shdr({d}) : {f}\n", .{ msec.output_section_index, msec.fmt(self) });
40744069 }
40754070
4076 try writer.writeAll("\nOutput shdrs\n");
4071 try bw.writeAll("\nOutput shdrs\n");
40774072 for (slice.items(.shdr), slice.items(.phndx), 0..) |shdr, phndx, shndx| {
4078 try writer.print(" shdr({d}) : phdr({?d}) : {}\n", .{
4073 try bw.print(" shdr({d}) : phdr({?d}) : {f}\n", .{
40794074 shndx,
40804075 phndx,
40814076 self.fmtShdr(shdr),
40824077 });
40834078 }
4084 try writer.writeAll("\nOutput phdrs\n");
4079 try bw.writeAll("\nOutput phdrs\n");
40854080 for (self.phdrs.items, 0..) |phdr, phndx| {
4086 try writer.print(" phdr({d}) : {}\n", .{ phndx, self.fmtPhdr(phdr) });
4081 try bw.print(" phdr({d}) : {f}\n", .{ phndx, self.fmtPhdr(phdr) });
40874082 }
40884083}
40894084
......@@ -4221,15 +4216,9 @@ pub const Ref = struct {
42214216 return ref.index == other.index and ref.file == other.file;
42224217 }
42234218
4224 pub fn format(
4225 ref: Ref,
4226 comptime unused_fmt_string: []const u8,
4227 options: std.fmt.FormatOptions,
4228 writer: anytype,
4229 ) !void {
4219 pub fn format(ref: Ref, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
42304220 _ = unused_fmt_string;
4231 _ = options;
4232 try writer.print("ref({},{})", .{ ref.index, ref.file });
4221 try bw.print("ref({},{})", .{ ref.index, ref.file });
42334222 }
42344223};
42354224
......@@ -4424,7 +4413,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void {
44244413 for (atom_list.atoms.keys()[start..i]) |ref| {
44254414 const atom_ptr = elf_file.atom(ref).?;
44264415 const file_ptr = atom_ptr.file(elf_file).?;
4427 log.debug("atom({}) {s}", .{ ref, atom_ptr.name(elf_file) });
4416 log.debug("atom({f}) {s}", .{ ref, atom_ptr.name(elf_file) });
44284417 for (atom_ptr.relocs(elf_file)) |rel| {
44294418 const is_reachable = switch (cpu_arch) {
44304419 .aarch64 => r: {
......@@ -4453,7 +4442,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void {
44534442
44544443 thunk_ptr.value = try advance(atom_list, thunk_ptr.size(elf_file), Atom.Alignment.fromNonzeroByteUnits(2));
44554444
4456 log.debug("thunk({d}) : {}", .{ thunk_index, thunk_ptr.fmt(elf_file) });
4445 log.debug("thunk({d}) : {f}", .{ thunk_index, thunk_ptr.fmt(elf_file) });
44574446 }
44584447}
44594448
src/link/Elf/Archive.zig+20-55
......@@ -44,7 +44,7 @@ pub fn parse(
4444 pos += @sizeOf(elf.ar_hdr);
4545
4646 if (!mem.eql(u8, &hdr.ar_fmag, elf.ARFMAG)) {
47 return diags.failParse(path, "invalid archive header delimiter: {s}", .{
47 return diags.failParse(path, "invalid archive header delimiter: {f}", .{
4848 std.fmt.fmtSliceEscapeLower(&hdr.ar_fmag),
4949 });
5050 }
......@@ -83,8 +83,8 @@ pub fn parse(
8383 .alive = false,
8484 };
8585
86 log.debug("extracting object '{}' from archive '{}'", .{
87 @as(Path, object.path), @as(Path, path),
86 log.debug("extracting object '{f}' from archive '{f}'", .{
87 object.path, path,
8888 });
8989
9090 try objects.append(gpa, object);
......@@ -110,33 +110,16 @@ pub fn setArHdr(opts: struct {
110110 },
111111 size: usize,
112112}) elf.ar_hdr {
113 var hdr: elf.ar_hdr = .{
114 .ar_name = undefined,
115 .ar_date = undefined,
116 .ar_uid = undefined,
117 .ar_gid = undefined,
118 .ar_mode = undefined,
119 .ar_size = undefined,
120 .ar_fmag = undefined,
121 };
122 @memset(mem.asBytes(&hdr), 0x20);
113 var hdr: elf.ar_hdr = undefined;
114 @memset(mem.asBytes(&hdr), ' ');
123115 @memcpy(&hdr.ar_fmag, elf.ARFMAG);
124
125 {
126 var stream = std.io.fixedBufferStream(&hdr.ar_name);
127 const writer = stream.writer();
128 switch (opts.name) {
129 .symtab => writer.print("{s}", .{elf.SYM64NAME}) catch unreachable,
130 .strtab => writer.print("//", .{}) catch unreachable,
131 .name => |x| writer.print("{s}/", .{x}) catch unreachable,
132 .name_off => |x| writer.print("/{d}", .{x}) catch unreachable,
133 }
116 switch (opts.name) {
117 .symtab => _ = std.fmt.bufPrint(&hdr.ar_name, "{s}", .{elf.SYM64NAME}) catch unreachable,
118 .strtab => _ = std.fmt.bufPrint(&hdr.ar_name, "//", .{}) catch unreachable,
119 .name => |x| _ = std.fmt.bufPrint(&hdr.ar_name, "{s}/", .{x}) catch unreachable,
120 .name_off => |x| _ = std.fmt.bufPrint(&hdr.ar_name, "/{d}", .{x}) catch unreachable,
134121 }
135 {
136 var stream = std.io.fixedBufferStream(&hdr.ar_size);
137 stream.writer().print("{d}", .{opts.size}) catch unreachable;
138 }
139
122 _ = std.fmt.bufPrint(&hdr.ar_size, "{d}", .{opts.size}) catch unreachable;
140123 return hdr;
141124}
142125
......@@ -201,16 +184,10 @@ pub const ArSymtab = struct {
201184 }
202185 }
203186
204 pub fn format(
205 ar: ArSymtab,
206 comptime unused_fmt_string: []const u8,
207 options: std.fmt.FormatOptions,
208 writer: anytype,
209 ) !void {
187 pub fn format(ar: ArSymtab, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
210188 _ = ar;
189 _ = bw;
211190 _ = unused_fmt_string;
212 _ = options;
213 _ = writer;
214191 @compileError("do not format ar symtab directly; use fmt instead");
215192 }
216193
......@@ -226,20 +203,14 @@ pub const ArSymtab = struct {
226203 } };
227204 }
228205
229 fn format2(
230 ctx: FormatContext,
231 comptime unused_fmt_string: []const u8,
232 options: std.fmt.FormatOptions,
233 writer: anytype,
234 ) !void {
206 fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
235207 _ = unused_fmt_string;
236 _ = options;
237208 const ar = ctx.ar;
238209 const elf_file = ctx.elf_file;
239210 for (ar.symtab.items, 0..) |entry, i| {
240211 const name = ar.strtab.getAssumeExists(entry.off);
241212 const file = elf_file.file(entry.file_index).?;
242 try writer.print(" {d}: {s} in file({d})({})\n", .{ i, name, entry.file_index, file.fmtPath() });
213 try bw.print(" {d}: {s} in file({d})({f})\n", .{ i, name, entry.file_index, file.fmtPath() });
243214 }
244215 }
245216
......@@ -264,9 +235,9 @@ pub const ArStrtab = struct {
264235 ar.buffer.deinit(allocator);
265236 }
266237
267 pub fn insert(ar: *ArStrtab, allocator: Allocator, name: []const u8) error{OutOfMemory}!u32 {
268 const off = @as(u32, @intCast(ar.buffer.items.len));
269 try ar.buffer.writer(allocator).print("{s}/{c}", .{ name, strtab_delimiter });
238 pub fn insert(ar: *ArStrtab, gpa: Allocator, name: []const u8) error{OutOfMemory}!u32 {
239 const off: u32 = @intCast(ar.buffer.items.len);
240 try ar.buffer.print(gpa, "{s}/{c}", .{ name, strtab_delimiter });
270241 return off;
271242 }
272243
......@@ -280,15 +251,9 @@ pub const ArStrtab = struct {
280251 try writer.writeAll(ar.buffer.items);
281252 }
282253
283 pub fn format(
284 ar: ArStrtab,
285 comptime unused_fmt_string: []const u8,
286 options: std.fmt.FormatOptions,
287 writer: anytype,
288 ) !void {
254 pub fn format(ar: ArStrtab, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
289255 _ = unused_fmt_string;
290 _ = options;
291 try writer.print("{s}", .{std.fmt.fmtSliceEscapeLower(ar.buffer.items)});
256 try bw.print("{f}", .{std.fmt.fmtSliceEscapeLower(ar.buffer.items)});
292257 }
293258};
294259
src/link/Elf/Atom.zig+181-219
......@@ -142,7 +142,7 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool {
142142}
143143
144144pub fn free(self: *Atom, elf_file: *Elf) void {
145 log.debug("freeAtom atom({}) ({s})", .{ self.ref(), self.name(elf_file) });
145 log.debug("freeAtom atom({f}) ({s})", .{ self.ref(), self.name(elf_file) });
146146
147147 const comp = elf_file.base.comp;
148148 const gpa = comp.gpa;
......@@ -243,7 +243,7 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
243243 },
244244 }
245245
246 relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{
246 relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{
247247 relocation.fmtRelocType(rel.r_type(), cpu_arch),
248248 r_offset,
249249 r_sym,
......@@ -316,7 +316,7 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype
316316 };
317317 // Violation of One Definition Rule for COMDATs.
318318 // TODO convert into an error
319 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{
319 log.debug("{f}: {s}: {s} refers to a discarded COMDAT section", .{
320320 file_ptr.fmtPath(),
321321 self.name(elf_file),
322322 sym_name,
......@@ -519,11 +519,11 @@ fn dataType(symbol: *const Symbol, elf_file: *Elf) u2 {
519519fn reportUnhandledRelocError(self: Atom, rel: elf.Elf64_Rela, elf_file: *Elf) RelocError!void {
520520 const diags = &elf_file.base.comp.link_diags;
521521 var err = try diags.addErrorWithNotes(1);
522 try err.addMsg("fatal linker error: unhandled relocation type {} at offset 0x{x}", .{
522 try err.addMsg("fatal linker error: unhandled relocation type {f} at offset 0x{x}", .{
523523 relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch),
524524 rel.r_offset,
525525 });
526 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
526 err.addNote("in {f}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
527527 return error.RelocFailure;
528528}
529529
......@@ -539,7 +539,7 @@ fn reportTextRelocError(
539539 rel.r_offset,
540540 symbol.name(elf_file),
541541 });
542 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
542 err.addNote("in {f}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
543543 return error.RelocFailure;
544544}
545545
......@@ -555,7 +555,7 @@ fn reportPicError(
555555 rel.r_offset,
556556 symbol.name(elf_file),
557557 });
558 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
558 err.addNote("in {f}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
559559 err.addNote("recompile with -fPIC", .{});
560560 return error.RelocFailure;
561561}
......@@ -572,7 +572,7 @@ fn reportNoPicError(
572572 rel.r_offset,
573573 symbol.name(elf_file),
574574 });
575 err.addNote("in {}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
575 err.addNote("in {f}:{s}", .{ self.file(elf_file).?.fmtPath(), self.name(elf_file) });
576576 err.addNote("recompile with -fno-PIC", .{});
577577 return error.RelocFailure;
578578}
......@@ -621,7 +621,9 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
621621
622622 const cpu_arch = elf_file.getTarget().cpu.arch;
623623 const file_ptr = self.file(elf_file).?;
624 var stream = std.io.fixedBufferStream(code);
624
625 var bw: std.io.BufferedWriter = undefined;
626 bw.initFixed(code);
625627
626628 const rels = self.relocs(elf_file);
627629 var it = RelocsIterator{ .relocs = rels };
......@@ -652,7 +654,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
652654 // Address of the dynamic thread pointer.
653655 const DTP = elf_file.dtpAddress();
654656
655 relocs_log.debug(" {s}: {x}: [{x} => {x}] GOT({x}) ({s})", .{
657 relocs_log.debug(" {f}: {x}: [{x} => {x}] GOT({x}) ({s})", .{
656658 relocation.fmtRelocType(rel.r_type(), cpu_arch),
657659 r_offset,
658660 P,
......@@ -661,32 +663,32 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
661663 target.name(elf_file),
662664 });
663665
664 try stream.seekTo(r_offset);
665
666666 const args = ResolveArgs{ P, A, S, GOT, G, TP, DTP };
667667
668 bw.end = r_offset;
669 bw.count = 0;
668670 switch (cpu_arch) {
669 .x86_64 => x86_64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
671 .x86_64 => x86_64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, &bw) catch |err| switch (err) {
670672 error.RelocFailure,
671673 error.RelaxFailure,
672674 error.InvalidInstruction,
673675 error.CannotEncode,
674676 => has_reloc_errors = true,
675 else => |e| return e,
677 else => |e| return @errorCast(e),
676678 },
677 .aarch64 => aarch64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
679 .aarch64 => aarch64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, &bw) catch |err| switch (err) {
678680 error.RelocFailure,
679681 error.RelaxFailure,
680682 error.UnexpectedRemainder,
681683 error.DivisionByZero,
682684 => has_reloc_errors = true,
683 else => |e| return e,
685 else => |e| return @errorCast(e),
684686 },
685 .riscv64 => riscv.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
687 .riscv64 => riscv.resolveRelocAlloc(self, elf_file, rel, target, args, &it, &bw) catch |err| switch (err) {
686688 error.RelocFailure,
687689 error.RelaxFailure,
688690 => has_reloc_errors = true,
689 else => |e| return e,
691 else => |e| return @errorCast(e),
690692 },
691693 else => return error.UnsupportedCpuArch,
692694 }
......@@ -804,7 +806,9 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
804806
805807 const cpu_arch = elf_file.getTarget().cpu.arch;
806808 const file_ptr = self.file(elf_file).?;
807 var stream = std.io.fixedBufferStream(code);
809
810 var bw: std.io.BufferedWriter = undefined;
811 bw.initFixed(code);
808812
809813 const rels = self.relocs(elf_file);
810814 var has_reloc_errors = false;
......@@ -823,7 +827,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
823827 };
824828 // Violation of One Definition Rule for COMDATs.
825829 // TODO convert into an error
826 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{
830 log.debug("{f}: {s}: {s} refers to a discarded COMDAT section", .{
827831 file_ptr.fmtPath(),
828832 self.name(elf_file),
829833 sym_name,
......@@ -855,7 +859,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
855859
856860 const args = ResolveArgs{ P, A, S, GOT, 0, 0, DTP };
857861
858 relocs_log.debug(" {}: {x}: [{x} => {x}] ({s})", .{
862 relocs_log.debug(" {f}: {x}: [{x} => {x}] ({s})", .{
859863 relocation.fmtRelocType(rel.r_type(), cpu_arch),
860864 rel.r_offset,
861865 P,
......@@ -863,18 +867,18 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
863867 target.name(elf_file),
864868 });
865869
866 try stream.seekTo(r_offset);
867
870 bw.end = r_offset;
871 bw.count = 0;
868872 switch (cpu_arch) {
869 .x86_64 => x86_64.resolveRelocNonAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
873 .x86_64 => x86_64.resolveRelocNonAlloc(self, elf_file, rel, target, args, &bw) catch |err| switch (err) {
870874 error.RelocFailure => has_reloc_errors = true,
871875 else => |e| return e,
872876 },
873 .aarch64 => aarch64.resolveRelocNonAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
877 .aarch64 => aarch64.resolveRelocNonAlloc(self, elf_file, rel, target, args, &bw) catch |err| switch (err) {
874878 error.RelocFailure => has_reloc_errors = true,
875879 else => |e| return e,
876880 },
877 .riscv64 => riscv.resolveRelocNonAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) {
881 .riscv64 => riscv.resolveRelocNonAlloc(self, elf_file, rel, target, args, &bw) catch |err| switch (err) {
878882 error.RelocFailure => has_reloc_errors = true,
879883 else => |e| return e,
880884 },
......@@ -904,16 +908,10 @@ pub fn setExtra(atom: Atom, extras: Extra, elf_file: *Elf) void {
904908 atom.file(elf_file).?.setAtomExtra(atom.extra_index, extras);
905909}
906910
907pub fn format(
908 atom: Atom,
909 comptime unused_fmt_string: []const u8,
910 options: std.fmt.FormatOptions,
911 writer: anytype,
912) !void {
911pub fn format(atom: Atom, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
913912 _ = atom;
913 _ = bw;
914914 _ = unused_fmt_string;
915 _ = options;
916 _ = writer;
917915 @compileError("do not format Atom directly");
918916}
919917
......@@ -929,17 +927,11 @@ const FormatContext = struct {
929927 elf_file: *Elf,
930928};
931929
932fn format2(
933 ctx: FormatContext,
934 comptime unused_fmt_string: []const u8,
935 options: std.fmt.FormatOptions,
936 writer: anytype,
937) !void {
938 _ = options;
930fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
939931 _ = unused_fmt_string;
940932 const atom = ctx.atom;
941933 const elf_file = ctx.elf_file;
942 try writer.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x}) : prev({}) : next({})", .{
934 try bw.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x}) : prev({f}) : next({f})", .{
943935 atom.atom_index, atom.name(elf_file), atom.address(elf_file),
944936 atom.output_section_index, atom.alignment.toByteUnits() orelse 0, atom.size,
945937 atom.prev_atom_ref, atom.next_atom_ref,
......@@ -947,20 +939,20 @@ fn format2(
947939 if (atom.file(elf_file)) |atom_file| switch (atom_file) {
948940 .object => |object| {
949941 if (atom.fdes(object).len > 0) {
950 try writer.writeAll(" : fdes{ ");
942 try bw.writeAll(" : fdes{ ");
951943 const extras = atom.extra(elf_file);
952944 for (atom.fdes(object), extras.fde_start..) |fde, i| {
953 try writer.print("{d}", .{i});
954 if (!fde.alive) try writer.writeAll("([*])");
955 if (i - extras.fde_start < extras.fde_count - 1) try writer.writeAll(", ");
945 try bw.print("{d}", .{i});
946 if (!fde.alive) try bw.writeAll("([*])");
947 if (i - extras.fde_start < extras.fde_count - 1) try bw.writeAll(", ");
956948 }
957 try writer.writeAll(" }");
949 try bw.writeAll(" }");
958950 }
959951 },
960952 else => {},
961953 };
962954 if (!atom.alive) {
963 try writer.writeAll(" : [*]");
955 try bw.writeAll(" : [*]");
964956 }
965957}
966958
......@@ -1087,16 +1079,12 @@ const x86_64 = struct {
10871079 target: *const Symbol,
10881080 args: ResolveArgs,
10891081 it: *RelocsIterator,
1090 code: []u8,
1091 stream: anytype,
1092 ) (error{ InvalidInstruction, CannotEncode } || RelocError)!void {
1082 bw: *std.io.BufferedWriter,
1083 ) anyerror!void {
10931084 dev.check(.x86_64_backend);
10941085 const t = &elf_file.base.comp.root_mod.resolved_target.result;
10951086 const diags = &elf_file.base.comp.link_diags;
10961087 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
1097 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
1098
1099 const cwriter = stream.writer();
11001088
11011089 const P, const A, const S, const GOT, const G, const TP, const DTP = args;
11021090
......@@ -1109,58 +1097,54 @@ const x86_64 = struct {
11091097 rel,
11101098 dynAbsRelocAction(target, elf_file),
11111099 elf_file,
1112 cwriter,
1100 bw,
11131101 );
11141102 },
11151103
1116 .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
1117 .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
1104 .PLT32 => try bw.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
1105 .PC32 => try bw.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
11181106
1119 .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
1120 .GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),
1121 .GOTPC64 => try cwriter.writeInt(i64, GOT + A - P, .little),
1107 .GOTPCREL => try bw.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
1108 .GOTPC32 => try bw.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),
1109 .GOTPC64 => try bw.writeInt(i64, GOT + A - P, .little),
11221110
1123 .GOTPCRELX => {
1124 if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: {
1125 x86_64.relaxGotpcrelx(code[r_offset - 2 ..], t) catch break :blk;
1126 try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little);
1127 return;
1128 }
1129 try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little);
1111 .GOTPCRELX => if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: {
1112 x86_64.relaxGotpcrelx(bw.buffer[bw.end - 2 ..], t) catch break :blk;
1113 try bw.writeInt(i32, @as(i32, @intCast(S + A - P)), .little);
1114 } else {
1115 try bw.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little);
11301116 },
11311117
1132 .REX_GOTPCRELX => {
1133 if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: {
1134 x86_64.relaxRexGotpcrelx(code[r_offset - 3 ..], t) catch break :blk;
1135 try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little);
1136 return;
1137 }
1138 try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little);
1118 .REX_GOTPCRELX => if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: {
1119 x86_64.relaxRexGotpcrelx(bw.buffer[bw.end - 3 ..], t) catch break :blk;
1120 try bw.writeInt(i32, @as(i32, @intCast(S + A - P)), .little);
1121 } else {
1122 try bw.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little);
11391123 },
11401124
1141 .@"32" => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
1142 .@"32S" => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little),
1125 .@"32" => try bw.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
1126 .@"32S" => try bw.writeInt(i32, @as(i32, @truncate(S + A)), .little),
11431127
1144 .TPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - TP)), .little),
1145 .TPOFF64 => try cwriter.writeInt(i64, S + A - TP, .little),
1128 .TPOFF32 => try bw.writeInt(i32, @as(i32, @truncate(S + A - TP)), .little),
1129 .TPOFF64 => try bw.writeInt(i64, S + A - TP, .little),
11461130
1147 .DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - DTP)), .little),
1148 .DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little),
1131 .DTPOFF32 => try bw.writeInt(i32, @as(i32, @truncate(S + A - DTP)), .little),
1132 .DTPOFF64 => try bw.writeInt(i64, S + A - DTP, .little),
11491133
11501134 .TLSGD => {
11511135 if (target.flags.has_tlsgd) {
11521136 const S_ = target.tlsGdAddress(elf_file);
1153 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
1137 try bw.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
11541138 } else if (target.flags.has_gottp) {
11551139 const S_ = target.gotTpAddress(elf_file);
1156 try x86_64.relaxTlsGdToIe(atom, &.{ rel, it.next().? }, @intCast(S_ - P), elf_file, stream);
1140 try x86_64.relaxTlsGdToIe(atom, &.{ rel, it.next().? }, @intCast(S_ - P), elf_file, bw);
11571141 } else {
11581142 try x86_64.relaxTlsGdToLe(
11591143 atom,
11601144 &.{ rel, it.next().? },
11611145 @as(i32, @intCast(S - TP)),
11621146 elf_file,
1163 stream,
1147 bw,
11641148 );
11651149 }
11661150 },
......@@ -1169,14 +1153,14 @@ const x86_64 = struct {
11691153 if (elf_file.got.tlsld_index) |entry_index| {
11701154 const tlsld_entry = elf_file.got.entries.items[entry_index];
11711155 const S_ = tlsld_entry.address(elf_file);
1172 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
1156 try bw.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
11731157 } else {
11741158 try x86_64.relaxTlsLdToLe(
11751159 atom,
11761160 &.{ rel, it.next().? },
11771161 @as(i32, @intCast(TP - elf_file.tlsAddress())),
11781162 elf_file,
1179 stream,
1163 bw,
11801164 );
11811165 }
11821166 },
......@@ -1184,38 +1168,38 @@ const x86_64 = struct {
11841168 .GOTPC32_TLSDESC => {
11851169 if (target.flags.has_tlsdesc) {
11861170 const S_ = target.tlsDescAddress(elf_file);
1187 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
1171 try bw.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
11881172 } else {
1189 x86_64.relaxGotPcTlsDesc(code[r_offset - 3 ..], t) catch {
1173 x86_64.relaxGotPcTlsDesc(bw.buffer[bw.end - 3 ..], t) catch {
11901174 var err = try diags.addErrorWithNotes(1);
11911175 try err.addMsg("could not relax {s}", .{@tagName(r_type)});
1192 err.addNote("in {}:{s} at offset 0x{x}", .{
1176 err.addNote("in {f}:{s} at offset 0x{x}", .{
11931177 atom.file(elf_file).?.fmtPath(),
11941178 atom.name(elf_file),
11951179 rel.r_offset,
11961180 });
11971181 return error.RelaxFailure;
11981182 };
1199 try cwriter.writeInt(i32, @as(i32, @intCast(S - TP)), .little);
1183 try bw.writeInt(i32, @as(i32, @intCast(S - TP)), .little);
12001184 }
12011185 },
12021186
12031187 .TLSDESC_CALL => if (!target.flags.has_tlsdesc) {
12041188 // call -> nop
1205 try cwriter.writeAll(&.{ 0x66, 0x90 });
1189 try bw.writeAll(&.{ 0x66, 0x90 });
12061190 },
12071191
12081192 .GOTTPOFF => {
12091193 if (target.flags.has_gottp) {
12101194 const S_ = target.gotTpAddress(elf_file);
1211 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
1195 try bw.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
12121196 } else {
1213 x86_64.relaxGotTpOff(code[r_offset - 3 ..], t);
1214 try cwriter.writeInt(i32, @as(i32, @intCast(S - TP)), .little);
1197 x86_64.relaxGotTpOff(bw.buffer[bw.end - 3 ..], t);
1198 try bw.writeInt(i32, @as(i32, @intCast(S - TP)), .little);
12151199 }
12161200 },
12171201
1218 .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + A)), .little),
1202 .GOT32 => try bw.writeInt(i32, @as(i32, @intCast(G + A)), .little),
12191203
12201204 else => try atom.reportUnhandledRelocError(rel, elf_file),
12211205 }
......@@ -1227,45 +1211,40 @@ const x86_64 = struct {
12271211 rel: elf.Elf64_Rela,
12281212 target: *const Symbol,
12291213 args: ResolveArgs,
1230 it: *RelocsIterator,
1231 code: []u8,
1232 stream: anytype,
1233 ) !void {
1214 bw: *std.io.BufferedWriter,
1215 ) anyerror!void {
12341216 dev.check(.x86_64_backend);
1235 _ = code;
1236 _ = it;
1237 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
1238 const cwriter = stream.writer();
12391217
1218 const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
12401219 _, const A, const S, const GOT, _, _, const DTP = args;
12411220
12421221 switch (r_type) {
12431222 .NONE => unreachable,
1244 .@"8" => try cwriter.writeInt(u8, @as(u8, @bitCast(@as(i8, @intCast(S + A)))), .little),
1245 .@"16" => try cwriter.writeInt(u16, @as(u16, @bitCast(@as(i16, @intCast(S + A)))), .little),
1246 .@"32" => try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(S + A)))), .little),
1247 .@"32S" => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little),
1223 .@"8" => try bw.writeInt(u8, @as(u8, @bitCast(@as(i8, @intCast(S + A)))), .little),
1224 .@"16" => try bw.writeInt(u16, @as(u16, @bitCast(@as(i16, @intCast(S + A)))), .little),
1225 .@"32" => try bw.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(S + A)))), .little),
1226 .@"32S" => try bw.writeInt(i32, @as(i32, @intCast(S + A)), .little),
12481227 .@"64" => if (atom.debugTombstoneValue(target.*, elf_file)) |value|
1249 try cwriter.writeInt(u64, value, .little)
1228 try bw.writeInt(u64, value, .little)
12501229 else
1251 try cwriter.writeInt(i64, S + A, .little),
1230 try bw.writeInt(i64, S + A, .little),
12521231 .DTPOFF32 => if (atom.debugTombstoneValue(target.*, elf_file)) |value|
1253 try cwriter.writeInt(u64, value, .little)
1232 try bw.writeInt(u64, value, .little)
12541233 else
1255 try cwriter.writeInt(i32, @as(i32, @intCast(S + A - DTP)), .little),
1234 try bw.writeInt(i32, @as(i32, @intCast(S + A - DTP)), .little),
12561235 .DTPOFF64 => if (atom.debugTombstoneValue(target.*, elf_file)) |value|
1257 try cwriter.writeInt(u64, value, .little)
1236 try bw.writeInt(u64, value, .little)
12581237 else
1259 try cwriter.writeInt(i64, S + A - DTP, .little),
1260 .GOTOFF64 => try cwriter.writeInt(i64, S + A - GOT, .little),
1261 .GOTPC64 => try cwriter.writeInt(i64, GOT + A, .little),
1238 try bw.writeInt(i64, S + A - DTP, .little),
1239 .GOTOFF64 => try bw.writeInt(i64, S + A - GOT, .little),
1240 .GOTPC64 => try bw.writeInt(i64, GOT + A, .little),
12621241 .SIZE32 => {
12631242 const size = @as(i64, @intCast(target.elfSym(elf_file).st_size));
1264 try cwriter.writeInt(u32, @bitCast(@as(i32, @intCast(size + A))), .little);
1243 try bw.writeInt(u32, @bitCast(@as(i32, @intCast(size + A))), .little);
12651244 },
12661245 .SIZE64 => {
12671246 const size = @as(i64, @intCast(target.elfSym(elf_file).st_size));
1268 try cwriter.writeInt(i64, @intCast(size + A), .little);
1247 try bw.writeInt(i64, @intCast(size + A), .little);
12691248 },
12701249 else => try atom.reportUnhandledRelocError(rel, elf_file),
12711250 }
......@@ -1285,7 +1264,7 @@ const x86_64 = struct {
12851264 }, t),
12861265 else => return error.RelaxFailure,
12871266 };
1288 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
1267 relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding });
12891268 const nop: Instruction = try .new(.none, .nop, &.{}, t);
12901269 try encode(&.{ nop, inst }, code);
12911270 }
......@@ -1296,7 +1275,7 @@ const x86_64 = struct {
12961275 switch (old_inst.encoding.mnemonic) {
12971276 .mov => {
12981277 const inst: Instruction = try .new(old_inst.prefix, .lea, &old_inst.ops, t);
1299 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
1278 relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding });
13001279 try encode(&.{inst}, code);
13011280 },
13021281 else => return error.RelaxFailure,
......@@ -1308,12 +1287,11 @@ const x86_64 = struct {
13081287 rels: []const elf.Elf64_Rela,
13091288 value: i32,
13101289 elf_file: *Elf,
1311 stream: anytype,
1290 bw: *std.io.BufferedWriter,
13121291 ) !void {
13131292 dev.check(.x86_64_backend);
13141293 assert(rels.len == 2);
13151294 const diags = &elf_file.base.comp.link_diags;
1316 const writer = stream.writer();
13171295 const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type());
13181296 switch (rel) {
13191297 .PC32,
......@@ -1324,17 +1302,17 @@ const x86_64 = struct {
13241302 0x48, 0x03, 0x05, 0, 0, 0, 0, // add foo@gottpoff(%rip), %rax
13251303 };
13261304 std.mem.writeInt(i32, insts[12..][0..4], value - 12, .little);
1327 try stream.seekBy(-4);
1328 try writer.writeAll(&insts);
1305 bw.end -= 4;
1306 try bw.writeAll(&insts);
13291307 },
13301308
13311309 else => {
13321310 var err = try diags.addErrorWithNotes(1);
1333 try err.addMsg("TODO: rewrite {} when followed by {}", .{
1311 try err.addMsg("TODO: rewrite {f} when followed by {f}", .{
13341312 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
13351313 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
13361314 });
1337 err.addNote("in {}:{s} at offset 0x{x}", .{
1315 err.addNote("in {f}:{s} at offset 0x{x}", .{
13381316 self.file(elf_file).?.fmtPath(),
13391317 self.name(elf_file),
13401318 rels[0].r_offset,
......@@ -1349,12 +1327,11 @@ const x86_64 = struct {
13491327 rels: []const elf.Elf64_Rela,
13501328 value: i32,
13511329 elf_file: *Elf,
1352 stream: anytype,
1330 bw: *std.io.BufferedWriter,
13531331 ) !void {
13541332 dev.check(.x86_64_backend);
13551333 assert(rels.len == 2);
13561334 const diags = &elf_file.base.comp.link_diags;
1357 const writer = stream.writer();
13581335 const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type());
13591336 switch (rel) {
13601337 .PC32,
......@@ -1366,8 +1343,8 @@ const x86_64 = struct {
13661343 0x48, 0x2d, 0, 0, 0, 0, // sub $tls_size, %rax
13671344 };
13681345 std.mem.writeInt(i32, insts[8..][0..4], value, .little);
1369 try stream.seekBy(-3);
1370 try writer.writeAll(&insts);
1346 bw.end -= 3;
1347 try bw.writeAll(&insts);
13711348 },
13721349
13731350 .GOTPCREL,
......@@ -1380,17 +1357,17 @@ const x86_64 = struct {
13801357 0x90, // nop
13811358 };
13821359 std.mem.writeInt(i32, insts[8..][0..4], value, .little);
1383 try stream.seekBy(-3);
1384 try writer.writeAll(&insts);
1360 bw.end -= 3;
1361 try bw.writeAll(&insts);
13851362 },
13861363
13871364 else => {
13881365 var err = try diags.addErrorWithNotes(1);
1389 try err.addMsg("TODO: rewrite {} when followed by {}", .{
1366 try err.addMsg("TODO: rewrite {f} when followed by {f}", .{
13901367 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
13911368 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
13921369 });
1393 err.addNote("in {}:{s} at offset 0x{x}", .{
1370 err.addNote("in {f}:{s} at offset 0x{x}", .{
13941371 self.file(elf_file).?.fmtPath(),
13951372 self.name(elf_file),
13961373 rels[0].r_offset,
......@@ -1410,7 +1387,12 @@ const x86_64 = struct {
14101387 // TODO: hack to force imm32s in the assembler
14111388 .{ .imm = .s(-129) },
14121389 }, t) catch return false;
1413 inst.encode(std.io.null_writer, .{}) catch return false;
1390 var buf: [std.atomic.cache_line]u8 = undefined;
1391 var bw: std.io.BufferedWriter = .{
1392 .unbuffered_writer = .null,
1393 .buffer = &buf,
1394 };
1395 inst.encode(&bw, .{}) catch return false;
14141396 return true;
14151397 },
14161398 else => return false,
......@@ -1427,7 +1409,7 @@ const x86_64 = struct {
14271409 // TODO: hack to force imm32s in the assembler
14281410 .{ .imm = .s(-129) },
14291411 }, t) catch unreachable;
1430 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
1412 relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding });
14311413 encode(&.{inst}, code) catch unreachable;
14321414 },
14331415 else => unreachable,
......@@ -1444,7 +1426,7 @@ const x86_64 = struct {
14441426 // TODO: hack to force imm32s in the assembler
14451427 .{ .imm = .s(-129) },
14461428 }, target);
1447 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
1429 relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding });
14481430 try encode(&.{inst}, code);
14491431 },
14501432 else => return error.RelaxFailure,
......@@ -1456,12 +1438,11 @@ const x86_64 = struct {
14561438 rels: []const elf.Elf64_Rela,
14571439 value: i32,
14581440 elf_file: *Elf,
1459 stream: anytype,
1441 bw: *std.io.BufferedWriter,
14601442 ) !void {
14611443 dev.check(.x86_64_backend);
14621444 assert(rels.len == 2);
14631445 const diags = &elf_file.base.comp.link_diags;
1464 const writer = stream.writer();
14651446 const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type());
14661447 switch (rel) {
14671448 .PC32,
......@@ -1474,9 +1455,9 @@ const x86_64 = struct {
14741455 0x48, 0x81, 0xc0, 0, 0, 0, 0, // add $tp_offset, %rax
14751456 };
14761457 std.mem.writeInt(i32, insts[12..][0..4], value, .little);
1477 try stream.seekBy(-4);
1478 try writer.writeAll(&insts);
1479 relocs_log.debug(" relaxing {} and {}", .{
1458 bw.end -= 4;
1459 try bw.writeAll(&insts);
1460 relocs_log.debug(" relaxing {f} and {f}", .{
14801461 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
14811462 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
14821463 });
......@@ -1484,11 +1465,11 @@ const x86_64 = struct {
14841465
14851466 else => {
14861467 var err = try diags.addErrorWithNotes(1);
1487 try err.addMsg("fatal linker error: rewrite {} when followed by {}", .{
1468 try err.addMsg("fatal linker error: rewrite {f} when followed by {f}", .{
14881469 relocation.fmtRelocType(rels[0].r_type(), .x86_64),
14891470 relocation.fmtRelocType(rels[1].r_type(), .x86_64),
14901471 });
1491 err.addNote("in {}:{s} at offset 0x{x}", .{
1472 err.addNote("in {f}:{s} at offset 0x{x}", .{
14921473 self.file(elf_file).?.fmtPath(),
14931474 self.name(elf_file),
14941475 rels[0].r_offset,
......@@ -1505,11 +1486,9 @@ const x86_64 = struct {
15051486 }
15061487
15071488 fn encode(insts: []const Instruction, code: []u8) !void {
1508 var stream = std.io.fixedBufferStream(code);
1509 const writer = stream.writer();
1510 for (insts) |inst| {
1511 try inst.encode(writer, .{});
1512 }
1489 var bw: std.io.BufferedWriter = undefined;
1490 bw.initFixed(code);
1491 for (insts) |inst| try inst.encode(&bw, .{});
15131492 }
15141493
15151494 const bits = @import("../../arch/x86_64/bits.zig");
......@@ -1613,16 +1592,14 @@ const aarch64 = struct {
16131592 target: *const Symbol,
16141593 args: ResolveArgs,
16151594 it: *RelocsIterator,
1616 code_buffer: []u8,
1617 stream: anytype,
1618 ) (error{ UnexpectedRemainder, DivisionByZero } || RelocError)!void {
1595 bw: *std.io.BufferedWriter,
1596 ) anyerror!void {
16191597 _ = it;
16201598
16211599 const diags = &elf_file.base.comp.link_diags;
16221600 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
16231601 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
1624 const cwriter = stream.writer();
1625 const code = code_buffer[r_offset..][0..4];
1602 const code = (try bw.writableSlice(4))[0..4];
16261603 const file_ptr = atom.file(elf_file).?;
16271604
16281605 const P, const A, const S, const GOT, const G, const TP, const DTP = args;
......@@ -1636,7 +1613,7 @@ const aarch64 = struct {
16361613 rel,
16371614 dynAbsRelocAction(target, elf_file),
16381615 elf_file,
1639 cwriter,
1616 bw,
16401617 );
16411618 },
16421619
......@@ -1649,17 +1626,17 @@ const aarch64 = struct {
16491626 const S_ = th.targetAddress(target_index, elf_file);
16501627 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;
16511628 };
1652 aarch64_util.writeBranchImm(disp, code);
1629 aarch64_util.writeBranchImm(disp, (try bw.writableSlice(4))[0..4]);
16531630 },
16541631
16551632 .PREL32 => {
16561633 const value = math.cast(i32, S + A - P) orelse return error.Overflow;
1657 mem.writeInt(u32, code, @bitCast(value), .little);
1634 try bw.writeInt(u32, @bitCast(value), .little);
16581635 },
16591636
16601637 .PREL64 => {
16611638 const value = S + A - P;
1662 mem.writeInt(u64, code_buffer[r_offset..][0..8], @bitCast(value), .little);
1639 try bw.writeInt(u64, @bitCast(value), .little);
16631640 },
16641641
16651642 .ADR_PREL_PG_HI21 => {
......@@ -1675,7 +1652,7 @@ const aarch64 = struct {
16751652 // TODO: relax
16761653 var err = try diags.addErrorWithNotes(1);
16771654 try err.addMsg("TODO: relax ADR_GOT_PAGE", .{});
1678 err.addNote("in {}:{s} at offset 0x{x}", .{
1655 err.addNote("in {f}:{s} at offset 0x{x}", .{
16791656 atom.file(elf_file).?.fmtPath(),
16801657 atom.name(elf_file),
16811658 r_offset,
......@@ -1818,25 +1795,18 @@ const aarch64 = struct {
18181795 rel: elf.Elf64_Rela,
18191796 target: *const Symbol,
18201797 args: ResolveArgs,
1821 it: *RelocsIterator,
1822 code: []u8,
1823 stream: anytype,
1798 bw: *std.io.BufferedWriter,
18241799 ) !void {
1825 _ = it;
1826 _ = code;
1827
18281800 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
1829 const cwriter = stream.writer();
1830
18311801 _, const A, const S, _, _, _, _ = args;
18321802
18331803 switch (r_type) {
18341804 .NONE => unreachable,
1835 .ABS32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little),
1805 .ABS32 => try bw.writeInt(i32, @as(i32, @intCast(S + A)), .little),
18361806 .ABS64 => if (atom.debugTombstoneValue(target.*, elf_file)) |value|
1837 try cwriter.writeInt(u64, value, .little)
1807 try bw.writeInt(u64, value, .little)
18381808 else
1839 try cwriter.writeInt(i64, S + A, .little),
1809 try bw.writeInt(i64, S + A, .little),
18401810 else => try atom.reportUnhandledRelocError(rel, elf_file),
18411811 }
18421812 }
......@@ -1898,13 +1868,10 @@ const riscv = struct {
18981868 target: *const Symbol,
18991869 args: ResolveArgs,
19001870 it: *RelocsIterator,
1901 code: []u8,
1902 stream: anytype,
1871 bw: *std.io.BufferedWriter,
19031872 ) !void {
19041873 const diags = &elf_file.base.comp.link_diags;
19051874 const r_type: elf.R_RISCV = @enumFromInt(rel.r_type());
1906 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
1907 const cwriter = stream.writer();
19081875
19091876 const P, const A, const S, const GOT, const G, const TP, const DTP = args;
19101877 _ = TP;
......@@ -1913,7 +1880,7 @@ const riscv = struct {
19131880 switch (r_type) {
19141881 .NONE => unreachable,
19151882
1916 .@"32" => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
1883 .@"32" => try bw.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
19171884
19181885 .@"64" => {
19191886 try atom.resolveDynAbsReloc(
......@@ -1921,34 +1888,35 @@ const riscv = struct {
19211888 rel,
19221889 dynAbsRelocAction(target, elf_file),
19231890 elf_file,
1924 cwriter,
1891 bw,
19251892 );
19261893 },
19271894
1928 .ADD32 => riscv_util.writeAddend(i32, .add, code[r_offset..][0..4], S + A),
1929 .SUB32 => riscv_util.writeAddend(i32, .sub, code[r_offset..][0..4], S + A),
1895 .ADD32 => try riscv_util.writeAddend(i32, .add, S + A, bw),
1896 .SUB32 => try riscv_util.writeAddend(i32, .sub, S + A, bw),
19301897
19311898 .HI20 => {
19321899 const value: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow);
1933 riscv_util.writeInstU(code[r_offset..][0..4], value);
1900 riscv_util.writeInstU((try bw.writableSlice(4))[0..4], value);
19341901 },
19351902
19361903 .GOT_HI20 => {
19371904 assert(target.flags.has_got);
19381905 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A - P) orelse return error.Overflow);
1939 riscv_util.writeInstU(code[r_offset..][0..4], disp);
1906 riscv_util.writeInstU((try bw.writableSlice(4))[0..4], disp);
19401907 },
19411908
19421909 .CALL_PLT => {
19431910 // TODO: relax
19441911 const disp: u32 = @bitCast(math.cast(i32, S + A - P) orelse return error.Overflow);
1945 riscv_util.writeInstU(code[r_offset..][0..4], disp); // auipc
1946 riscv_util.writeInstI(code[r_offset + 4 ..][0..4], disp); // jalr
1912 const code = (try bw.writableSlice(8))[0..8];
1913 riscv_util.writeInstU(code[0..4], disp); // auipc
1914 riscv_util.writeInstI(code[4..8], disp); // jalr
19471915 },
19481916
19491917 .PCREL_HI20 => {
19501918 const disp: u32 = @bitCast(math.cast(i32, S + A - P) orelse return error.Overflow);
1951 riscv_util.writeInstU(code[r_offset..][0..4], disp);
1919 riscv_util.writeInstU((try bw.writableSlice(4))[0..4], disp);
19521920 },
19531921
19541922 .PCREL_LO12_I,
......@@ -1965,7 +1933,7 @@ const riscv = struct {
19651933 // TODO: implement searching forward
19661934 var err = try diags.addErrorWithNotes(1);
19671935 try err.addMsg("TODO: find HI20 paired reloc scanning forward", .{});
1968 err.addNote("in {}:{s} at offset 0x{x}", .{
1936 err.addNote("in {f}:{s} at offset 0x{x}", .{
19691937 atom.file(elf_file).?.fmtPath(),
19701938 atom.name(elf_file),
19711939 rel.r_offset,
......@@ -1986,8 +1954,8 @@ const riscv = struct {
19861954 };
19871955 relocs_log.debug(" [{x} => {x}]", .{ P_, disp + P_ });
19881956 switch (r_type) {
1989 .PCREL_LO12_I => riscv_util.writeInstI(code[r_offset..][0..4], @bitCast(disp)),
1990 .PCREL_LO12_S => riscv_util.writeInstS(code[r_offset..][0..4], @bitCast(disp)),
1957 .PCREL_LO12_I => riscv_util.writeInstI((try bw.writableSlice(4))[0..4], @bitCast(disp)),
1958 .PCREL_LO12_S => riscv_util.writeInstS((try bw.writableSlice(4))[0..4], @bitCast(disp)),
19911959 else => unreachable,
19921960 }
19931961 },
......@@ -1997,8 +1965,8 @@ const riscv = struct {
19971965 => {
19981966 const disp: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow);
19991967 switch (r_type) {
2000 .LO12_I => riscv_util.writeInstI(code[r_offset..][0..4], disp),
2001 .LO12_S => riscv_util.writeInstS(code[r_offset..][0..4], disp),
1968 .LO12_I => riscv_util.writeInstI((try bw.writableSlice(4))[0..4], disp),
1969 .LO12_S => riscv_util.writeInstS((try bw.writableSlice(4))[0..4], disp),
20021970 else => unreachable,
20031971 }
20041972 },
......@@ -2006,7 +1974,7 @@ const riscv = struct {
20061974 .TPREL_HI20 => {
20071975 const target_addr: u32 = @intCast(target.address(.{}, elf_file));
20081976 const val: i32 = @intCast(S + A - target_addr);
2009 riscv_util.writeInstU(code[r_offset..][0..4], @bitCast(val));
1977 riscv_util.writeInstU((try bw.writableSlice(4))[0..4], @bitCast(val));
20101978 },
20111979
20121980 .TPREL_LO12_I,
......@@ -2015,8 +1983,8 @@ const riscv = struct {
20151983 const target_addr: u32 = @intCast(target.address(.{}, elf_file));
20161984 const val: i32 = @intCast(S + A - target_addr);
20171985 switch (r_type) {
2018 .TPREL_LO12_I => riscv_util.writeInstI(code[r_offset..][0..4], @bitCast(val)),
2019 .TPREL_LO12_S => riscv_util.writeInstS(code[r_offset..][0..4], @bitCast(val)),
1986 .TPREL_LO12_I => riscv_util.writeInstI((try bw.writableSlice(4))[0..4], @bitCast(val)),
1987 .TPREL_LO12_S => riscv_util.writeInstS((try bw.writableSlice(4))[0..4], @bitCast(val)),
20201988 else => unreachable,
20211989 }
20221990 },
......@@ -2035,15 +2003,9 @@ const riscv = struct {
20352003 rel: elf.Elf64_Rela,
20362004 target: *const Symbol,
20372005 args: ResolveArgs,
2038 it: *RelocsIterator,
2039 code: []u8,
2040 stream: anytype,
2041 ) !void {
2042 _ = it;
2043
2006 bw: *std.io.BufferedWriter,
2007 ) anyerror!void {
20442008 const r_type: elf.R_RISCV = @enumFromInt(rel.r_type());
2045 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
2046 const cwriter = stream.writer();
20472009
20482010 _, const A, const S, const GOT, _, _, const DTP = args;
20492011 _ = GOT;
......@@ -2052,30 +2014,30 @@ const riscv = struct {
20522014 switch (r_type) {
20532015 .NONE => unreachable,
20542016
2055 .@"32" => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little),
2017 .@"32" => try bw.writeInt(i32, @as(i32, @intCast(S + A)), .little),
20562018 .@"64" => if (atom.debugTombstoneValue(target.*, elf_file)) |value|
2057 try cwriter.writeInt(u64, value, .little)
2019 try bw.writeInt(u64, value, .little)
20582020 else
2059 try cwriter.writeInt(i64, S + A, .little),
2060
2061 .ADD8 => riscv_util.writeAddend(i8, .add, code[r_offset..][0..1], S + A),
2062 .SUB8 => riscv_util.writeAddend(i8, .sub, code[r_offset..][0..1], S + A),
2063 .ADD16 => riscv_util.writeAddend(i16, .add, code[r_offset..][0..2], S + A),
2064 .SUB16 => riscv_util.writeAddend(i16, .sub, code[r_offset..][0..2], S + A),
2065 .ADD32 => riscv_util.writeAddend(i32, .add, code[r_offset..][0..4], S + A),
2066 .SUB32 => riscv_util.writeAddend(i32, .sub, code[r_offset..][0..4], S + A),
2067 .ADD64 => riscv_util.writeAddend(i64, .add, code[r_offset..][0..8], S + A),
2068 .SUB64 => riscv_util.writeAddend(i64, .sub, code[r_offset..][0..8], S + A),
2069
2070 .SET8 => mem.writeInt(i8, code[r_offset..][0..1], @as(i8, @truncate(S + A)), .little),
2071 .SET16 => mem.writeInt(i16, code[r_offset..][0..2], @as(i16, @truncate(S + A)), .little),
2072 .SET32 => mem.writeInt(i32, code[r_offset..][0..4], @as(i32, @truncate(S + A)), .little),
2073
2074 .SET6 => riscv_util.writeSetSub6(.set, code[r_offset..][0..1], S + A),
2075 .SUB6 => riscv_util.writeSetSub6(.sub, code[r_offset..][0..1], S + A),
2076
2077 .SET_ULEB128 => try riscv_util.writeSetSubUleb(.set, stream, S + A),
2078 .SUB_ULEB128 => try riscv_util.writeSetSubUleb(.sub, stream, S - A),
2021 try bw.writeInt(i64, S + A, .little),
2022
2023 .ADD8 => try riscv_util.writeAddend(i8, .add, S + A, bw),
2024 .SUB8 => try riscv_util.writeAddend(i8, .sub, S + A, bw),
2025 .ADD16 => try riscv_util.writeAddend(i16, .add, S + A, bw),
2026 .SUB16 => try riscv_util.writeAddend(i16, .sub, S + A, bw),
2027 .ADD32 => try riscv_util.writeAddend(i32, .add, S + A, bw),
2028 .SUB32 => try riscv_util.writeAddend(i32, .sub, S + A, bw),
2029 .ADD64 => try riscv_util.writeAddend(i64, .add, S + A, bw),
2030 .SUB64 => try riscv_util.writeAddend(i64, .sub, S + A, bw),
2031
2032 .SET8 => try bw.writeInt(i8, @truncate(S + A), .little),
2033 .SET16 => try bw.writeInt(i16, @truncate(S + A), .little),
2034 .SET32 => try bw.writeInt(i32, @truncate(S + A), .little),
2035
2036 .SET6 => try riscv_util.writeSetSub6(.set, S + A, bw),
2037 .SUB6 => try riscv_util.writeSetSub6(.sub, S + A, bw),
2038
2039 .SET_ULEB128 => try riscv_util.writeSetSubUleb(.set, S + A, bw),
2040 .SUB_ULEB128 => try riscv_util.writeSetSubUleb(.sub, S - A, bw),
20792041
20802042 else => try atom.reportUnhandledRelocError(rel, elf_file),
20812043 }
src/link/Elf/AtomList.zig+10-22
......@@ -108,7 +108,7 @@ pub fn write(list: AtomList, buffer: *std.ArrayList(u8), undefs: anytype, elf_fi
108108 const off = math.cast(usize, atom_ptr.value - list.value) orelse return error.Overflow;
109109 const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow;
110110
111 log.debug(" atom({}) at 0x{x}", .{ ref, list.offset(elf_file) + off });
111 log.debug(" atom({f}) at 0x{x}", .{ ref, list.offset(elf_file) + off });
112112
113113 const object = atom_ptr.file(elf_file).?.object;
114114 const code = try object.codeDecompressAlloc(elf_file, ref.index);
......@@ -144,7 +144,7 @@ pub fn writeRelocatable(list: AtomList, buffer: *std.ArrayList(u8), elf_file: *E
144144 const off = math.cast(usize, atom_ptr.value - list.value) orelse return error.Overflow;
145145 const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow;
146146
147 log.debug(" atom({}) at 0x{x}", .{ ref, list.offset(elf_file) + off });
147 log.debug(" atom({f}) at 0x{x}", .{ ref, list.offset(elf_file) + off });
148148
149149 const object = atom_ptr.file(elf_file).?.object;
150150 const code = try object.codeDecompressAlloc(elf_file, ref.index);
......@@ -167,16 +167,10 @@ pub fn lastAtom(list: AtomList, elf_file: *Elf) *Atom {
167167 return elf_file.atom(list.atoms.keys()[list.atoms.keys().len - 1]).?;
168168}
169169
170pub fn format(
171 list: AtomList,
172 comptime unused_fmt_string: []const u8,
173 options: std.fmt.FormatOptions,
174 writer: anytype,
175) !void {
170pub fn format(list: AtomList, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
176171 _ = list;
172 _ = bw;
177173 _ = unused_fmt_string;
178 _ = options;
179 _ = writer;
180174 @compileError("do not format AtomList directly");
181175}
182176
......@@ -186,25 +180,19 @@ pub fn fmt(list: AtomList, elf_file: *Elf) std.fmt.Formatter(format2) {
186180 return .{ .data = .{ list, elf_file } };
187181}
188182
189fn format2(
190 ctx: FormatCtx,
191 comptime unused_fmt_string: []const u8,
192 options: std.fmt.FormatOptions,
193 writer: anytype,
194) !void {
183fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
195184 _ = unused_fmt_string;
196 _ = options;
197185 const list, const elf_file = ctx;
198 try writer.print("list : @{x} : shdr({d}) : align({x}) : size({x})", .{
186 try bw.print("list : @{x} : shdr({d}) : align({x}) : size({x})", .{
199187 list.address(elf_file), list.output_section_index,
200188 list.alignment.toByteUnits() orelse 0, list.size,
201189 });
202 try writer.writeAll(" : atoms{ ");
190 try bw.writeAll(" : atoms{ ");
203191 for (list.atoms.keys(), 0..) |ref, i| {
204 try writer.print("{}", .{ref});
205 if (i < list.atoms.keys().len - 1) try writer.writeAll(", ");
192 try bw.print("{f}", .{ref});
193 if (i < list.atoms.keys().len - 1) try bw.writeAll(", ");
206194 }
207 try writer.writeAll(" }");
195 try bw.writeAll(" }");
208196}
209197
210198const assert = std.debug.assert;
src/link/Elf/LinkerDefined.zig+4-10
......@@ -449,23 +449,17 @@ const FormatContext = struct {
449449 elf_file: *Elf,
450450};
451451
452fn formatSymtab(
453 ctx: FormatContext,
454 comptime unused_fmt_string: []const u8,
455 options: std.fmt.FormatOptions,
456 writer: anytype,
457) !void {
452fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
458453 _ = unused_fmt_string;
459 _ = options;
460454 const self = ctx.self;
461455 const elf_file = ctx.elf_file;
462 try writer.writeAll(" globals\n");
456 try bw.writeAll(" globals\n");
463457 for (self.symbols.items, 0..) |sym, i| {
464458 const ref = self.resolveSymbol(@intCast(i), elf_file);
465459 if (elf_file.symbol(ref)) |ref_sym| {
466 try writer.print(" {}\n", .{ref_sym.fmt(elf_file)});
460 try bw.print(" {f}\n", .{ref_sym.fmt(elf_file)});
467461 } else {
468 try writer.print(" {s} : unclaimed\n", .{sym.name(elf_file)});
462 try bw.print(" {s} : unclaimed\n", .{sym.name(elf_file)});
469463 }
470464 }
471465}
src/link/Elf/Merge.zig+10-34
......@@ -157,16 +157,10 @@ pub const Section = struct {
157157 }
158158 };
159159
160 pub fn format(
161 msec: Section,
162 comptime unused_fmt_string: []const u8,
163 options: std.fmt.FormatOptions,
164 writer: anytype,
165 ) !void {
160 pub fn format(msec: Section, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
166161 _ = msec;
162 _ = bw;
167163 _ = unused_fmt_string;
168 _ = options;
169 _ = writer;
170164 @compileError("do not format directly");
171165 }
172166
......@@ -182,17 +176,11 @@ pub const Section = struct {
182176 elf_file: *Elf,
183177 };
184178
185 pub fn format2(
186 ctx: FormatContext,
187 comptime unused_fmt_string: []const u8,
188 options: std.fmt.FormatOptions,
189 writer: anytype,
190 ) !void {
191 _ = options;
179 pub fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
192180 _ = unused_fmt_string;
193181 const msec = ctx.msec;
194182 const elf_file = ctx.elf_file;
195 try writer.print("{s} : @{x} : size({x}) : align({x}) : entsize({x}) : type({x}) : flags({x})\n", .{
183 try bw.print("{s} : @{x} : size({x}) : align({x}) : entsize({x}) : type({x}) : flags({x})\n", .{
196184 msec.name(elf_file),
197185 msec.address(elf_file),
198186 msec.size,
......@@ -202,7 +190,7 @@ pub const Section = struct {
202190 msec.flags,
203191 });
204192 for (msec.subsections.items) |msub| {
205 try writer.print(" {}\n", .{msub.fmt(elf_file)});
193 try bw.print(" {f}\n", .{msub.fmt(elf_file)});
206194 }
207195 }
208196
......@@ -231,16 +219,10 @@ pub const Subsection = struct {
231219 return msec.bytes.items[msub.string_index..][0..msub.size];
232220 }
233221
234 pub fn format(
235 msub: Subsection,
236 comptime unused_fmt_string: []const u8,
237 options: std.fmt.FormatOptions,
238 writer: anytype,
239 ) !void {
222 pub fn format(msub: Subsection, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
240223 _ = msub;
224 _ = bw;
241225 _ = unused_fmt_string;
242 _ = options;
243 _ = writer;
244226 @compileError("do not format directly");
245227 }
246228
......@@ -256,22 +238,16 @@ pub const Subsection = struct {
256238 elf_file: *Elf,
257239 };
258240
259 pub fn format2(
260 ctx: FormatContext,
261 comptime unused_fmt_string: []const u8,
262 options: std.fmt.FormatOptions,
263 writer: anytype,
264 ) !void {
265 _ = options;
241 pub fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
266242 _ = unused_fmt_string;
267243 const msub = ctx.msub;
268244 const elf_file = ctx.elf_file;
269 try writer.print("@{x} : align({x}) : size({x})", .{
245 try bw.print("@{x} : align({x}) : size({x})", .{
270246 msub.address(elf_file),
271247 msub.alignment,
272248 msub.size,
273249 });
274 if (!msub.alive) try writer.writeAll(" : [*]");
250 if (!msub.alive) try bw.writeAll(" : [*]");
275251 }
276252
277253 pub const Index = u32;
src/link/Elf/Object.zig+47-90
......@@ -281,7 +281,7 @@ fn initAtoms(
281281 elf.SHT_GROUP => {
282282 if (shdr.sh_info >= self.symtab.items.len) {
283283 // TODO convert into an error
284 log.debug("{}: invalid symbol index in sh_info", .{self.fmtPath()});
284 log.debug("{f}: invalid symbol index in sh_info", .{self.fmtPath()});
285285 continue;
286286 }
287287 const group_info_sym = self.symtab.items[shdr.sh_info];
......@@ -448,7 +448,8 @@ fn parseEhFrame(
448448 const fdes_start = self.fdes.items.len;
449449 const cies_start = self.cies.items.len;
450450
451 var it = eh_frame.Iterator{ .data = raw };
451 var it: eh_frame.Iterator = undefined;
452 it.br.initFixed(raw);
452453 while (try it.next()) |rec| {
453454 const rel_range = filterRelocs(self.relocs.items[rel_start..][0..relocs.len], rec.offset, rec.size + 4);
454455 switch (rec.tag) {
......@@ -488,7 +489,7 @@ fn parseEhFrame(
488489 if (cie.offset == cie_ptr) break @as(u32, @intCast(cie_index));
489490 } else {
490491 // TODO convert into an error
491 log.debug("{s}: no matching CIE found for FDE at offset {x}", .{
492 log.debug("{f}: no matching CIE found for FDE at offset {x}", .{
492493 self.fmtPath(),
493494 fde.offset,
494495 });
......@@ -582,7 +583,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
582583 if (sym.flags.import) {
583584 if (sym.type(elf_file) != elf.STT_FUNC)
584585 // TODO convert into an error
585 log.debug("{s}: {s}: CIE referencing external data reference", .{
586 log.debug("{fs}: {s}: CIE referencing external data reference", .{
586587 self.fmtPath(), sym.name(elf_file),
587588 });
588589 sym.flags.needs_plt = true;
......@@ -796,7 +797,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void {
796797 if (!isNull(data[end .. end + sh_entsize])) {
797798 var err = try diags.addErrorWithNotes(1);
798799 try err.addMsg("string not null terminated", .{});
799 err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
800 err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
800801 return error.LinkFailure;
801802 }
802803 end += sh_entsize;
......@@ -811,7 +812,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void {
811812 if (shdr.sh_size % sh_entsize != 0) {
812813 var err = try diags.addErrorWithNotes(1);
813814 try err.addMsg("size not a multiple of sh_entsize", .{});
814 err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
815 err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
815816 return error.LinkFailure;
816817 }
817818
......@@ -889,7 +890,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
889890 var err = try diags.addErrorWithNotes(2);
890891 try err.addMsg("invalid symbol value: {x}", .{esym.st_value});
891892 err.addNote("for symbol {s}", .{sym.name(elf_file)});
892 err.addNote("in {}", .{self.fmtPath()});
893 err.addNote("in {f}", .{self.fmtPath()});
893894 return error.LinkFailure;
894895 };
895896
......@@ -914,7 +915,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
914915 const res = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse {
915916 var err = try diags.addErrorWithNotes(1);
916917 try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset});
917 err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
918 err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
918919 return error.LinkFailure;
919920 };
920921
......@@ -952,7 +953,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
952953 const is_tls = sym.type(elf_file) == elf.STT_TLS;
953954 const name = if (is_tls) ".tls_common" else ".common";
954955 const name_offset = @as(u32, @intCast(self.strtab.items.len));
955 try self.strtab.writer(gpa).print("{s}\x00", .{name});
956 try self.strtab.print(gpa, "{s}\x00", .{name});
956957
957958 var sh_flags: u32 = elf.SHF_ALLOC | elf.SHF_WRITE;
958959 if (is_tls) sh_flags |= elf.SHF_TLS;
......@@ -1191,28 +1192,26 @@ pub fn codeDecompressAlloc(self: *Object, elf_file: *Elf, atom_index: Atom.Index
11911192 const atom_ptr = self.atom(atom_index).?;
11921193 const shdr = atom_ptr.inputShdr(elf_file);
11931194 const handle = elf_file.fileHandle(self.file_handle);
1194 const data = try self.preadShdrContentsAlloc(gpa, handle, atom_ptr.input_section_index);
1195 defer if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) gpa.free(data);
1195 var br: std.io.BufferedReader = undefined;
1196 br.initFixed(try self.preadShdrContentsAlloc(gpa, handle, atom_ptr.input_section_index));
1197 defer if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) gpa.free(br.storageBuffer());
11961198
11971199 if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) {
1198 const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*;
1200 const chdr = (try br.takeStruct(elf.Elf64_Chdr)).*;
11991201 switch (chdr.ch_type) {
12001202 .ZLIB => {
1201 var stream = std.io.fixedBufferStream(data[@sizeOf(elf.Elf64_Chdr)..]);
1202 var zlib_stream = std.compress.zlib.decompressor(stream.reader());
1203 const size = std.math.cast(usize, chdr.ch_size) orelse return error.Overflow;
1204 const decomp = try gpa.alloc(u8, size);
1205 const nread = zlib_stream.reader().readAll(decomp) catch return error.InputOutput;
1206 if (nread != decomp.len) {
1207 return error.InputOutput;
1208 }
1209 return decomp;
1203 var bw: std.io.BufferedWriter = undefined;
1204 bw.initFixed(try gpa.alloc(u8, std.math.cast(usize, chdr.ch_size) orelse return error.Overflow));
1205 errdefer gpa.free(bw.buffer);
1206 try std.compress.zlib.decompress(&br, &bw);
1207 if (bw.end != bw.buffer.len) return error.InputOutput;
1208 return bw.buffer;
12101209 },
12111210 else => @panic("TODO unhandled compression scheme"),
12121211 }
12131212 }
12141213
1215 return data;
1214 return br.storageBuffer();
12161215}
12171216
12181217fn locals(self: *Object) []Symbol {
......@@ -1432,16 +1431,10 @@ pub fn group(self: *Object, index: Elf.Group.Index) *Elf.Group {
14321431 return &self.groups.items[index];
14331432}
14341433
1435pub fn format(
1436 self: *Object,
1437 comptime unused_fmt_string: []const u8,
1438 options: std.fmt.FormatOptions,
1439 writer: anytype,
1440) !void {
1434pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
14411435 _ = self;
1436 _ = bw;
14421437 _ = unused_fmt_string;
1443 _ = options;
1444 _ = writer;
14451438 @compileError("do not format objects directly");
14461439}
14471440
......@@ -1457,28 +1450,22 @@ const FormatContext = struct {
14571450 elf_file: *Elf,
14581451};
14591452
1460fn formatSymtab(
1461 ctx: FormatContext,
1462 comptime unused_fmt_string: []const u8,
1463 options: std.fmt.FormatOptions,
1464 writer: anytype,
1465) !void {
1453fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
14661454 _ = unused_fmt_string;
1467 _ = options;
14681455 const object = ctx.object;
14691456 const elf_file = ctx.elf_file;
1470 try writer.writeAll(" locals\n");
1457 try bw.writeAll(" locals\n");
14711458 for (object.locals()) |sym| {
1472 try writer.print(" {}\n", .{sym.fmt(elf_file)});
1459 try bw.print(" {f}\n", .{sym.fmt(elf_file)});
14731460 }
1474 try writer.writeAll(" globals\n");
1461 try bw.writeAll(" globals\n");
14751462 for (object.globals(), 0..) |sym, i| {
14761463 const first_global = object.first_global.?;
14771464 const ref = object.resolveSymbol(@intCast(i + first_global), elf_file);
14781465 if (elf_file.symbol(ref)) |ref_sym| {
1479 try writer.print(" {}\n", .{ref_sym.fmt(elf_file)});
1466 try bw.print(" {f}\n", .{ref_sym.fmt(elf_file)});
14801467 } else {
1481 try writer.print(" {s} : unclaimed\n", .{sym.name(elf_file)});
1468 try bw.print(" {s} : unclaimed\n", .{sym.name(elf_file)});
14821469 }
14831470 }
14841471}
......@@ -1490,19 +1477,13 @@ pub fn fmtAtoms(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatAtoms) {
14901477 } };
14911478}
14921479
1493fn formatAtoms(
1494 ctx: FormatContext,
1495 comptime unused_fmt_string: []const u8,
1496 options: std.fmt.FormatOptions,
1497 writer: anytype,
1498) !void {
1480fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
14991481 _ = unused_fmt_string;
1500 _ = options;
15011482 const object = ctx.object;
1502 try writer.writeAll(" atoms\n");
1483 try bw.writeAll(" atoms\n");
15031484 for (object.atoms_indexes.items) |atom_index| {
15041485 const atom_ptr = object.atom(atom_index) orelse continue;
1505 try writer.print(" {}\n", .{atom_ptr.fmt(ctx.elf_file)});
1486 try bw.print(" {f}\n", .{atom_ptr.fmt(ctx.elf_file)});
15061487 }
15071488}
15081489
......@@ -1513,18 +1494,12 @@ pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) {
15131494 } };
15141495}
15151496
1516fn formatCies(
1517 ctx: FormatContext,
1518 comptime unused_fmt_string: []const u8,
1519 options: std.fmt.FormatOptions,
1520 writer: anytype,
1521) !void {
1497fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
15221498 _ = unused_fmt_string;
1523 _ = options;
15241499 const object = ctx.object;
1525 try writer.writeAll(" cies\n");
1500 try bw.writeAll(" cies\n");
15261501 for (object.cies.items, 0..) |cie, i| {
1527 try writer.print(" cie({d}) : {}\n", .{ i, cie.fmt(ctx.elf_file) });
1502 try bw.print(" cie({d}) : {f}\n", .{ i, cie.fmt(ctx.elf_file) });
15281503 }
15291504}
15301505
......@@ -1535,18 +1510,12 @@ pub fn fmtFdes(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatFdes) {
15351510 } };
15361511}
15371512
1538fn formatFdes(
1539 ctx: FormatContext,
1540 comptime unused_fmt_string: []const u8,
1541 options: std.fmt.FormatOptions,
1542 writer: anytype,
1543) !void {
1513fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
15441514 _ = unused_fmt_string;
1545 _ = options;
15461515 const object = ctx.object;
1547 try writer.writeAll(" fdes\n");
1516 try bw.writeAll(" fdes\n");
15481517 for (object.fdes.items, 0..) |fde, i| {
1549 try writer.print(" fde({d}) : {}\n", .{ i, fde.fmt(ctx.elf_file) });
1518 try bw.print(" fde({d}) : {f}\n", .{ i, fde.fmt(ctx.elf_file) });
15501519 }
15511520}
15521521
......@@ -1557,26 +1526,20 @@ pub fn fmtGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatGroups)
15571526 } };
15581527}
15591528
1560fn formatGroups(
1561 ctx: FormatContext,
1562 comptime unused_fmt_string: []const u8,
1563 options: std.fmt.FormatOptions,
1564 writer: anytype,
1565) !void {
1529fn formatGroups(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
15661530 _ = unused_fmt_string;
1567 _ = options;
15681531 const object = ctx.object;
15691532 const elf_file = ctx.elf_file;
1570 try writer.writeAll(" groups\n");
1533 try bw.writeAll(" groups\n");
15711534 for (object.groups.items, 0..) |g, g_index| {
1572 try writer.print(" {s}({d})", .{ if (g.is_comdat) "COMDAT" else "GROUP", g_index });
1573 if (!g.alive) try writer.writeAll(" : [*]");
1574 try writer.writeByte('\n');
1535 try bw.print(" {s}({d})", .{ if (g.is_comdat) "COMDAT" else "GROUP", g_index });
1536 if (!g.alive) try bw.writeAll(" : [*]");
1537 try bw.writeByte('\n');
15751538 const g_members = g.members(elf_file);
15761539 for (g_members) |shndx| {
15771540 const atom_index = object.atoms_indexes.items[shndx];
15781541 const atom_ptr = object.atom(atom_index) orelse continue;
1579 try writer.print(" atom({d}) : {s}\n", .{ atom_index, atom_ptr.name(elf_file) });
1542 try bw.print(" atom({d}) : {s}\n", .{ atom_index, atom_ptr.name(elf_file) });
15801543 }
15811544 }
15821545}
......@@ -1585,18 +1548,12 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) {
15851548 return .{ .data = self };
15861549}
15871550
1588fn formatPath(
1589 object: Object,
1590 comptime unused_fmt_string: []const u8,
1591 options: std.fmt.FormatOptions,
1592 writer: anytype,
1593) !void {
1551fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
15941552 _ = unused_fmt_string;
1595 _ = options;
15961553 if (object.archive) |ar| {
1597 try writer.print("{}({})", .{ ar.path, object.path });
1554 try bw.print("{f}({f})", .{ ar.path, object.path });
15981555 } else {
1599 try writer.print("{}", .{object.path});
1556 try bw.print("{f}", .{object.path});
16001557 }
16011558}
16021559
src/link/Elf/SharedObject.zig+6-18
......@@ -509,16 +509,10 @@ pub fn setSymbolExtra(self: *SharedObject, index: u32, extra: Symbol.Extra) void
509509 }
510510}
511511
512pub fn format(
513 self: SharedObject,
514 comptime unused_fmt_string: []const u8,
515 options: std.fmt.FormatOptions,
516 writer: anytype,
517) !void {
512pub fn format(self: SharedObject, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
518513 _ = self;
514 _ = bw;
519515 _ = unused_fmt_string;
520 _ = options;
521 _ = writer;
522516 @compileError("unreachable");
523517}
524518
......@@ -534,23 +528,17 @@ const FormatContext = struct {
534528 elf_file: *Elf,
535529};
536530
537fn formatSymtab(
538 ctx: FormatContext,
539 comptime unused_fmt_string: []const u8,
540 options: std.fmt.FormatOptions,
541 writer: anytype,
542) !void {
531fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
543532 _ = unused_fmt_string;
544 _ = options;
545533 const shared = ctx.shared;
546534 const elf_file = ctx.elf_file;
547 try writer.writeAll(" globals\n");
535 try bw.writeAll(" globals\n");
548536 for (shared.symbols.items, 0..) |sym, i| {
549537 const ref = shared.resolveSymbol(@intCast(i), elf_file);
550538 if (elf_file.symbol(ref)) |ref_sym| {
551 try writer.print(" {}\n", .{ref_sym.fmt(elf_file)});
539 try bw.print(" {f}\n", .{ref_sym.fmt(elf_file)});
552540 } else {
553 try writer.print(" {s} : unclaimed\n", .{sym.name(elf_file)});
541 try bw.print(" {s} : unclaimed\n", .{sym.name(elf_file)});
554542 }
555543 }
556544}
src/link/Elf/Symbol.zig+15-33
......@@ -316,16 +316,10 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
316316 out.st_size = esym.st_size;
317317}
318318
319pub fn format(
320 symbol: Symbol,
321 comptime unused_fmt_string: []const u8,
322 options: std.fmt.FormatOptions,
323 writer: anytype,
324) !void {
319pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
325320 _ = symbol;
321 _ = bw;
326322 _ = unused_fmt_string;
327 _ = options;
328 _ = writer;
329323 @compileError("do not format Symbol directly");
330324}
331325
......@@ -341,24 +335,18 @@ pub fn fmtName(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(formatName) {
341335 } };
342336}
343337
344fn formatName(
345 ctx: FormatContext,
346 comptime unused_fmt_string: []const u8,
347 options: std.fmt.FormatOptions,
348 writer: anytype,
349) !void {
350 _ = options;
338fn formatName(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
351339 _ = unused_fmt_string;
352340 const elf_file = ctx.elf_file;
353341 const symbol = ctx.symbol;
354 try writer.writeAll(symbol.name(elf_file));
342 try bw.writeAll(symbol.name(elf_file));
355343 switch (symbol.version_index.VERSION) {
356344 @intFromEnum(elf.VER_NDX.LOCAL), @intFromEnum(elf.VER_NDX.GLOBAL) => {},
357345 else => {
358346 const file_ptr = symbol.file(elf_file).?;
359347 assert(file_ptr == .shared_object);
360348 const shared_object = file_ptr.shared_object;
361 try writer.print("@{s}", .{shared_object.versionString(symbol.version_index)});
349 try bw.print("@{s}", .{shared_object.versionString(symbol.version_index)});
362350 },
363351 }
364352}
......@@ -370,17 +358,11 @@ pub fn fmt(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(format2) {
370358 } };
371359}
372360
373fn format2(
374 ctx: FormatContext,
375 comptime unused_fmt_string: []const u8,
376 options: std.fmt.FormatOptions,
377 writer: anytype,
378) !void {
379 _ = options;
361fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
380362 _ = unused_fmt_string;
381363 const symbol = ctx.symbol;
382364 const elf_file = ctx.elf_file;
383 try writer.print("%{d} : {s} : @{x}", .{
365 try bw.print("%{d} : {f} : @{x}", .{
384366 symbol.esym_index,
385367 symbol.fmtName(elf_file),
386368 symbol.address(.{ .plt = false, .trampoline = false }, elf_file),
......@@ -388,25 +370,25 @@ fn format2(
388370 if (symbol.file(elf_file)) |file_ptr| {
389371 if (symbol.isAbs(elf_file)) {
390372 if (symbol.elfSym(elf_file).st_shndx == elf.SHN_UNDEF) {
391 try writer.writeAll(" : undef");
373 try bw.writeAll(" : undef");
392374 } else {
393 try writer.writeAll(" : absolute");
375 try bw.writeAll(" : absolute");
394376 }
395377 } else if (symbol.outputShndx(elf_file)) |shndx| {
396 try writer.print(" : shdr({d})", .{shndx});
378 try bw.print(" : shdr({d})", .{shndx});
397379 }
398380 if (symbol.atom(elf_file)) |atom_ptr| {
399 try writer.print(" : atom({d})", .{atom_ptr.atom_index});
381 try bw.print(" : atom({d})", .{atom_ptr.atom_index});
400382 }
401383 var buf: [2]u8 = .{'_'} ** 2;
402384 if (symbol.flags.@"export") buf[0] = 'E';
403385 if (symbol.flags.import) buf[1] = 'I';
404 try writer.print(" : {s}", .{&buf});
405 if (symbol.flags.weak) try writer.writeAll(" : weak");
386 try bw.print(" : {s}", .{&buf});
387 if (symbol.flags.weak) try bw.writeAll(" : weak");
406388 switch (file_ptr) {
407 inline else => |x| try writer.print(" : {s}({d})", .{ @tagName(file_ptr), x.index }),
389 inline else => |x| try bw.print(" : {s}({d})", .{ @tagName(file_ptr), x.index }),
408390 }
409 } else try writer.writeAll(" : unresolved");
391 } else try bw.writeAll(" : unresolved");
410392}
411393
412394pub const Flags = packed struct {
src/link/Elf/Thunk.zig+5-17
......@@ -65,16 +65,10 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) usize {
6565 };
6666}
6767
68pub fn format(
69 thunk: Thunk,
70 comptime unused_fmt_string: []const u8,
71 options: std.fmt.FormatOptions,
72 writer: anytype,
73) !void {
68pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
7469 _ = thunk;
70 _ = bw;
7571 _ = unused_fmt_string;
76 _ = options;
77 _ = writer;
7872 @compileError("do not format Thunk directly");
7973}
8074
......@@ -90,20 +84,14 @@ const FormatContext = struct {
9084 elf_file: *Elf,
9185};
9286
93fn format2(
94 ctx: FormatContext,
95 comptime unused_fmt_string: []const u8,
96 options: std.fmt.FormatOptions,
97 writer: anytype,
98) !void {
99 _ = options;
87fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
10088 _ = unused_fmt_string;
10189 const thunk = ctx.thunk;
10290 const elf_file = ctx.elf_file;
103 try writer.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) });
91 try bw.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) });
10492 for (thunk.symbols.keys()) |ref| {
10593 const sym = elf_file.symbol(ref).?;
106 try writer.print(" {} : {s} : @{x}\n", .{ ref, sym.name(elf_file), sym.value });
94 try bw.print(" {f} : {s} : @{x}\n", .{ ref, sym.name(elf_file), sym.value });
10795 }
10896}
10997
src/link/Elf/ZigObject.zig+20-41
......@@ -35,9 +35,6 @@ lazy_syms: LazySymbolTable = .{},
3535/// Table of tracked `Nav`s.
3636navs: NavTable = .{},
3737
38/// TLS variables indexed by Atom.Index.
39tls_variables: TlsTable = .{},
40
4138/// Table of tracked `Uav`s.
4239uavs: UavTable = .{},
4340
......@@ -257,7 +254,6 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
257254 meta.exports.deinit(allocator);
258255 }
259256 self.uavs.deinit(allocator);
260 self.tls_variables.deinit(allocator);
261257
262258 if (self.dwarf) |*dwarf| {
263259 dwarf.deinit();
......@@ -925,7 +921,7 @@ pub fn getNavVAddr(
925921 const zcu = pt.zcu;
926922 const ip = &zcu.intern_pool;
927923 const nav = ip.getNav(nav_index);
928 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
924 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
929925 const this_sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol(
930926 elf_file,
931927 nav.name.toSlice(ip),
......@@ -1268,7 +1264,7 @@ fn updateNavCode(
12681264 const ip = &zcu.intern_pool;
12691265 const nav = ip.getNav(nav_index);
12701266
1271 log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1267 log.debug("updateNavCode {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
12721268
12731269 const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
12741270 const required_alignment = switch (pt.navAlignment(nav_index)) {
......@@ -1302,7 +1298,7 @@ fn updateNavCode(
13021298 self.allocateAtom(atom_ptr, true, elf_file) catch |err|
13031299 return elf_file.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(err)});
13041300
1305 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom_ptr.value });
1301 log.debug("growing {f} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom_ptr.value });
13061302 if (old_vaddr != atom_ptr.value) {
13071303 sym.value = 0;
13081304 esym.st_value = 0;
......@@ -1347,7 +1343,7 @@ fn updateNavCode(
13471343 const file_offset = atom_ptr.offset(elf_file);
13481344 elf_file.base.file.?.pwriteAll(code, file_offset) catch |err|
13491345 return elf_file.base.cgFail(nav_index, "failed to write to output file: {s}", .{@errorName(err)});
1350 log.debug("writing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), file_offset, file_offset + code.len });
1346 log.debug("writing {f} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), file_offset, file_offset + code.len });
13511347 }
13521348}
13531349
......@@ -1365,7 +1361,7 @@ fn updateTlv(
13651361 const gpa = zcu.gpa;
13661362 const nav = ip.getNav(nav_index);
13671363
1368 log.debug("updateTlv {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1364 log.debug("updateTlv {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
13691365
13701366 const required_alignment = pt.navAlignment(nav_index);
13711367
......@@ -1386,9 +1382,6 @@ fn updateTlv(
13861382 atom_ptr.alignment = required_alignment;
13871383 atom_ptr.size = code.len;
13881384
1389 const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index);
1390 assert(!gop.found_existing); // TODO incremental updates
1391
13921385 self.allocateAtom(atom_ptr, true, elf_file) catch |err|
13931386 return elf_file.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(err)});
13941387 sym.value = 0;
......@@ -1424,7 +1417,7 @@ pub fn updateFunc(
14241417 const gpa = elf_file.base.comp.gpa;
14251418 const func = zcu.funcInfo(func_index);
14261419
1427 log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
1420 log.debug("updateFunc {f}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
14281421
14291422 const sym_index = try self.getOrCreateMetadataForNav(zcu, func.owner_nav);
14301423 self.atom(self.symbol(sym_index).ref.index).?.freeRelocs(self);
......@@ -1447,7 +1440,7 @@ pub fn updateFunc(
14471440 const code = code_buffer.items;
14481441
14491442 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code);
1450 log.debug("setting shdr({x},{s}) for {}", .{
1443 log.debug("setting shdr({x},{s}) for {f}", .{
14511444 shndx,
14521445 elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
14531446 ip.getNav(func.owner_nav).fqn.fmt(ip),
......@@ -1529,7 +1522,7 @@ pub fn updateNav(
15291522 const ip = &zcu.intern_pool;
15301523 const nav = ip.getNav(nav_index);
15311524
1532 log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1525 log.debug("updateNav {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
15331526
15341527 const nav_init = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
15351528 .func => .none,
......@@ -1546,7 +1539,6 @@ pub fn updateNav(
15461539 defer debug_wip_nav.deinit();
15471540 dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) {
15481541 error.OutOfMemory => return error.OutOfMemory,
1549 error.Overflow => return error.Overflow,
15501542 else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
15511543 };
15521544 }
......@@ -1576,7 +1568,7 @@ pub fn updateNav(
15761568 const code = code_buffer.items;
15771569
15781570 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code);
1579 log.debug("setting shdr({x},{s}) for {}", .{
1571 log.debug("setting shdr({x},{s}) for {f}", .{
15801572 shndx,
15811573 elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name),
15821574 nav.fqn.fmt(ip),
......@@ -1588,7 +1580,6 @@ pub fn updateNav(
15881580
15891581 if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) {
15901582 error.OutOfMemory => return error.OutOfMemory,
1591 error.Overflow => return error.Overflow,
15921583 else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
15931584 };
15941585 } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
......@@ -1622,7 +1613,7 @@ fn updateLazySymbol(
16221613 defer code_buffer.deinit(gpa);
16231614
16241615 const name_str_index = blk: {
1625 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1616 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
16261617 @tagName(sym.kind),
16271618 Type.fromInterned(sym.ty).fmt(pt),
16281619 });
......@@ -2207,25 +2198,19 @@ const FormatContext = struct {
22072198 elf_file: *Elf,
22082199};
22092200
2210fn formatSymtab(
2211 ctx: FormatContext,
2212 comptime unused_fmt_string: []const u8,
2213 options: std.fmt.FormatOptions,
2214 writer: anytype,
2215) !void {
2201fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
22162202 _ = unused_fmt_string;
2217 _ = options;
22182203 const self = ctx.self;
22192204 const elf_file = ctx.elf_file;
2220 try writer.writeAll(" locals\n");
2205 try bw.writeAll(" locals\n");
22212206 for (self.local_symbols.items) |index| {
22222207 const local = self.symbols.items[index];
2223 try writer.print(" {}\n", .{local.fmt(elf_file)});
2208 try bw.print(" {f}\n", .{local.fmt(elf_file)});
22242209 }
2225 try writer.writeAll(" globals\n");
2210 try bw.writeAll(" globals\n");
22262211 for (ctx.self.global_symbols.items) |index| {
22272212 const global = self.symbols.items[index];
2228 try writer.print(" {}\n", .{global.fmt(elf_file)});
2213 try bw.print(" {f}\n", .{global.fmt(elf_file)});
22292214 }
22302215}
22312216
......@@ -2236,18 +2221,12 @@ pub fn fmtAtoms(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatAtoms)
22362221 } };
22372222}
22382223
2239fn formatAtoms(
2240 ctx: FormatContext,
2241 comptime unused_fmt_string: []const u8,
2242 options: std.fmt.FormatOptions,
2243 writer: anytype,
2244) !void {
2224fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
22452225 _ = unused_fmt_string;
2246 _ = options;
2247 try writer.writeAll(" atoms\n");
2226 try bw.writeAll(" atoms\n");
22482227 for (ctx.self.atoms_indexes.items) |atom_index| {
22492228 const atom_ptr = ctx.self.atom(atom_index) orelse continue;
2250 try writer.print(" {}\n", .{atom_ptr.fmt(ctx.elf_file)});
2229 try bw.print(" {f}\n", .{atom_ptr.fmt(ctx.elf_file)});
22512230 }
22522231}
22532232
......@@ -2285,7 +2264,7 @@ fn checkNavAllocated(pt: Zcu.PerThread, index: InternPool.Nav.Index, meta: AvMet
22852264 const zcu = pt.zcu;
22862265 const ip = &zcu.intern_pool;
22872266 const nav = ip.getNav(index);
2288 log.err("NAV {}({d}) assigned symbol {d} but not allocated!", .{
2267 log.err("NAV {f}({d}) assigned symbol {d} but not allocated!", .{
22892268 nav.fqn.fmt(ip),
22902269 index,
22912270 meta.symbol_index,
......@@ -2298,7 +2277,7 @@ fn checkUavAllocated(pt: Zcu.PerThread, index: InternPool.Index, meta: AvMetadat
22982277 const zcu = pt.zcu;
22992278 const uav = Value.fromInterned(index);
23002279 const ty = uav.typeOf(zcu);
2301 log.err("UAV {}({d}) assigned symbol {d} but not allocated!", .{
2280 log.err("UAV {f}({d}) assigned symbol {d} but not allocated!", .{
23022281 ty.fmt(pt),
23032282 index,
23042283 meta.symbol_index,
src/link/Elf/eh_frame.zig+37-50
......@@ -49,14 +49,12 @@ pub const Fde = struct {
4949
5050 pub fn format(
5151 fde: Fde,
52 bw: *std.io.BufferedWriter,
5253 comptime unused_fmt_string: []const u8,
53 options: std.fmt.FormatOptions,
54 writer: *std.io.BufferedWriter,
5554 ) !void {
5655 _ = fde;
5756 _ = unused_fmt_string;
58 _ = options;
59 _ = writer;
57 _ = bw;
6058 @compileError("do not format FDEs directly");
6159 }
6260
......@@ -74,24 +72,22 @@ pub const Fde = struct {
7472
7573 fn format2(
7674 ctx: FdeFormatContext,
75 bw: *std.io.BufferedWriter,
7776 comptime unused_fmt_string: []const u8,
78 options: std.fmt.FormatOptions,
79 writer: *std.io.BufferedWriter,
8077 ) !void {
8178 _ = unused_fmt_string;
82 _ = options;
8379 const fde = ctx.fde;
8480 const elf_file = ctx.elf_file;
8581 const base_addr = fde.address(elf_file);
8682 const object = elf_file.file(fde.file_index).?.object;
8783 const atom_name = fde.atom(object).name(elf_file);
88 try writer.print("@{x} : size({x}) : cie({d}) : {s}", .{
84 try bw.print("@{x} : size({x}) : cie({d}) : {s}", .{
8985 base_addr + fde.out_offset,
9086 fde.calcSize(),
9187 fde.cie_index,
9288 atom_name,
9389 });
94 if (!fde.alive) try writer.writeAll(" : [*]");
90 if (!fde.alive) try bw.writeAll(" : [*]");
9591 }
9692};
9793
......@@ -152,14 +148,12 @@ pub const Cie = struct {
152148
153149 pub fn format(
154150 cie: Cie,
151 bw: *std.io.BufferedWriter,
155152 comptime unused_fmt_string: []const u8,
156 options: std.fmt.FormatOptions,
157 writer: *std.io.BufferedWriter,
158153 ) !void {
159154 _ = cie;
160155 _ = unused_fmt_string;
161 _ = options;
162 _ = writer;
156 _ = bw;
163157 @compileError("do not format CIEs directly");
164158 }
165159
......@@ -177,26 +171,23 @@ pub const Cie = struct {
177171
178172 fn format2(
179173 ctx: CieFormatContext,
174 bw: *std.io.BufferedWriter,
180175 comptime unused_fmt_string: []const u8,
181 options: std.fmt.FormatOptions,
182 writer: *std.io.BufferedWriter,
183176 ) !void {
184177 _ = unused_fmt_string;
185 _ = options;
186178 const cie = ctx.cie;
187179 const elf_file = ctx.elf_file;
188180 const base_addr = cie.address(elf_file);
189 try writer.print("@{x} : size({x})", .{
181 try bw.print("@{x} : size({x})", .{
190182 base_addr + cie.out_offset,
191183 cie.calcSize(),
192184 });
193 if (!cie.alive) try writer.writeAll(" : [*]");
185 if (!cie.alive) try bw.writeAll(" : [*]");
194186 }
195187};
196188
197189pub const Iterator = struct {
198 data: []const u8,
199 pos: usize = 0,
190 br: std.io.BufferedReader,
200191
201192 pub const Record = struct {
202193 tag: enum { fde, cie },
......@@ -205,22 +196,18 @@ pub const Iterator = struct {
205196 };
206197
207198 pub fn next(it: *Iterator) !?Record {
208 if (it.pos >= it.data.len) return null;
199 if (it.br.seek >= it.br.storageBuffer().len) return null;
209200
210 var stream = std.io.fixedBufferStream(it.data[it.pos..]);
211 const reader = stream.reader();
201 const size = try it.br.takeInt(u32, .little);
202 if (size == 0xFFFFFFFF) @panic("DWARF CFI is 32bit on macOS");
212203
213 const size = try reader.readInt(u32, .little);
214 if (size == 0) return null;
215 if (size == 0xFFFFFFFF) @panic("TODO");
216
217 const id = try reader.readInt(u32, .little);
218 const record = Record{
204 const id = try it.br.takeInt(u32, .little);
205 const record: Record = .{
219206 .tag = if (id == 0) .cie else .fde,
220 .offset = it.pos,
207 .offset = it.br.seek,
221208 .size = size,
222209 };
223 it.pos += size + 4;
210 try it.br.discard(size);
224211
225212 return record;
226213 }
......@@ -316,7 +303,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
316303 const S = math.cast(i64, sym.address(.{}, elf_file)) orelse return error.Overflow;
317304 const A = rel.r_addend;
318305
319 relocs_log.debug(" {s}: {x}: [{x} => {x}] ({s})", .{
306 relocs_log.debug(" {f}: {x}: [{x} => {x}] ({s})", .{
320307 relocation.fmtRelocType(rel.r_type(), cpu_arch),
321308 offset,
322309 P,
......@@ -332,7 +319,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
332319 }
333320}
334321
335pub fn writeEhFrame(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
322pub fn writeEhFrame(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
336323 relocs_log.debug("{x}: .eh_frame", .{
337324 elf_file.sections.items(.shdr)[elf_file.section_indexes.eh_frame.?].sh_addr,
338325 });
......@@ -356,7 +343,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
356343 };
357344 }
358345
359 try writer.writeAll(contents);
346 try bw.writeAll(contents);
360347 }
361348 }
362349
......@@ -384,22 +371,22 @@ pub fn writeEhFrame(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
384371 };
385372 }
386373
387 try writer.writeAll(contents);
374 try bw.writeAll(contents);
388375 }
389376 }
390377
391 try writer.writeInt(u32, 0, .little);
378 try bw.writeInt(u32, 0, .little);
392379
393380 if (has_reloc_errors) return error.RelocFailure;
394381}
395382
396pub fn writeEhFrameRelocatable(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
383pub fn writeEhFrameRelocatable(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
397384 for (elf_file.objects.items) |index| {
398385 const object = elf_file.file(index).?.object;
399386
400387 for (object.cies.items) |cie| {
401388 if (!cie.alive) continue;
402 try writer.writeAll(cie.data(elf_file));
389 try bw.writeAll(cie.data(elf_file));
403390 }
404391 }
405392
......@@ -418,7 +405,7 @@ pub fn writeEhFrameRelocatable(elf_file: *Elf, writer: *std.io.BufferedWriter) !
418405 .little,
419406 );
420407
421 try writer.writeAll(contents);
408 try bw.writeAll(contents);
422409 }
423410 }
424411}
......@@ -438,7 +425,7 @@ fn emitReloc(elf_file: *Elf, r_offset: u64, sym: *const Symbol, rel: elf.Elf64_R
438425 },
439426 }
440427
441 relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{
428 relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{
442429 relocation.fmtRelocType(r_type, cpu_arch),
443430 r_offset,
444431 r_sym,
......@@ -495,14 +482,14 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, relocs: *std.ArrayList(elf.Elf64_Rela)
495482 }
496483}
497484
498pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
485pub fn writeEhFrameHdr(elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
499486 const comp = elf_file.base.comp;
500487 const gpa = comp.gpa;
501488
502 try writer.writeByte(1); // version
503 try writer.writeByte(DW_EH_PE.pcrel | DW_EH_PE.sdata4);
504 try writer.writeByte(DW_EH_PE.udata4);
505 try writer.writeByte(DW_EH_PE.datarel | DW_EH_PE.sdata4);
489 try bw.writeByte(1); // version
490 try bw.writeByte(DW_EH_PE.pcrel | DW_EH_PE.sdata4);
491 try bw.writeByte(DW_EH_PE.udata4);
492 try bw.writeByte(DW_EH_PE.datarel | DW_EH_PE.sdata4);
506493
507494 const shdrs = elf_file.sections.items(.shdr);
508495 const eh_frame_shdr = shdrs[elf_file.section_indexes.eh_frame.?];
......@@ -513,7 +500,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
513500 const sym = zo.symbol(zo.eh_frame_index orelse break :existing_size 0);
514501 break :existing_size sym.atom(elf_file).?.size;
515502 };
516 try writer.writeInt(
503 try bw.writeInt(
517504 u32,
518505 @as(u32, @bitCast(@as(
519506 i32,
......@@ -521,7 +508,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
521508 ))),
522509 .little,
523510 );
524 try writer.writeInt(u32, num_fdes, .little);
511 try bw.writeInt(u32, num_fdes, .little);
525512
526513 const Entry = struct {
527514 init_addr: u32,
......@@ -561,7 +548,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void {
561548 }
562549
563550 std.mem.sort(Entry, entries.items, {}, Entry.lessThan);
564 try writer.writeAll(std.mem.sliceAsBytes(entries.items));
551 try bw.writeAll(std.mem.sliceAsBytes(entries.items));
565552}
566553
567554const eh_frame_hdr_header_size: usize = 12;
......@@ -607,11 +594,11 @@ const riscv = struct {
607594fn reportInvalidReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela) !void {
608595 const diags = &elf_file.base.comp.link_diags;
609596 var err = try diags.addErrorWithNotes(1);
610 try err.addMsg("invalid relocation type {} at offset 0x{x}", .{
597 try err.addMsg("invalid relocation type {f} at offset 0x{x}", .{
611598 relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch),
612599 rel.r_offset,
613600 });
614 err.addNote("in {}:.eh_frame", .{elf_file.file(rec.file_index).?.fmtPath()});
601 err.addNote("in {f}:.eh_frame", .{elf_file.file(rec.file_index).?.fmtPath()});
615602 return error.RelocFailure;
616603}
617604
src/link/Elf/file.zig+5-11
......@@ -14,19 +14,13 @@ pub const File = union(enum) {
1414 return .{ .data = file };
1515 }
1616
17 fn formatPath(
18 file: File,
19 comptime unused_fmt_string: []const u8,
20 options: std.fmt.FormatOptions,
21 writer: anytype,
22 ) !void {
17 fn formatPath(file: File, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
2318 _ = unused_fmt_string;
24 _ = options;
2519 switch (file) {
26 .zig_object => |zo| try writer.writeAll(zo.basename),
27 .linker_defined => try writer.writeAll("(linker defined)"),
28 .object => |x| try writer.print("{}", .{x.fmtPath()}),
29 .shared_object => |x| try writer.print("{}", .{@as(Path, x.path)}),
20 .zig_object => |zo| try bw.writeAll(zo.basename),
21 .linker_defined => try bw.writeAll("(linker defined)"),
22 .object => |x| try bw.print("{f}", .{x.fmtPath()}),
23 .shared_object => |x| try bw.print("{f}", .{x.path}),
3024 }
3125 }
3226
src/link/Elf/gc.zig+5-11
......@@ -111,7 +111,7 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {
111111 const target_sym = elf_file.symbol(ref) orelse continue;
112112 const target_atom = target_sym.atom(elf_file) orelse continue;
113113 target_atom.alive = true;
114 gc_track_live_log.debug("{}marking live atom({d})", .{ track_live_level, target_atom.atom_index });
114 gc_track_live_log.debug("{f}marking live atom({d})", .{ track_live_level, target_atom.atom_index });
115115 if (markAtom(target_atom)) markLive(target_atom, elf_file);
116116 }
117117 }
......@@ -128,7 +128,7 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {
128128 }
129129 const target_atom = target_sym.atom(elf_file) orelse continue;
130130 target_atom.alive = true;
131 gc_track_live_log.debug("{}marking live atom({d})", .{ track_live_level, target_atom.atom_index });
131 gc_track_live_log.debug("{f}marking live atom({d})", .{ track_live_level, target_atom.atom_index });
132132 if (markAtom(target_atom)) markLive(target_atom, elf_file);
133133 }
134134}
......@@ -170,7 +170,7 @@ pub fn dumpPrunedAtoms(elf_file: *Elf) !void {
170170 for (file.atoms()) |atom_index| {
171171 const atom = file.atom(atom_index) orelse continue;
172172 if (!atom.alive)
173 try stderr.print("link: removing unused section '{s}' in file '{}'\n", .{
173 try stderr.print("link: removing unused section '{s}' in file '{f}'\n", .{
174174 atom.name(elf_file),
175175 atom.file(elf_file).?.fmtPath(),
176176 });
......@@ -185,15 +185,9 @@ const Level = struct {
185185 self.value += 1;
186186 }
187187
188 pub fn format(
189 self: *const @This(),
190 comptime unused_fmt_string: []const u8,
191 options: std.fmt.FormatOptions,
192 writer: anytype,
193 ) !void {
188 pub fn format(self: *const @This(), bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
194189 _ = unused_fmt_string;
195 _ = options;
196 try writer.writeByteNTimes(' ', self.value);
190 try bw.splatByteAll(' ', self.value);
197191 }
198192};
199193
src/link/Elf/relocatable.zig+21-23
......@@ -31,7 +31,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
3131 try elf_file.allocateNonAllocSections();
3232
3333 if (build_options.enable_logging) {
34 state_log.debug("{}", .{elf_file.dumpState()});
34 state_log.debug("{f}", .{elf_file.dumpState()});
3535 }
3636
3737 try elf_file.writeMergeSections();
......@@ -96,36 +96,35 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
9696 };
9797
9898 if (build_options.enable_logging) {
99 state_log.debug("ar_symtab\n{}\n", .{ar_symtab.fmt(elf_file)});
100 state_log.debug("ar_strtab\n{}\n", .{ar_strtab});
99 state_log.debug("ar_symtab\n{f}\n", .{ar_symtab.fmt(elf_file)});
100 state_log.debug("ar_strtab\n{f}\n", .{ar_strtab});
101101 }
102102
103 var buffer = std.ArrayList(u8).init(gpa);
104 defer buffer.deinit();
105 try buffer.ensureTotalCapacityPrecise(total_size);
103 var bw: std.io.BufferedWriter = undefined;
104 bw.initFixed(try gpa.alloc(u8, total_size));
105 defer gpa.free(bw.buffer);
106106
107107 // Write magic
108 try buffer.writer().writeAll(elf.ARMAG);
108 try bw.writeAll(elf.ARMAG);
109109
110110 // Write symtab
111 try ar_symtab.write(.p64, elf_file, buffer.writer());
111 try ar_symtab.write(.p64, elf_file, &bw);
112112
113113 // Write strtab
114114 if (ar_strtab.size() > 0) {
115 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
116 try ar_strtab.write(buffer.writer());
115 if (!mem.isAligned(bw.count, 2)) try bw.writeByte(0);
116 try ar_strtab.write(&bw);
117117 }
118118
119119 // Write object files
120120 for (files.items) |index| {
121 if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0);
122 try elf_file.file(index).?.writeAr(elf_file, buffer.writer());
121 if (!mem.isAligned(bw.count, 2)) try bw.writeByte(0);
122 try elf_file.file(index).?.writeAr(elf_file, &bw);
123123 }
124124
125 assert(buffer.items.len == total_size);
126
125 assert(bw.end == bw.buffer.len);
127126 try elf_file.base.file.?.setEndPos(total_size);
128 try elf_file.base.file.?.pwriteAll(buffer.items, 0);
127 try elf_file.base.file.?.pwriteAll(bw.buffer, 0);
129128
130129 if (diags.hasErrors()) return error.LinkFailure;
131130}
......@@ -170,7 +169,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void {
170169 try elf_file.allocateNonAllocSections();
171170
172171 if (build_options.enable_logging) {
173 state_log.debug("{}", .{elf_file.dumpState()});
172 state_log.debug("{f}", .{elf_file.dumpState()});
174173 }
175174
176175 try writeAtoms(elf_file);
......@@ -407,17 +406,16 @@ fn writeSyntheticSections(elf_file: *Elf) !void {
407406 };
408407 const shdr = slice.items(.shdr)[shndx];
409408 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
410 var buffer: std.io.AllocatingWriter = undefined;
411 const bw = buffer.init(gpa);
412 defer buffer.deinit();
413 try buffer.ensureTotalCapacity(gpa, sh_size - existing_size);
414 try eh_frame.writeEhFrameRelocatable(elf_file, bw);
409 var bw: std.io.BufferedWriter = undefined;
410 bw.initFixed(try gpa.alloc(u8, sh_size - existing_size));
411 defer gpa.free(bw.buffer);
412 try eh_frame.writeEhFrameRelocatable(elf_file, &bw);
415413 log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{
416414 shdr.sh_offset + existing_size,
417415 shdr.sh_offset + sh_size,
418416 });
419 assert(buffer.getWritten().len == sh_size - existing_size);
420 try elf_file.base.file.?.pwriteAll(buffer.getWritten(), shdr.sh_offset + existing_size);
417 assert(bw.end == bw.buffer.len);
418 try elf_file.base.file.?.pwriteAll(bw.buffer, shdr.sh_offset + existing_size);
421419 }
422420 if (elf_file.section_indexes.eh_frame_rela) |shndx| {
423421 const shdr = slice.items(.shdr)[shndx];
src/link/Elf/relocation.zig+4-10
......@@ -148,19 +148,13 @@ pub fn fmtRelocType(r_type: u32, cpu_arch: std.Target.Cpu.Arch) std.fmt.Formatte
148148 } };
149149}
150150
151fn formatRelocType(
152 ctx: FormatRelocTypeCtx,
153 comptime unused_fmt_string: []const u8,
154 options: std.fmt.FormatOptions,
155 writer: anytype,
156) !void {
151fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
157152 _ = unused_fmt_string;
158 _ = options;
159153 const r_type = ctx.r_type;
160154 switch (ctx.cpu_arch) {
161 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
162 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
163 .riscv64 => try writer.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
155 .x86_64 => try bw.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
156 .aarch64 => try bw.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
157 .riscv64 => try bw.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
164158 else => unreachable,
165159 }
166160}
src/link/Elf/synthetic_sections.zig+111-131
......@@ -94,115 +94,115 @@ pub const DynamicSection = struct {
9494 return nentries * @sizeOf(elf.Elf64_Dyn);
9595 }
9696
97 pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void {
97 pub fn write(dt: DynamicSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
9898 const shdrs = elf_file.sections.items(.shdr);
9999
100100 // NEEDED
101101 for (dt.needed.items) |off| {
102 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off });
102 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off });
103103 }
104104
105105 if (dt.soname) |off| {
106 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SONAME, .d_val = off });
106 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SONAME, .d_val = off });
107107 }
108108
109109 // RUNPATH
110110 // TODO add option in Options to revert to old RPATH tag
111111 if (dt.rpath > 0) {
112 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RUNPATH, .d_val = dt.rpath });
112 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RUNPATH, .d_val = dt.rpath });
113113 }
114114
115115 // INIT
116116 if (elf_file.sectionByName(".init")) |shndx| {
117117 const addr = shdrs[shndx].sh_addr;
118 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr });
118 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr });
119119 }
120120
121121 // FINI
122122 if (elf_file.sectionByName(".fini")) |shndx| {
123123 const addr = shdrs[shndx].sh_addr;
124 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr });
124 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr });
125125 }
126126
127127 // INIT_ARRAY
128128 if (elf_file.sectionByName(".init_array")) |shndx| {
129129 const shdr = shdrs[shndx];
130 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr });
131 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size });
130 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr });
131 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size });
132132 }
133133
134134 // FINI_ARRAY
135135 if (elf_file.sectionByName(".fini_array")) |shndx| {
136136 const shdr = shdrs[shndx];
137 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr });
138 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size });
137 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr });
138 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size });
139139 }
140140
141141 // RELA
142142 if (elf_file.section_indexes.rela_dyn) |shndx| {
143143 const shdr = shdrs[shndx];
144 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr });
145 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size });
146 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize });
144 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr });
145 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size });
146 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize });
147147 }
148148
149149 // JMPREL
150150 if (elf_file.section_indexes.rela_plt) |shndx| {
151151 const shdr = shdrs[shndx];
152 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr });
153 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size });
154 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA });
152 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr });
153 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size });
154 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA });
155155 }
156156
157157 // PLTGOT
158158 if (elf_file.section_indexes.got_plt) |shndx| {
159159 const addr = shdrs[shndx].sh_addr;
160 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr });
160 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr });
161161 }
162162
163163 {
164164 assert(elf_file.section_indexes.hash != null);
165165 const addr = shdrs[elf_file.section_indexes.hash.?].sh_addr;
166 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr });
166 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr });
167167 }
168168
169169 if (elf_file.section_indexes.gnu_hash) |shndx| {
170170 const addr = shdrs[shndx].sh_addr;
171 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });
171 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });
172172 }
173173
174174 // TEXTREL
175175 if (elf_file.has_text_reloc) {
176 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_TEXTREL, .d_val = 0 });
176 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_TEXTREL, .d_val = 0 });
177177 }
178178
179179 // SYMTAB + SYMENT
180180 {
181181 assert(elf_file.section_indexes.dynsymtab != null);
182182 const shdr = shdrs[elf_file.section_indexes.dynsymtab.?];
183 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr });
184 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize });
183 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr });
184 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize });
185185 }
186186
187187 // STRTAB + STRSZ
188188 {
189189 assert(elf_file.section_indexes.dynstrtab != null);
190190 const shdr = shdrs[elf_file.section_indexes.dynstrtab.?];
191 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr });
192 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size });
191 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr });
192 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size });
193193 }
194194
195195 // VERSYM
196196 if (elf_file.section_indexes.versym) |shndx| {
197197 const addr = shdrs[shndx].sh_addr;
198 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr });
198 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr });
199199 }
200200
201201 // VERNEED + VERNEEDNUM
202202 if (elf_file.section_indexes.verneed) |shndx| {
203203 const addr = shdrs[shndx].sh_addr;
204 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr });
205 try writer.writeStruct(elf.Elf64_Dyn{
204 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr });
205 try bw.writeStruct(elf.Elf64_Dyn{
206206 .d_tag = elf.DT_VERNEEDNUM,
207207 .d_val = elf_file.verneed.verneed.items.len,
208208 });
......@@ -210,18 +210,18 @@ pub const DynamicSection = struct {
210210
211211 // FLAGS
212212 if (dt.getFlags(elf_file)) |flags| {
213 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FLAGS, .d_val = flags });
213 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FLAGS, .d_val = flags });
214214 }
215215 // FLAGS_1
216216 if (dt.getFlags1(elf_file)) |flags_1| {
217 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FLAGS_1, .d_val = flags_1 });
217 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FLAGS_1, .d_val = flags_1 });
218218 }
219219
220220 // DEBUG
221 if (!elf_file.isEffectivelyDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 });
221 if (!elf_file.isEffectivelyDynLib()) try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 });
222222
223223 // NULL
224 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 });
224 try bw.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 });
225225 }
226226};
227227
......@@ -360,7 +360,7 @@ pub const GotSection = struct {
360360 return s;
361361 }
362362
363 pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void {
363 pub fn write(got: GotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
364364 const comp = elf_file.base.comp;
365365 const is_dyn_lib = elf_file.isEffectivelyDynLib();
366366 const apply_relocs = true; // TODO add user option for this
......@@ -381,47 +381,47 @@ pub const GotSection = struct {
381381 }
382382 break :blk value;
383383 };
384 try writeInt(value, elf_file, writer);
384 try writeInt(value, elf_file, bw);
385385 },
386386 .tlsld => {
387 try writeInt(if (is_dyn_lib) @as(u64, 0) else 1, elf_file, writer);
388 try writeInt(0, elf_file, writer);
387 try writeInt(if (is_dyn_lib) @as(u64, 0) else 1, elf_file, bw);
388 try writeInt(0, elf_file, bw);
389389 },
390390 .tlsgd => {
391391 if (symbol.?.flags.import) {
392 try writeInt(0, elf_file, writer);
393 try writeInt(0, elf_file, writer);
392 try writeInt(0, elf_file, bw);
393 try writeInt(0, elf_file, bw);
394394 } else {
395 try writeInt(if (is_dyn_lib) @as(u64, 0) else 1, elf_file, writer);
395 try writeInt(if (is_dyn_lib) @as(u64, 0) else 1, elf_file, bw);
396396 const offset = symbol.?.address(.{}, elf_file) - elf_file.dtpAddress();
397 try writeInt(offset, elf_file, writer);
397 try writeInt(offset, elf_file, bw);
398398 }
399399 },
400400 .gottp => {
401401 if (symbol.?.flags.import) {
402 try writeInt(0, elf_file, writer);
402 try writeInt(0, elf_file, bw);
403403 } else if (is_dyn_lib) {
404404 const offset = if (apply_relocs)
405405 symbol.?.address(.{}, elf_file) - elf_file.tlsAddress()
406406 else
407407 0;
408 try writeInt(offset, elf_file, writer);
408 try writeInt(offset, elf_file, bw);
409409 } else {
410410 const offset = symbol.?.address(.{}, elf_file) - elf_file.tpAddress();
411 try writeInt(offset, elf_file, writer);
411 try writeInt(offset, elf_file, bw);
412412 }
413413 },
414414 .tlsdesc => {
415415 if (symbol.?.flags.import) {
416 try writeInt(0, elf_file, writer);
417 try writeInt(0, elf_file, writer);
416 try writeInt(0, elf_file, bw);
417 try writeInt(0, elf_file, bw);
418418 } else {
419 try writeInt(0, elf_file, writer);
419 try writeInt(0, elf_file, bw);
420420 const offset = if (apply_relocs)
421421 symbol.?.address(.{}, elf_file) - elf_file.tlsAddress()
422422 else
423423 0;
424 try writeInt(offset, elf_file, writer);
424 try writeInt(offset, elf_file, bw);
425425 }
426426 },
427427 }
......@@ -615,20 +615,14 @@ pub const GotSection = struct {
615615 return .{ .data = .{ .got = got, .elf_file = elf_file } };
616616 }
617617
618 pub fn format2(
619 ctx: FormatCtx,
620 comptime unused_fmt_string: []const u8,
621 options: std.fmt.FormatOptions,
622 writer: anytype,
623 ) !void {
624 _ = options;
618 pub fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
625619 _ = unused_fmt_string;
626620 const got = ctx.got;
627621 const elf_file = ctx.elf_file;
628 try writer.writeAll("GOT\n");
622 try bw.writeAll("GOT\n");
629623 for (got.entries.items) |entry| {
630624 const symbol = elf_file.symbol(entry.ref).?;
631 try writer.print(" {d}@0x{x} => {}@0x{x} ({s})\n", .{
625 try bw.print(" {d}@0x{x} => {f}@0x{x} ({s})\n", .{
632626 entry.cell_index,
633627 entry.address(elf_file),
634628 entry.ref,
......@@ -678,11 +672,11 @@ pub const PltSection = struct {
678672 };
679673 }
680674
681 pub fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
675 pub fn write(plt: PltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
682676 const cpu_arch = elf_file.getTarget().cpu.arch;
683677 switch (cpu_arch) {
684 .x86_64 => try x86_64.write(plt, elf_file, writer),
685 .aarch64 => try aarch64.write(plt, elf_file, writer),
678 .x86_64 => try x86_64.write(plt, elf_file, bw),
679 .aarch64 => try aarch64.write(plt, elf_file, bw),
686680 else => return error.UnsupportedCpuArch,
687681 }
688682 }
......@@ -703,7 +697,7 @@ pub const PltSection = struct {
703697 const r_sym: u64 = extra.dynamic;
704698 const r_type = relocation.encode(.jump_slot, cpu_arch);
705699
706 relocs_log.debug(" {s}: [{x} => {d}({s})] + 0", .{
700 relocs_log.debug(" {f}: [{x} => {d}({s})] + 0", .{
707701 relocation.fmtRelocType(r_type, cpu_arch),
708702 r_offset,
709703 r_sym,
......@@ -758,20 +752,14 @@ pub const PltSection = struct {
758752 return .{ .data = .{ .plt = plt, .elf_file = elf_file } };
759753 }
760754
761 pub fn format2(
762 ctx: FormatCtx,
763 comptime unused_fmt_string: []const u8,
764 options: std.fmt.FormatOptions,
765 writer: anytype,
766 ) !void {
767 _ = options;
755 pub fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
768756 _ = unused_fmt_string;
769757 const plt = ctx.plt;
770758 const elf_file = ctx.elf_file;
771 try writer.writeAll("PLT\n");
759 try bw.writeAll("PLT\n");
772760 for (plt.symbols.items, 0..) |ref, i| {
773761 const symbol = elf_file.symbol(ref).?;
774 try writer.print(" {d}@0x{x} => {}@0x{x} ({s})\n", .{
762 try bw.print(" {d}@0x{x} => {f}@0x{x} ({s})\n", .{
775763 i,
776764 symbol.pltAddress(elf_file),
777765 ref,
......@@ -782,7 +770,7 @@ pub const PltSection = struct {
782770 }
783771
784772 const x86_64 = struct {
785 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
773 fn write(plt: PltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
786774 const shdrs = elf_file.sections.items(.shdr);
787775 const plt_addr = shdrs[elf_file.section_indexes.plt.?].sh_addr;
788776 const got_plt_addr = shdrs[elf_file.section_indexes.got_plt.?].sh_addr;
......@@ -796,8 +784,8 @@ pub const PltSection = struct {
796784 mem.writeInt(i32, preamble[8..][0..4], @as(i32, @intCast(disp)), .little);
797785 disp = @as(i64, @intCast(got_plt_addr + 16)) - @as(i64, @intCast(plt_addr + 14)) - 4;
798786 mem.writeInt(i32, preamble[14..][0..4], @as(i32, @intCast(disp)), .little);
799 try writer.writeAll(&preamble);
800 try writer.writeByteNTimes(0xcc, preambleSize(.x86_64) - preamble.len);
787 try bw.writeAll(&preamble);
788 try bw.splatByteAll(0xcc, preambleSize(.x86_64) - preamble.len);
801789
802790 for (plt.symbols.items, 0..) |ref, i| {
803791 const sym = elf_file.symbol(ref).?;
......@@ -811,13 +799,13 @@ pub const PltSection = struct {
811799 };
812800 mem.writeInt(i32, entry[6..][0..4], @as(i32, @intCast(i)), .little);
813801 mem.writeInt(i32, entry[12..][0..4], @as(i32, @intCast(disp)), .little);
814 try writer.writeAll(&entry);
802 try bw.writeAll(&entry);
815803 }
816804 }
817805 };
818806
819807 const aarch64 = struct {
820 fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void {
808 fn write(plt: PltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
821809 {
822810 const shdrs = elf_file.sections.items(.shdr);
823811 const plt_addr: i64 = @intCast(shdrs[elf_file.section_indexes.plt.?].sh_addr);
......@@ -845,7 +833,7 @@ pub const PltSection = struct {
845833 };
846834 comptime assert(preamble.len == 8);
847835 for (preamble) |inst| {
848 try writer.writeInt(u32, inst.toU32(), .little);
836 try bw.writeInt(u32, inst.toU32(), .little);
849837 }
850838 }
851839
......@@ -864,7 +852,7 @@ pub const PltSection = struct {
864852 };
865853 comptime assert(insts.len == 4);
866854 for (insts) |inst| {
867 try writer.writeInt(u32, inst.toU32(), .little);
855 try bw.writeInt(u32, inst.toU32(), .little);
868856 }
869857 }
870858 }
......@@ -883,22 +871,22 @@ pub const GotPltSection = struct {
883871 return preamble_size + elf_file.plt.symbols.items.len * 8;
884872 }
885873
886 pub fn write(got_plt: GotPltSection, elf_file: *Elf, writer: anytype) !void {
874 pub fn write(got_plt: GotPltSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
887875 _ = got_plt;
888876 {
889877 // [0]: _DYNAMIC
890878 const symbol = elf_file.linkerDefinedPtr().?.dynamicSymbol(elf_file).?;
891 try writer.writeInt(u64, @intCast(symbol.address(.{}, elf_file)), .little);
879 try bw.writeInt(u64, @intCast(symbol.address(.{}, elf_file)), .little);
892880 }
893881 // [1]: 0x0
894882 // [2]: 0x0
895 try writer.writeInt(u64, 0x0, .little);
896 try writer.writeInt(u64, 0x0, .little);
883 try bw.writeInt(u64, 0x0, .little);
884 try bw.writeInt(u64, 0x0, .little);
897885 if (elf_file.section_indexes.plt) |shndx| {
898886 const plt_addr = elf_file.sections.items(.shdr)[shndx].sh_addr;
899887 for (0..elf_file.plt.symbols.items.len) |_| {
900888 // [N]: .plt
901 try writer.writeInt(u64, plt_addr, .little);
889 try bw.writeInt(u64, plt_addr, .little);
902890 }
903891 }
904892 }
......@@ -934,11 +922,11 @@ pub const PltGotSection = struct {
934922 };
935923 }
936924
937 pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
925 pub fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
938926 const cpu_arch = elf_file.getTarget().cpu.arch;
939927 switch (cpu_arch) {
940 .x86_64 => try x86_64.write(plt_got, elf_file, writer),
941 .aarch64 => try aarch64.write(plt_got, elf_file, writer),
928 .x86_64 => try x86_64.write(plt_got, elf_file, bw),
929 .aarch64 => try aarch64.write(plt_got, elf_file, bw),
942930 else => return error.UnsupportedCpuArch,
943931 }
944932 }
......@@ -970,7 +958,7 @@ pub const PltGotSection = struct {
970958 }
971959
972960 const x86_64 = struct {
973 pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
961 pub fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
974962 for (plt_got.symbols.items) |ref| {
975963 const sym = elf_file.symbol(ref).?;
976964 const target_addr = sym.gotAddress(elf_file);
......@@ -982,13 +970,13 @@ pub const PltGotSection = struct {
982970 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
983971 };
984972 mem.writeInt(i32, entry[6..][0..4], @as(i32, @intCast(disp)), .little);
985 try writer.writeAll(&entry);
973 try bw.writeAll(&entry);
986974 }
987975 }
988976 };
989977
990978 const aarch64 = struct {
991 fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
979 fn write(plt_got: PltGotSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
992980 for (plt_got.symbols.items) |ref| {
993981 const sym = elf_file.symbol(ref).?;
994982 const target_addr = sym.gotAddress(elf_file);
......@@ -1003,7 +991,7 @@ pub const PltGotSection = struct {
1003991 };
1004992 comptime assert(insts.len == 4);
1005993 for (insts) |inst| {
1006 try writer.writeInt(u32, inst.toU32(), .little);
994 try bw.writeInt(u32, inst.toU32(), .little);
1007995 }
1008996 }
1009997 }
......@@ -1167,23 +1155,23 @@ pub const DynsymSection = struct {
11671155 return @as(u32, @intCast(dynsym.entries.items.len + 1));
11681156 }
11691157
1170 pub fn write(dynsym: DynsymSection, elf_file: *Elf, writer: anytype) !void {
1171 try writer.writeStruct(Elf.null_sym);
1158 pub fn write(dynsym: DynsymSection, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
1159 try bw.writeStruct(Elf.null_sym);
11721160 for (dynsym.entries.items) |entry| {
11731161 const sym = elf_file.symbol(entry.ref).?;
11741162 var out_sym: elf.Elf64_Sym = Elf.null_sym;
11751163 sym.setOutputSym(elf_file, &out_sym);
11761164 out_sym.st_name = entry.off;
1177 try writer.writeStruct(out_sym);
1165 try bw.writeStruct(out_sym);
11781166 }
11791167 }
11801168};
11811169
11821170pub const HashSection = struct {
1183 buffer: std.ArrayListUnmanaged(u8) = .empty,
1171 buffer: []u32 = &.{},
11841172
1185 pub fn deinit(hs: *HashSection, allocator: Allocator) void {
1186 hs.buffer.deinit(allocator);
1173 pub fn deinit(hs: *HashSection, gpa: Allocator) void {
1174 gpa.free(hs.buffer);
11871175 }
11881176
11891177 pub fn generate(hs: *HashSection, elf_file: *Elf) !void {
......@@ -1193,30 +1181,25 @@ pub const HashSection = struct {
11931181 const gpa = comp.gpa;
11941182 const nsyms = elf_file.dynsym.count();
11951183
1196 var buckets = try gpa.alloc(u32, nsyms);
1197 defer gpa.free(buckets);
1198 @memset(buckets, 0);
1184 assert(hs.buffer.len == 0);
1185 hs.buffer = try gpa.alloc(u32, 2 * (1 + nsyms));
11991186
1200 var chains = try gpa.alloc(u32, nsyms);
1201 defer gpa.free(chains);
1187 @memset(hs.buffer[0..2], std.mem.nativeToLittle(u32, @intCast(nsyms)));
1188 const buckets = hs.buffer[2..][0..nsyms];
1189 @memset(buckets, 0);
1190 const chains = hs.buffer[2 + nsyms ..][0..nsyms];
12021191 @memset(chains, 0);
12031192
12041193 for (elf_file.dynsym.entries.items, 1..) |entry, i| {
12051194 const name = elf_file.getDynString(entry.off);
1206 const hash = hasher(name) % buckets.len;
1207 chains[@as(u32, @intCast(i))] = buckets[hash];
1208 buckets[hash] = @as(u32, @intCast(i));
1195 const hash = hasher(name) % nsyms;
1196 chains[i] = buckets[hash];
1197 buckets[hash] = std.mem.nativeToLittle(u32, @intCast(i));
12091198 }
1210
1211 try hs.buffer.ensureTotalCapacityPrecise(gpa, (2 + nsyms * 2) * 4);
1212 hs.buffer.writer(gpa).writeInt(u32, @as(u32, @intCast(nsyms)), .little) catch unreachable;
1213 hs.buffer.writer(gpa).writeInt(u32, @as(u32, @intCast(nsyms)), .little) catch unreachable;
1214 hs.buffer.writer(gpa).writeAll(mem.sliceAsBytes(buckets)) catch unreachable;
1215 hs.buffer.writer(gpa).writeAll(mem.sliceAsBytes(chains)) catch unreachable;
12161199 }
12171200
12181201 pub inline fn size(hs: HashSection) usize {
1219 return hs.buffer.items.len;
1202 return @sizeOf(u32) * hs.buffer.len;
12201203 }
12211204
12221205 pub fn hasher(name: [:0]const u8) u32 {
......@@ -1266,17 +1249,14 @@ pub const GnuHashSection = struct {
12661249 return header_size + hash.num_bloom * 8 + hash.num_buckets * 4 + hash.num_exports * 4;
12671250 }
12681251
1269 pub fn write(hash: GnuHashSection, elf_file: *Elf, writer: anytype) !void {
1252 pub fn write(hash: GnuHashSection, elf_file: *Elf, br: *std.io.BufferedWriter) !void {
12701253 const exports = getExports(elf_file);
12711254 const export_off = elf_file.dynsym.count() - hash.num_exports;
12721255
1273 var counting = std.io.countingWriter(writer);
1274 const cwriter = counting.writer();
1275
1276 try cwriter.writeInt(u32, hash.num_buckets, .little);
1277 try cwriter.writeInt(u32, export_off, .little);
1278 try cwriter.writeInt(u32, hash.num_bloom, .little);
1279 try cwriter.writeInt(u32, bloom_shift, .little);
1256 try br.writeInt(u32, hash.num_buckets, .little);
1257 try br.writeInt(u32, export_off, .little);
1258 try br.writeInt(u32, hash.num_bloom, .little);
1259 try br.writeInt(u32, bloom_shift, .little);
12801260
12811261 const comp = elf_file.base.comp;
12821262 const gpa = comp.gpa;
......@@ -1300,7 +1280,7 @@ pub const GnuHashSection = struct {
13001280 bloom[idx] |= @as(u64, 1) << @as(u6, @intCast((h >> bloom_shift) % 64));
13011281 }
13021282
1303 try cwriter.writeAll(mem.sliceAsBytes(bloom));
1283 try br.writeAll(mem.sliceAsBytes(bloom));
13041284
13051285 // Fill in the hash bucket indices
13061286 const buckets = try gpa.alloc(u32, hash.num_buckets);
......@@ -1313,7 +1293,7 @@ pub const GnuHashSection = struct {
13131293 }
13141294 }
13151295
1316 try cwriter.writeAll(mem.sliceAsBytes(buckets));
1296 try br.writeAll(mem.sliceAsBytes(buckets));
13171297
13181298 // Finally, write the hash table
13191299 const table = try gpa.alloc(u32, hash.num_exports);
......@@ -1329,9 +1309,9 @@ pub const GnuHashSection = struct {
13291309 }
13301310 }
13311311
1332 try cwriter.writeAll(mem.sliceAsBytes(table));
1312 try br.writeAll(mem.sliceAsBytes(table));
13331313
1334 assert(counting.bytes_written == hash.size());
1314 assert(br.count == hash.size());
13351315 }
13361316
13371317 pub fn hasher(name: [:0]const u8) u32 {
......@@ -1478,9 +1458,9 @@ pub const VerneedSection = struct {
14781458 return vern.verneed.items.len * @sizeOf(elf.Elf64_Verneed) + vern.vernaux.items.len * @sizeOf(elf.Vernaux);
14791459 }
14801460
1481 pub fn write(vern: VerneedSection, writer: anytype) !void {
1482 try writer.writeAll(mem.sliceAsBytes(vern.verneed.items));
1483 try writer.writeAll(mem.sliceAsBytes(vern.vernaux.items));
1461 pub fn write(vern: VerneedSection, bw: *std.io.BufferedWriter) anyerror!void {
1462 try bw.writeAll(mem.sliceAsBytes(vern.verneed.items));
1463 try bw.writeAll(mem.sliceAsBytes(vern.vernaux.items));
14841464 }
14851465};
14861466
......@@ -1506,11 +1486,11 @@ pub const GroupSection = struct {
15061486 return (members.len + 1) * @sizeOf(u32);
15071487 }
15081488
1509 pub fn write(cgs: GroupSection, elf_file: *Elf, writer: anytype) !void {
1489 pub fn write(cgs: GroupSection, elf_file: *Elf, bw: *std.io.BufferedWriter) !void {
15101490 const cg = cgs.group(elf_file);
15111491 const object = cg.file(elf_file).object;
15121492 const members = cg.members(elf_file);
1513 try writer.writeInt(u32, if (cg.is_comdat) elf.GRP_COMDAT else 0, .little);
1493 try bw.writeInt(u32, if (cg.is_comdat) elf.GRP_COMDAT else 0, .little);
15141494 for (members) |shndx| {
15151495 const shdr = object.shdrs.items[shndx];
15161496 switch (shdr.sh_type) {
......@@ -1522,26 +1502,26 @@ pub const GroupSection = struct {
15221502 atom.output_section_index == rela_shdr.sh_info)
15231503 break rela_shndx;
15241504 } else unreachable;
1525 try writer.writeInt(u32, @intCast(rela_shndx), .little);
1505 try bw.writeInt(u32, @intCast(rela_shndx), .little);
15261506 },
15271507 else => {
15281508 const atom_index = object.atoms_indexes.items[shndx];
15291509 const atom = object.atom(atom_index).?;
1530 try writer.writeInt(u32, atom.output_section_index, .little);
1510 try bw.writeInt(u32, atom.output_section_index, .little);
15311511 },
15321512 }
15331513 }
15341514 }
15351515};
15361516
1537fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
1517fn writeInt(value: anytype, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void {
15381518 const entry_size = elf_file.archPtrWidthBytes();
15391519 const target = elf_file.getTarget();
15401520 const endian = target.cpu.arch.endian();
15411521 switch (entry_size) {
1542 2 => try writer.writeInt(u16, @intCast(value), endian),
1543 4 => try writer.writeInt(u32, @intCast(value), endian),
1544 8 => try writer.writeInt(u64, @intCast(value), endian),
1522 2 => try bw.writeInt(u16, @intCast(value), endian),
1523 4 => try bw.writeInt(u32, @intCast(value), endian),
1524 8 => try bw.writeInt(u64, @intCast(value), endian),
15451525 else => unreachable,
15461526 }
15471527}
src/link/LdScript.zig+1-1
......@@ -41,7 +41,7 @@ pub fn parse(
4141 try line_col.append(gpa, .{ .line = line, .column = column });
4242 switch (tok.id) {
4343 .invalid => {
44 return diags.failParse(path, "invalid token in LD script: '{s}' ({d}:{d})", .{
44 return diags.failParse(path, "invalid token in LD script: '{f}' ({d}:{d})", .{
4545 std.fmt.fmtSliceEscapeLower(tok.get(data)), line, column,
4646 });
4747 },
src/link/MachO.zig+148-178
......@@ -41,9 +41,9 @@ data_in_code_cmd: macho.linkedit_data_command = .{ .cmd = .DATA_IN_CODE },
4141uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 },
4242codesig_cmd: macho.linkedit_data_command = .{ .cmd = .CODE_SIGNATURE },
4343
44pagezero_seg_index: ?u8 = null,
45text_seg_index: ?u8 = null,
46linkedit_seg_index: ?u8 = null,
44pagezero_seg_index: ?u4 = null,
45text_seg_index: ?u4 = null,
46linkedit_seg_index: ?u4 = null,
4747text_sect_index: ?u8 = null,
4848data_sect_index: ?u8 = null,
4949got_sect_index: ?u8 = null,
......@@ -76,10 +76,10 @@ unwind_info: UnwindInfo = .{},
7676data_in_code: DataInCode = .{},
7777
7878/// Tracked loadable segments during incremental linking.
79zig_text_seg_index: ?u8 = null,
80zig_const_seg_index: ?u8 = null,
81zig_data_seg_index: ?u8 = null,
82zig_bss_seg_index: ?u8 = null,
79zig_text_seg_index: ?u4 = null,
80zig_const_seg_index: ?u4 = null,
81zig_data_seg_index: ?u4 = null,
82zig_bss_seg_index: ?u4 = null,
8383
8484/// Tracked section headers with incremental updates to Zig object.
8585zig_text_sect_index: ?u8 = null,
......@@ -543,7 +543,7 @@ pub fn flush(
543543 self.allocateSyntheticSymbols();
544544
545545 if (build_options.enable_logging) {
546 state_log.debug("{}", .{self.dumpState()});
546 state_log.debug("{f}", .{self.dumpState()});
547547 }
548548
549549 // Beyond this point, everything has been allocated a virtual address and we can resolve
......@@ -591,6 +591,7 @@ pub fn flush(
591591 error.NoSpaceLeft => unreachable,
592592 error.OutOfMemory => return error.OutOfMemory,
593593 error.LinkFailure => return error.LinkFailure,
594 else => unreachable,
594595 };
595596 try self.writeHeader(ncmds, sizeofcmds);
596597 self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()) catch |err| switch (err) {
......@@ -677,12 +678,12 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
677678
678679 try argv.append("-platform_version");
679680 try argv.append(@tagName(self.platform.os_tag));
680 try argv.append(try std.fmt.allocPrint(arena, "{}", .{self.platform.version}));
681 try argv.append(try std.fmt.allocPrint(arena, "{f}", .{self.platform.version}));
681682
682683 if (self.sdk_version) |ver| {
683684 try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor }));
684685 } else {
685 try argv.append(try std.fmt.allocPrint(arena, "{}", .{self.platform.version}));
686 try argv.append(try std.fmt.allocPrint(arena, "{f}", .{self.platform.version}));
686687 }
687688
688689 if (comp.sysroot) |syslibroot| {
......@@ -863,7 +864,7 @@ pub fn classifyInputFile(self: *MachO, input: link.Input) !void {
863864
864865 const path, const file = input.pathAndFile().?;
865866 // TODO don't classify now, it's too late. The input file has already been classified
866 log.debug("classifying input file {}", .{path});
867 log.debug("classifying input file {f}", .{path});
867868
868869 const fh = try self.addFileHandle(file);
869870 var buffer: [Archive.SARMAG]u8 = undefined;
......@@ -1074,7 +1075,7 @@ fn accessLibPath(
10741075
10751076 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
10761077 test_path.clearRetainingCapacity();
1077 try test_path.writer().print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });
1078 try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });
10781079 try checked_paths.append(try arena.dupe(u8, test_path.items));
10791080 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
10801081 error.FileNotFound => continue,
......@@ -1097,7 +1098,7 @@ fn accessFrameworkPath(
10971098
10981099 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
10991100 test_path.clearRetainingCapacity();
1100 try test_path.writer().print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{
1101 try test_path.print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{
11011102 search_dir,
11021103 name,
11031104 name,
......@@ -1178,9 +1179,9 @@ fn parseDependentDylibs(self: *MachO) !void {
11781179 for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
11791180 test_path.clearRetainingCapacity();
11801181 if (self.base.comp.sysroot) |root| {
1181 try test_path.writer().print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext });
1182 try test_path.print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext });
11821183 } else {
1183 try test_path.writer().print("{s}{s}", .{ path, ext });
1184 try test_path.print("{s}{s}", .{ path, ext });
11841185 }
11851186 try checked_paths.append(try arena.dupe(u8, test_path.items));
11861187 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
......@@ -1591,7 +1592,7 @@ fn reportUndefs(self: *MachO) !void {
15911592 const ref = refs.items[inote];
15921593 const file = self.getFile(ref.file).?;
15931594 const atom = ref.getAtom(self).?;
1594 err.addNote("referenced by {}:{s}", .{ file.fmtPath(), atom.getName(self) });
1595 err.addNote("referenced by {f}:{s}", .{ file.fmtPath(), atom.getName(self) });
15951596 }
15961597
15971598 if (refs.items.len > max_notes) {
......@@ -2131,7 +2132,7 @@ fn initSegments(self: *MachO) !void {
21312132
21322133 mem.sort(Entry, entries.items, self, Entry.lessThan);
21332134
2134 const backlinks = try gpa.alloc(u8, entries.items.len);
2135 const backlinks = try gpa.alloc(u4, entries.items.len);
21352136 defer gpa.free(backlinks);
21362137 for (entries.items, 0..) |entry, i| {
21372138 backlinks[entry.index] = @intCast(i);
......@@ -2145,7 +2146,7 @@ fn initSegments(self: *MachO) !void {
21452146 self.segments.appendAssumeCapacity(segments[sorted.index]);
21462147 }
21472148
2148 for (&[_]*?u8{
2149 for (&[_]*?u4{
21492150 &self.pagezero_seg_index,
21502151 &self.text_seg_index,
21512152 &self.linkedit_seg_index,
......@@ -2163,7 +2164,7 @@ fn initSegments(self: *MachO) !void {
21632164 for (slice.items(.header), slice.items(.segment_id)) |header, *seg_id| {
21642165 const segname = header.segName();
21652166 const segment_id = self.getSegmentByName(segname) orelse blk: {
2166 const segment_id = @as(u8, @intCast(self.segments.items.len));
2167 const segment_id: u4 = @intCast(self.segments.items.len);
21672168 const protection = getSegmentProt(segname);
21682169 try self.segments.append(gpa, .{
21692170 .cmdsize = @sizeOf(macho.segment_command_64),
......@@ -2526,10 +2527,9 @@ fn writeThunkWorker(self: *MachO, thunk: Thunk) void {
25262527
25272528 const doWork = struct {
25282529 fn doWork(th: Thunk, buffer: []u8, macho_file: *MachO) !void {
2529 const off = try macho_file.cast(usize, th.value);
2530 const size = th.size();
2531 var stream = std.io.fixedBufferStream(buffer[off..][0..size]);
2532 try th.write(macho_file, stream.writer());
2530 var bw: std.io.BufferedWriter = undefined;
2531 bw.initFixed(buffer[try macho_file.cast(usize, th.value)..][0..th.size()]);
2532 try th.write(macho_file, &bw);
25332533 }
25342534 }.doWork;
25352535 const out = self.sections.items(.out)[thunk.out_n_sect].items;
......@@ -2556,15 +2556,16 @@ fn writeSyntheticSectionWorker(self: *MachO, sect_id: u8, out: []u8) void {
25562556
25572557 const doWork = struct {
25582558 fn doWork(macho_file: *MachO, tag: Tag, buffer: []u8) !void {
2559 var stream = std.io.fixedBufferStream(buffer);
2559 var bw: std.io.BufferedWriter = undefined;
2560 bw.initFixed(buffer);
25602561 switch (tag) {
25612562 .eh_frame => eh_frame.write(macho_file, buffer),
2562 .unwind_info => try macho_file.unwind_info.write(macho_file, buffer),
2563 .got => try macho_file.got.write(macho_file, stream.writer()),
2564 .stubs => try macho_file.stubs.write(macho_file, stream.writer()),
2565 .la_symbol_ptr => try macho_file.la_symbol_ptr.write(macho_file, stream.writer()),
2566 .tlv_ptr => try macho_file.tlv_ptr.write(macho_file, stream.writer()),
2567 .objc_stubs => try macho_file.objc_stubs.write(macho_file, stream.writer()),
2563 .unwind_info => try macho_file.unwind_info.write(macho_file, &bw),
2564 .got => try macho_file.got.write(macho_file, &bw),
2565 .stubs => try macho_file.stubs.write(macho_file, &bw),
2566 .la_symbol_ptr => try macho_file.la_symbol_ptr.write(macho_file, &bw),
2567 .tlv_ptr => try macho_file.tlv_ptr.write(macho_file, &bw),
2568 .objc_stubs => try macho_file.objc_stubs.write(macho_file, &bw),
25682569 }
25692570 }
25702571 }.doWork;
......@@ -2605,8 +2606,9 @@ fn updateLazyBindSizeWorker(self: *MachO) void {
26052606 try macho_file.lazy_bind_section.updateSize(macho_file);
26062607 const sect_id = macho_file.stubs_helper_sect_index.?;
26072608 const out = &macho_file.sections.items(.out)[sect_id];
2608 var stream = std.io.fixedBufferStream(out.items);
2609 try macho_file.stubs_helper.write(macho_file, stream.writer());
2609 var bw: std.io.BufferedWriter = undefined;
2610 bw.initFixed(out.items);
2611 try macho_file.stubs_helper.write(macho_file, &bw);
26102612 }
26112613 }.doWork;
26122614 doWork(self) catch |err|
......@@ -2665,23 +2667,21 @@ fn writeDyldInfo(self: *MachO) !void {
26652667 needed_size += cmd.lazy_bind_size;
26662668 needed_size += cmd.export_size;
26672669
2668 const buffer = try gpa.alloc(u8, needed_size);
2669 defer gpa.free(buffer);
2670 @memset(buffer, 0);
2670 var bw: std.io.BufferedWriter = undefined;
2671 bw.initFixed(try gpa.alloc(u8, needed_size));
2672 defer gpa.free(bw.buffer);
2673 @memset(bw.buffer, 0);
26712674
2672 var stream = std.io.fixedBufferStream(buffer);
2673 const writer = stream.writer();
2674
2675 try self.rebase_section.write(writer);
2676 try stream.seekTo(cmd.bind_off - base_off);
2677 try self.bind_section.write(writer);
2678 try stream.seekTo(cmd.weak_bind_off - base_off);
2679 try self.weak_bind_section.write(writer);
2680 try stream.seekTo(cmd.lazy_bind_off - base_off);
2681 try self.lazy_bind_section.write(writer);
2682 try stream.seekTo(cmd.export_off - base_off);
2683 try self.export_trie.write(writer);
2684 try self.pwriteAll(buffer, cmd.rebase_off);
2675 try self.rebase_section.write(&bw);
2676 bw.end = cmd.bind_off - base_off;
2677 try self.bind_section.write(&bw);
2678 bw.end = cmd.weak_bind_off - base_off;
2679 try self.weak_bind_section.write(&bw);
2680 bw.end = cmd.lazy_bind_off - base_off;
2681 try self.lazy_bind_section.write(&bw);
2682 bw.end = cmd.export_off - base_off;
2683 try self.export_trie.write(&bw);
2684 try self.pwriteAll(bw.buffer, cmd.rebase_off);
26852685}
26862686
26872687pub fn writeDataInCode(self: *MachO) !void {
......@@ -2689,22 +2689,30 @@ pub fn writeDataInCode(self: *MachO) !void {
26892689 defer tracy.end();
26902690 const gpa = self.base.comp.gpa;
26912691 const cmd = self.data_in_code_cmd;
2692 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.data_in_code.size());
2693 defer buffer.deinit();
2694 try self.data_in_code.write(self, buffer.writer());
2695 try self.pwriteAll(buffer.items, cmd.dataoff);
2692
2693 var bw: std.io.BufferedWriter = undefined;
2694 bw.initFixed(try gpa.alloc(u8, self.data_in_code.size()));
2695 defer gpa.free(bw.buffer);
2696
2697 try self.data_in_code.write(self, &bw);
2698 assert(bw.end == bw.buffer.len);
2699 try self.pwriteAll(bw.buffer, cmd.dataoff);
26962700}
26972701
26982702fn writeIndsymtab(self: *MachO) !void {
26992703 const tracy = trace(@src());
27002704 defer tracy.end();
2705
27012706 const gpa = self.base.comp.gpa;
27022707 const cmd = self.dysymtab_cmd;
2703 const needed_size = cmd.nindirectsyms * @sizeOf(u32);
2704 var buffer = try std.ArrayList(u8).initCapacity(gpa, needed_size);
2705 defer buffer.deinit();
2706 try self.indsymtab.write(self, buffer.writer());
2707 try self.pwriteAll(buffer.items, cmd.indirectsymoff);
2708
2709 var bw: std.io.BufferedWriter = undefined;
2710 bw.initFixed(try gpa.alloc(u8, @sizeOf(u32) * cmd.nindirectsyms));
2711 defer gpa.free(bw.buffer);
2712
2713 try self.indsymtab.write(self, &bw);
2714 assert(bw.end == bw.buffer.len);
2715 try self.pwriteAll(bw.buffer, cmd.indirectsymoff);
27082716}
27092717
27102718pub fn writeSymtabToFile(self: *MachO) !void {
......@@ -2814,15 +2822,13 @@ fn calcSymtabSize(self: *MachO) !void {
28142822 }
28152823}
28162824
2817fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
2825fn writeLoadCommands(self: *MachO) anyerror!struct { usize, usize, u64 } {
28182826 const comp = self.base.comp;
28192827 const gpa = comp.gpa;
2820 const needed_size = try load_commands.calcLoadCommandsSize(self, false);
2821 const buffer = try gpa.alloc(u8, needed_size);
2822 defer gpa.free(buffer);
28232828
2824 var stream = std.io.fixedBufferStream(buffer);
2825 const writer = stream.writer();
2829 var bw: std.io.BufferedWriter = undefined;
2830 bw.initFixed(try gpa.alloc(u8, try load_commands.calcLoadCommandsSize(self, false)));
2831 defer gpa.free(bw.buffer);
28262832
28272833 var ncmds: usize = 0;
28282834
......@@ -2831,26 +2837,26 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
28312837 const slice = self.sections.slice();
28322838 var sect_id: usize = 0;
28332839 for (self.segments.items) |seg| {
2834 try writer.writeStruct(seg);
2840 try bw.writeStruct(seg);
28352841 for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| {
2836 try writer.writeStruct(header);
2842 try bw.writeStruct(header);
28372843 }
28382844 sect_id += seg.nsects;
28392845 }
28402846 ncmds += self.segments.items.len;
28412847 }
28422848
2843 try writer.writeStruct(self.dyld_info_cmd);
2849 try bw.writeStruct(self.dyld_info_cmd);
28442850 ncmds += 1;
2845 try writer.writeStruct(self.function_starts_cmd);
2851 try bw.writeStruct(self.function_starts_cmd);
28462852 ncmds += 1;
2847 try writer.writeStruct(self.data_in_code_cmd);
2853 try bw.writeStruct(self.data_in_code_cmd);
28482854 ncmds += 1;
2849 try writer.writeStruct(self.symtab_cmd);
2855 try bw.writeStruct(self.symtab_cmd);
28502856 ncmds += 1;
2851 try writer.writeStruct(self.dysymtab_cmd);
2857 try bw.writeStruct(self.dysymtab_cmd);
28522858 ncmds += 1;
2853 try load_commands.writeDylinkerLC(writer);
2859 try load_commands.writeDylinkerLC(&bw);
28542860 ncmds += 1;
28552861
28562862 if (self.getInternalObject()) |obj| {
......@@ -2861,7 +2867,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
28612867 0
28622868 else
28632869 @as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr));
2864 try writer.writeStruct(macho.entry_point_command{
2870 try bw.writeStruct(macho.entry_point_command{
28652871 .entryoff = entryoff,
28662872 .stacksize = self.base.stack_size,
28672873 });
......@@ -2870,35 +2876,35 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
28702876 }
28712877
28722878 if (self.base.isDynLib()) {
2873 try load_commands.writeDylibIdLC(self, writer);
2879 try load_commands.writeDylibIdLC(self, &bw);
28742880 ncmds += 1;
28752881 }
28762882
28772883 for (self.rpath_list) |rpath| {
2878 try load_commands.writeRpathLC(rpath, writer);
2884 try load_commands.writeRpathLC(&bw, rpath);
28792885 ncmds += 1;
28802886 }
28812887 if (comp.config.any_sanitize_thread) {
28822888 const path = try comp.tsan_lib.?.full_object_path.toString(gpa);
28832889 defer gpa.free(path);
28842890 const rpath = std.fs.path.dirname(path) orelse ".";
2885 try load_commands.writeRpathLC(rpath, writer);
2891 try load_commands.writeRpathLC(&bw, rpath);
28862892 ncmds += 1;
28872893 }
28882894
2889 try writer.writeStruct(macho.source_version_command{ .version = 0 });
2895 try bw.writeStruct(macho.source_version_command{ .version = 0 });
28902896 ncmds += 1;
28912897
28922898 if (self.platform.isBuildVersionCompatible()) {
2893 try load_commands.writeBuildVersionLC(self.platform, self.sdk_version, writer);
2899 try load_commands.writeBuildVersionLC(&bw, self.platform, self.sdk_version);
28942900 ncmds += 1;
28952901 } else {
2896 try load_commands.writeVersionMinLC(self.platform, self.sdk_version, writer);
2902 try load_commands.writeVersionMinLC(&bw, self.platform, self.sdk_version);
28972903 ncmds += 1;
28982904 }
28992905
2900 const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + stream.pos;
2901 try writer.writeStruct(self.uuid_cmd);
2906 const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + bw.count;
2907 try bw.writeStruct(self.uuid_cmd);
29022908 ncmds += 1;
29032909
29042910 for (self.dylibs.items) |index| {
......@@ -2916,20 +2922,19 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
29162922 .timestamp = dylib_id.timestamp,
29172923 .current_version = dylib_id.current_version,
29182924 .compatibility_version = dylib_id.compatibility_version,
2919 }, writer);
2925 }, &bw);
29202926 ncmds += 1;
29212927 }
29222928
29232929 if (self.requiresCodeSig()) {
2924 try writer.writeStruct(self.codesig_cmd);
2930 try bw.writeStruct(self.codesig_cmd);
29252931 ncmds += 1;
29262932 }
29272933
2928 assert(stream.pos == needed_size);
2934 assert(bw.end == bw.buffer.len);
2935 try self.pwriteAll(bw.buffer, @sizeOf(macho.mach_header_64));
29292936
2930 try self.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
2931
2932 return .{ ncmds, buffer.len, uuid_cmd_offset };
2937 return .{ ncmds, bw.end, uuid_cmd_offset };
29332938}
29342939
29352940fn writeHeader(self: *MachO, ncmds: usize, sizeofcmds: usize) !void {
......@@ -3012,27 +3017,28 @@ pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {
30123017}
30133018
30143019pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void {
3020 const gpa = self.base.comp.gpa;
30153021 const seg = self.getTextSegment();
30163022 const offset = self.codesig_cmd.dataoff;
30173023
3018 var buffer = std.ArrayList(u8).init(self.base.comp.gpa);
3019 defer buffer.deinit();
3020 try buffer.ensureTotalCapacityPrecise(code_sig.size());
3024 var bw: std.io.BufferedWriter = undefined;
3025 bw.initFixed(try gpa.alloc(u8, code_sig.size()));
3026 defer gpa.free(bw.buffer);
30213027 try code_sig.writeAdhocSignature(self, .{
30223028 .file = self.base.file.?,
30233029 .exec_seg_base = seg.fileoff,
30243030 .exec_seg_limit = seg.filesize,
30253031 .file_size = offset,
30263032 .dylib = self.base.isDynLib(),
3027 }, buffer.writer());
3028 assert(buffer.items.len == code_sig.size());
3033 }, &bw);
30293034
30303035 log.debug("writing code signature from 0x{x} to 0x{x}", .{
30313036 offset,
3032 offset + buffer.items.len,
3037 offset + bw.end,
30333038 });
30343039
3035 try self.pwriteAll(buffer.items, offset);
3040 assert(bw.end == bw.buffer.len);
3041 try self.pwriteAll(bw.buffer, offset);
30363042}
30373043
30383044pub fn updateFunc(
......@@ -3341,7 +3347,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
33413347 }
33423348
33433349 const appendSect = struct {
3344 fn appendSect(macho_file: *MachO, sect_id: u8, seg_id: u8) void {
3350 fn appendSect(macho_file: *MachO, sect_id: u8, seg_id: u4) void {
33453351 const sect = &macho_file.sections.items(.header)[sect_id];
33463352 const seg = macho_file.segments.items[seg_id];
33473353 sect.addr = seg.vmaddr;
......@@ -3600,7 +3606,7 @@ inline fn requiresThunks(self: MachO) bool {
36003606}
36013607
36023608pub fn isZigSegment(self: MachO, seg_id: u8) bool {
3603 inline for (&[_]?u8{
3609 inline for (&[_]?u4{
36043610 self.zig_text_seg_index,
36053611 self.zig_const_seg_index,
36063612 self.zig_data_seg_index,
......@@ -3648,9 +3654,9 @@ pub fn addSegment(self: *MachO, name: []const u8, opts: struct {
36483654 fileoff: u64 = 0,
36493655 filesize: u64 = 0,
36503656 prot: macho.vm_prot_t = macho.PROT.NONE,
3651}) error{OutOfMemory}!u8 {
3657}) error{OutOfMemory}!u4 {
36523658 const gpa = self.base.comp.gpa;
3653 const index = @as(u8, @intCast(self.segments.items.len));
3659 const index: u4 = @intCast(self.segments.items.len);
36543660 try self.segments.append(gpa, .{
36553661 .segname = makeStaticString(name),
36563662 .vmaddr = opts.vmaddr,
......@@ -3700,9 +3706,9 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 {
37003706 return buf;
37013707}
37023708
3703pub fn getSegmentByName(self: MachO, segname: []const u8) ?u8 {
3709pub fn getSegmentByName(self: MachO, segname: []const u8) ?u4 {
37043710 for (self.segments.items, 0..) |seg, i| {
3705 if (mem.eql(u8, segname, seg.segName())) return @as(u8, @intCast(i));
3711 if (mem.eql(u8, segname, seg.segName())) return @intCast(i);
37063712 } else return null;
37073713}
37083714
......@@ -3791,7 +3797,7 @@ pub fn reportParseError2(
37913797 const diags = &self.base.comp.link_diags;
37923798 var err = try diags.addErrorWithNotes(1);
37933799 try err.addMsg(format, args);
3794 err.addNote("while parsing {}", .{self.getFile(file_index).?.fmtPath()});
3800 err.addNote("while parsing {f}", .{self.getFile(file_index).?.fmtPath()});
37953801}
37963802
37973803fn reportMissingDependencyError(
......@@ -3806,7 +3812,7 @@ fn reportMissingDependencyError(
38063812 var err = try diags.addErrorWithNotes(2 + checked_paths.len);
38073813 try err.addMsg(format, args);
38083814 err.addNote("while resolving {s}", .{path});
3809 err.addNote("a dependency of {}", .{self.getFile(parent).?.fmtPath()});
3815 err.addNote("a dependency of {f}", .{self.getFile(parent).?.fmtPath()});
38103816 for (checked_paths) |p| {
38113817 err.addNote("tried {s}", .{p});
38123818 }
......@@ -3823,7 +3829,7 @@ fn reportDependencyError(
38233829 var err = try diags.addErrorWithNotes(2);
38243830 try err.addMsg(format, args);
38253831 err.addNote("while parsing {s}", .{path});
3826 err.addNote("a dependency of {}", .{self.getFile(parent).?.fmtPath()});
3832 err.addNote("a dependency of {f}", .{self.getFile(parent).?.fmtPath()});
38273833}
38283834
38293835fn reportDuplicates(self: *MachO) error{ HasDuplicates, OutOfMemory }!void {
......@@ -3853,12 +3859,12 @@ fn reportDuplicates(self: *MachO) error{ HasDuplicates, OutOfMemory }!void {
38533859
38543860 var err = try diags.addErrorWithNotes(nnotes + 1);
38553861 try err.addMsg("duplicate symbol definition: {s}", .{sym.getName(self)});
3856 err.addNote("defined by {}", .{sym.getFile(self).?.fmtPath()});
3862 err.addNote("defined by {f}", .{sym.getFile(self).?.fmtPath()});
38573863
38583864 var inote: usize = 0;
38593865 while (inote < @min(notes.items.len, max_notes)) : (inote += 1) {
38603866 const file = self.getFile(notes.items[inote]).?;
3861 err.addNote("defined by {}", .{file.fmtPath()});
3867 err.addNote("defined by {f}", .{file.fmtPath()});
38623868 }
38633869
38643870 if (notes.items.len > max_notes) {
......@@ -3904,31 +3910,25 @@ pub fn dumpState(self: *MachO) std.fmt.Formatter(fmtDumpState) {
39043910 return .{ .data = self };
39053911}
39063912
3907fn fmtDumpState(
3908 self: *MachO,
3909 comptime unused_fmt_string: []const u8,
3910 options: std.fmt.FormatOptions,
3911 writer: anytype,
3912) !void {
3913 _ = options;
3913fn fmtDumpState(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
39143914 _ = unused_fmt_string;
39153915 if (self.getZigObject()) |zo| {
3916 try writer.print("zig_object({d}) : {s}\n", .{ zo.index, zo.basename });
3917 try writer.print("{}{}\n", .{
3916 try bw.print("zig_object({d}) : {s}\n", .{ zo.index, zo.basename });
3917 try bw.print("{f}{f}\n", .{
39183918 zo.fmtAtoms(self),
39193919 zo.fmtSymtab(self),
39203920 });
39213921 }
39223922 for (self.objects.items) |index| {
39233923 const object = self.getFile(index).?.object;
3924 try writer.print("object({d}) : {} : has_debug({})", .{
3924 try bw.print("object({d}) : {f} : has_debug({})", .{
39253925 index,
39263926 object.fmtPath(),
39273927 object.hasDebugInfo(),
39283928 });
3929 if (!object.alive) try writer.writeAll(" : ([*])");
3930 try writer.writeByte('\n');
3931 try writer.print("{}{}{}{}{}\n", .{
3929 if (!object.alive) try bw.writeAll(" : ([*])");
3930 try bw.writeByte('\n');
3931 try bw.print("{f}{f}{f}{f}{f}\n", .{
39323932 object.fmtAtoms(self),
39333933 object.fmtCies(self),
39343934 object.fmtFdes(self),
......@@ -3938,48 +3938,42 @@ fn fmtDumpState(
39383938 }
39393939 for (self.dylibs.items) |index| {
39403940 const dylib = self.getFile(index).?.dylib;
3941 try writer.print("dylib({d}) : {} : needed({}) : weak({})", .{
3941 try bw.print("dylib({d}) : {f} : needed({}) : weak({})", .{
39423942 index,
39433943 @as(Path, dylib.path),
39443944 dylib.needed,
39453945 dylib.weak,
39463946 });
3947 if (!dylib.isAlive(self)) try writer.writeAll(" : ([*])");
3948 try writer.writeByte('\n');
3949 try writer.print("{}\n", .{dylib.fmtSymtab(self)});
3947 if (!dylib.isAlive(self)) try bw.writeAll(" : ([*])");
3948 try bw.writeByte('\n');
3949 try bw.print("{f}\n", .{dylib.fmtSymtab(self)});
39503950 }
39513951 if (self.getInternalObject()) |internal| {
3952 try writer.print("internal({d}) : internal\n", .{internal.index});
3953 try writer.print("{}{}\n", .{ internal.fmtAtoms(self), internal.fmtSymtab(self) });
3952 try bw.print("internal({d}) : internal\n", .{internal.index});
3953 try bw.print("{f}{f}\n", .{ internal.fmtAtoms(self), internal.fmtSymtab(self) });
39543954 }
3955 try writer.writeAll("thunks\n");
3955 try bw.writeAll("thunks\n");
39563956 for (self.thunks.items, 0..) |thunk, index| {
3957 try writer.print("thunk({d}) : {}\n", .{ index, thunk.fmt(self) });
3957 try bw.print("thunk({d}) : {f}\n", .{ index, thunk.fmt(self) });
39583958 }
3959 try writer.print("stubs\n{}\n", .{self.stubs.fmt(self)});
3960 try writer.print("objc_stubs\n{}\n", .{self.objc_stubs.fmt(self)});
3961 try writer.print("got\n{}\n", .{self.got.fmt(self)});
3962 try writer.print("tlv_ptr\n{}\n", .{self.tlv_ptr.fmt(self)});
3963 try writer.writeByte('\n');
3964 try writer.print("sections\n{}\n", .{self.fmtSections()});
3965 try writer.print("segments\n{}\n", .{self.fmtSegments()});
3959 try bw.print("stubs\n{f}\n", .{self.stubs.fmt(self)});
3960 try bw.print("objc_stubs\n{f}\n", .{self.objc_stubs.fmt(self)});
3961 try bw.print("got\n{f}\n", .{self.got.fmt(self)});
3962 try bw.print("tlv_ptr\n{f}\n", .{self.tlv_ptr.fmt(self)});
3963 try bw.writeByte('\n');
3964 try bw.print("sections\n{f}\n", .{self.fmtSections()});
3965 try bw.print("segments\n{f}\n", .{self.fmtSegments()});
39663966}
39673967
39683968fn fmtSections(self: *MachO) std.fmt.Formatter(formatSections) {
39693969 return .{ .data = self };
39703970}
39713971
3972fn formatSections(
3973 self: *MachO,
3974 comptime unused_fmt_string: []const u8,
3975 options: std.fmt.FormatOptions,
3976 writer: anytype,
3977) !void {
3978 _ = options;
3972fn formatSections(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
39793973 _ = unused_fmt_string;
39803974 const slice = self.sections.slice();
39813975 for (slice.items(.header), slice.items(.segment_id), 0..) |header, seg_id, i| {
3982 try writer.print(
3976 try bw.print(
39833977 "sect({d}) : seg({d}) : {s},{s} : @{x} ({x}) : align({x}) : size({x}) : relocs({x};{d})\n",
39843978 .{
39853979 i, seg_id, header.segName(), header.sectName(), header.addr, header.offset,
......@@ -3993,16 +3987,10 @@ fn fmtSegments(self: *MachO) std.fmt.Formatter(formatSegments) {
39933987 return .{ .data = self };
39943988}
39953989
3996fn formatSegments(
3997 self: *MachO,
3998 comptime unused_fmt_string: []const u8,
3999 options: std.fmt.FormatOptions,
4000 writer: anytype,
4001) !void {
4002 _ = options;
3990fn formatSegments(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
40033991 _ = unused_fmt_string;
40043992 for (self.segments.items, 0..) |seg, i| {
4005 try writer.print("seg({d}) : {s} : @{x}-{x} ({x}-{x})\n", .{
3993 try bw.print("seg({d}) : {s} : @{x}-{x} ({x}-{x})\n", .{
40063994 i, seg.segName(), seg.vmaddr, seg.vmaddr + seg.vmsize,
40073995 seg.fileoff, seg.fileoff + seg.filesize,
40083996 });
......@@ -4013,13 +4001,7 @@ pub fn fmtSectType(tt: u8) std.fmt.Formatter(formatSectType) {
40134001 return .{ .data = tt };
40144002}
40154003
4016fn formatSectType(
4017 tt: u8,
4018 comptime unused_fmt_string: []const u8,
4019 options: std.fmt.FormatOptions,
4020 writer: anytype,
4021) !void {
4022 _ = options;
4004fn formatSectType(tt: u8, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
40234005 _ = unused_fmt_string;
40244006 const name = switch (tt) {
40254007 macho.S_REGULAR => "REGULAR",
......@@ -4044,9 +4026,9 @@ fn formatSectType(
40444026 macho.S_THREAD_LOCAL_VARIABLE_POINTERS => "THREAD_LOCAL_VARIABLE_POINTERS",
40454027 macho.S_THREAD_LOCAL_INIT_FUNCTION_POINTERS => "THREAD_LOCAL_INIT_FUNCTION_POINTERS",
40464028 macho.S_INIT_FUNC_OFFSETS => "INIT_FUNC_OFFSETS",
4047 else => |x| return writer.print("UNKNOWN({x})", .{x}),
4029 else => |x| return bw.print("UNKNOWN({x})", .{x}),
40484030 };
4049 try writer.print("{s}", .{name});
4031 try bw.print("{s}", .{name});
40504032}
40514033
40524034const is_hot_update_compatible = switch (builtin.target.os.tag) {
......@@ -4058,7 +4040,7 @@ const default_entry_symbol_name = "_main";
40584040
40594041const Section = struct {
40604042 header: macho.section_64,
4061 segment_id: u8,
4043 segment_id: u4,
40624044 atoms: std.ArrayListUnmanaged(Ref) = .empty,
40634045 free_list: std.ArrayListUnmanaged(Atom.Index) = .empty,
40644046 last_atom_index: Atom.Index = 0,
......@@ -4288,17 +4270,11 @@ pub const Platform = struct {
42884270 cpu_arch: std.Target.Cpu.Arch,
42894271 };
42904272
4291 pub fn formatTarget(
4292 ctx: FmtCtx,
4293 comptime unused_fmt_string: []const u8,
4294 options: std.fmt.FormatOptions,
4295 writer: anytype,
4296 ) !void {
4273 pub fn formatTarget(ctx: FmtCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
42974274 _ = unused_fmt_string;
4298 _ = options;
4299 try writer.print("{s}-{s}", .{ @tagName(ctx.cpu_arch), @tagName(ctx.platform.os_tag) });
4275 try bw.print("{s}-{s}", .{ @tagName(ctx.cpu_arch), @tagName(ctx.platform.os_tag) });
43004276 if (ctx.platform.abi != .none) {
4301 try writer.print("-{s}", .{@tagName(ctx.platform.abi)});
4277 try bw.print("-{s}", .{@tagName(ctx.platform.abi)});
43024278 }
43034279 }
43044280
......@@ -4390,7 +4366,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi
43904366// The file/property is also available with vendored libc.
43914367fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 {
43924368 const sdk_path = try fs.path.join(arena, &.{ dir, "SDKSettings.json" });
4393 const contents = try fs.cwd().readFileAlloc(arena, sdk_path, std.math.maxInt(u16));
4369 const contents = try fs.cwd().readFileAlloc(sdk_path, arena, .limited(std.math.maxInt(u16)));
43944370 const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{});
43954371 if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string;
43964372 return error.SdkVersionFailure;
......@@ -4406,7 +4382,7 @@ fn parseSdkVersion(raw: []const u8) ?std.SemanticVersion {
44064382 };
44074383
44084384 const parseNext = struct {
4409 fn parseNext(it: anytype) ?u16 {
4385 fn parseNext(it: *std.mem.SplitIterator(u8, .any)) ?u16 {
44104386 const nn = it.next() orelse return null;
44114387 return std.fmt.parseInt(u16, nn, 10) catch null;
44124388 }
......@@ -4507,15 +4483,9 @@ pub const Ref = struct {
45074483 };
45084484 }
45094485
4510 pub fn format(
4511 ref: Ref,
4512 comptime unused_fmt_string: []const u8,
4513 options: std.fmt.FormatOptions,
4514 writer: anytype,
4515 ) !void {
4486 pub fn format(ref: Ref, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
45164487 _ = unused_fmt_string;
4517 _ = options;
4518 try writer.print("%{d} in file({d})", .{ ref.index, ref.file });
4488 try bw.print("%{d} in file({d})", .{ ref.index, ref.file });
45194489 }
45204490};
45214491
......@@ -5315,7 +5285,7 @@ fn createThunks(macho_file: *MachO, sect_id: u8) !void {
53155285 try scanThunkRelocs(thunk_index, gpa, atoms[start..i], macho_file);
53165286 thunk.value = advanceSection(header, thunk.size(), .@"4");
53175287
5318 log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) });
5288 log.debug("thunk({d}) : {f}", .{ thunk_index, thunk.fmt(macho_file) });
53195289 }
53205290}
53215291
src/link/MachO/Archive.zig+25-58
......@@ -29,7 +29,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File
2929 pos += @sizeOf(ar_hdr);
3030
3131 if (!mem.eql(u8, &hdr.ar_fmag, ARFMAG)) {
32 return diags.failParse(path, "invalid header delimiter: expected '{s}', found '{s}'", .{
32 return diags.failParse(path, "invalid header delimiter: expected '{f}', found '{f}'", .{
3333 std.fmt.fmtSliceEscapeLower(ARFMAG), std.fmt.fmtSliceEscapeLower(&hdr.ar_fmag),
3434 });
3535 }
......@@ -71,53 +71,29 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File
7171 .mtime = hdr.date() catch 0,
7272 };
7373
74 log.debug("extracting object '{}' from archive '{}'", .{ object.path, path });
74 log.debug("extracting object '{f}' from archive '{f}'", .{ object.path, path });
7575
7676 try self.objects.append(gpa, object);
7777 }
7878}
7979
8080pub fn writeHeader(
81 bw: *std.io.BufferedWriter,
8182 object_name: []const u8,
8283 object_size: usize,
8384 format: Format,
84 writer: anytype,
85) !void {
86 var hdr: ar_hdr = .{
87 .ar_name = undefined,
88 .ar_date = undefined,
89 .ar_uid = undefined,
90 .ar_gid = undefined,
91 .ar_mode = undefined,
92 .ar_size = undefined,
93 .ar_fmag = undefined,
94 };
95 @memset(mem.asBytes(&hdr), 0x20);
96 inline for (@typeInfo(ar_hdr).@"struct".fields) |field| {
97 var stream = std.io.fixedBufferStream(&@field(hdr, field.name));
98 stream.writer().print("0", .{}) catch unreachable;
99 }
85) anyerror!void {
86 var hdr: ar_hdr = undefined;
87 @memset(mem.asBytes(&hdr), ' ');
88 inline for (@typeInfo(ar_hdr).@"struct".fields) |field| @field(hdr, field.name)[0] = '0';
10089 @memcpy(&hdr.ar_fmag, ARFMAG);
101
10290 const object_name_len = mem.alignForward(usize, object_name.len + 1, ptrWidth(format));
91 _ = std.fmt.bufPrint(&hdr.ar_name, "#1/{d}", .{object_name_len}) catch unreachable;
10392 const total_object_size = object_size + object_name_len;
104
105 {
106 var stream = std.io.fixedBufferStream(&hdr.ar_name);
107 stream.writer().print("#1/{d}", .{object_name_len}) catch unreachable;
108 }
109 {
110 var stream = std.io.fixedBufferStream(&hdr.ar_size);
111 stream.writer().print("{d}", .{total_object_size}) catch unreachable;
112 }
113
114 try writer.writeAll(mem.asBytes(&hdr));
115 try writer.print("{s}\x00", .{object_name});
116
117 const padding = object_name_len - object_name.len - 1;
118 if (padding > 0) {
119 try writer.writeByteNTimes(0, padding);
120 }
93 _ = std.fmt.bufPrint(&hdr.ar_size, "{d}", .{total_object_size}) catch unreachable;
94 try bw.writeStruct(hdr);
95 try bw.writeAll(object_name);
96 try bw.splatByteAll(0, object_name_len - object_name.len);
12197}
12298
12399// Archive files start with the ARMAG identifying string. Then follows a
......@@ -201,12 +177,12 @@ pub const ArSymtab = struct {
201177 return ptr_width + ar.entries.items.len * 2 * ptr_width + ptr_width + mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width);
202178 }
203179
204 pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: anytype) !void {
180 pub fn write(ar: ArSymtab, bw: *std.io.BufferedWriter, format: Format, macho_file: *MachO) anyerror!void {
205181 const ptr_width = ptrWidth(format);
206182 // Header
207 try writeHeader(SYMDEF, ar.size(format), format, writer);
183 try writeHeader(bw, SYMDEF, ar.size(format), format);
208184 // Symtab size
209 try writeInt(format, ar.entries.items.len * 2 * ptr_width, writer);
185 try writeInt(bw, format, ar.entries.items.len * 2 * ptr_width);
210186 // Symtab entries
211187 for (ar.entries.items) |entry| {
212188 const file_off = switch (macho_file.getFile(entry.file).?) {
......@@ -215,19 +191,16 @@ pub const ArSymtab = struct {
215191 else => unreachable,
216192 };
217193 // Name offset
218 try writeInt(format, entry.off, writer);
194 try writeInt(bw, format, entry.off);
219195 // File offset
220 try writeInt(format, file_off, writer);
196 try writeInt(bw, format, file_off);
221197 }
222198 // Strtab size
223199 const strtab_size = mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width);
224 const padding = strtab_size - ar.strtab.buffer.items.len;
225 try writeInt(format, strtab_size, writer);
200 try writeInt(bw, format, strtab_size);
226201 // Strtab
227 try writer.writeAll(ar.strtab.buffer.items);
228 if (padding > 0) {
229 try writer.writeByteNTimes(0, padding);
230 }
202 try bw.writeAll(ar.strtab.buffer.items);
203 try bw.splatByteAll(0, strtab_size - ar.strtab.buffer.items.len);
231204 }
232205
233206 const FormatContext = struct {
......@@ -239,20 +212,14 @@ pub const ArSymtab = struct {
239212 return .{ .data = .{ .ar = ar, .macho_file = macho_file } };
240213 }
241214
242 fn format2(
243 ctx: FormatContext,
244 comptime unused_fmt_string: []const u8,
245 options: std.fmt.FormatOptions,
246 writer: anytype,
247 ) !void {
215 fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
248216 _ = unused_fmt_string;
249 _ = options;
250217 const ar = ctx.ar;
251218 const macho_file = ctx.macho_file;
252219 for (ar.entries.items, 0..) |entry, i| {
253220 const name = ar.strtab.getAssumeExists(entry.off);
254221 const file = macho_file.getFile(entry.file).?;
255 try writer.print(" {d}: {s} in file({d})({})\n", .{ i, name, entry.file, file.fmtPath() });
222 try bw.print(" {d}: {s} in file({d})({f})\n", .{ i, name, entry.file, file.fmtPath() });
256223 }
257224 }
258225
......@@ -282,10 +249,10 @@ pub fn ptrWidth(format: Format) usize {
282249 };
283250}
284251
285pub fn writeInt(format: Format, value: u64, writer: anytype) !void {
252pub fn writeInt(bw: *std.io.BufferedWriter, format: Format, value: u64) anyerror!void {
286253 switch (format) {
287 .p32 => try writer.writeInt(u32, std.math.cast(u32, value) orelse return error.Overflow, .little),
288 .p64 => try writer.writeInt(u64, value, .little),
254 .p32 => try bw.writeInt(u32, std.math.cast(u32, value) orelse return error.Overflow, .little),
255 .p64 => try bw.writeInt(u64, value, .little),
289256 }
290257}
291258
src/link/MachO/Atom.zig+59-67
......@@ -580,8 +580,10 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
580580
581581 relocs_log.debug("{x}: {s}", .{ self.value, name });
582582
583 var bw: std.io.BufferedWriter = undefined;
584 bw.initFixed(buffer);
585
583586 var has_error = false;
584 var stream = std.io.fixedBufferStream(buffer);
585587 var i: usize = 0;
586588 while (i < relocs.len) : (i += 1) {
587589 const rel = relocs[i];
......@@ -592,30 +594,28 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
592594 if (rel.getTargetSymbol(self, macho_file).getFile(macho_file) == null) continue;
593595 }
594596
595 try stream.seekTo(rel_offset);
596 self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| {
597 switch (err) {
598 error.RelaxFail => {
599 const target = switch (rel.tag) {
600 .@"extern" => rel.getTargetSymbol(self, macho_file).getName(macho_file),
601 .local => rel.getTargetAtom(self, macho_file).getName(macho_file),
602 };
603 try macho_file.reportParseError2(
604 file.getIndex(),
605 "{s}: 0x{x}: 0x{x}: failed to relax relocation: type {}, target {s}",
606 .{
607 name,
608 self.getAddress(macho_file),
609 rel.offset,
610 rel.fmtPretty(macho_file.getTarget().cpu.arch),
611 target,
612 },
613 );
614 has_error = true;
615 },
616 error.RelaxFailUnexpectedInstruction => has_error = true,
617 else => |e| return e,
618 }
597 bw.end = std.math.cast(usize, rel_offset) orelse return error.Overflow;
598 self.resolveRelocInner(rel, subtractor, buffer, macho_file, &bw) catch |err| switch (@as(ResolveError, @errorCast(err))) {
599 error.RelaxFail => {
600 const target = switch (rel.tag) {
601 .@"extern" => rel.getTargetSymbol(self, macho_file).getName(macho_file),
602 .local => rel.getTargetAtom(self, macho_file).getName(macho_file),
603 };
604 try macho_file.reportParseError2(
605 file.getIndex(),
606 "{s}: 0x{x}: 0x{x}: failed to relax relocation: type {f}, target {s}",
607 .{
608 name,
609 self.getAddress(macho_file),
610 rel.offset,
611 rel.fmtPretty(macho_file.getTarget().cpu.arch),
612 target,
613 },
614 );
615 has_error = true;
616 },
617 error.RelaxFailUnexpectedInstruction => has_error = true,
618 else => |e| return e,
619619 };
620620 }
621621
......@@ -638,8 +638,8 @@ fn resolveRelocInner(
638638 subtractor: ?Relocation,
639639 code: []u8,
640640 macho_file: *MachO,
641 writer: anytype,
642) ResolveError!void {
641 bw: *std.io.BufferedWriter,
642) anyerror!void {
643643 const t = &macho_file.base.comp.root_mod.resolved_target.result;
644644 const cpu_arch = t.cpu.arch;
645645 const rel_offset = math.cast(usize, rel.offset - self.off) orelse return error.Overflow;
......@@ -653,7 +653,7 @@ fn resolveRelocInner(
653653 const divExact = struct {
654654 fn divExact(atom: Atom, r: Relocation, num: u12, den: u12, ctx: *MachO) !u12 {
655655 return math.divExact(u12, num, den) catch {
656 try ctx.reportParseError2(atom.getFile(ctx).getIndex(), "{s}: unexpected remainder when resolving {s} at offset 0x{x}", .{
656 try ctx.reportParseError2(atom.getFile(ctx).getIndex(), "{s}: unexpected remainder when resolving {f} at offset 0x{x}", .{
657657 atom.getName(ctx),
658658 r.fmtPretty(ctx.getTarget().cpu.arch),
659659 r.offset,
......@@ -664,14 +664,14 @@ fn resolveRelocInner(
664664 }.divExact;
665665
666666 switch (rel.tag) {
667 .local => relocs_log.debug(" {x}<+{d}>: {}: [=> {x}] atom({d})", .{
667 .local => relocs_log.debug(" {x}<+{d}>: {f}: [=> {x}] atom({d})", .{
668668 P,
669669 rel_offset,
670670 rel.fmtPretty(cpu_arch),
671671 S + A - SUB,
672672 rel.getTargetAtom(self, macho_file).atom_index,
673673 }),
674 .@"extern" => relocs_log.debug(" {x}<+{d}>: {}: [=> {x}] G({x}) ({s})", .{
674 .@"extern" => relocs_log.debug(" {x}<+{d}>: {f}: [=> {x}] G({x}) ({s})", .{
675675 P,
676676 rel_offset,
677677 rel.fmtPretty(cpu_arch),
......@@ -690,14 +690,14 @@ fn resolveRelocInner(
690690 if (rel.tag == .@"extern") {
691691 const sym = rel.getTargetSymbol(self, macho_file);
692692 if (sym.isTlvInit(macho_file)) {
693 try writer.writeInt(u64, @intCast(S - TLS), .little);
693 try bw.writeInt(u64, @intCast(S - TLS), .little);
694694 return;
695695 }
696696 if (sym.flags.import) return;
697697 }
698 try writer.writeInt(u64, @bitCast(S + A - SUB), .little);
698 try bw.writeInt(u64, @bitCast(S + A - SUB), .little);
699699 } else if (rel.meta.length == 2) {
700 try writer.writeInt(u32, @bitCast(@as(i32, @truncate(S + A - SUB))), .little);
700 try bw.writeInt(u32, @bitCast(@as(i32, @truncate(S + A - SUB))), .little);
701701 } else unreachable;
702702 },
703703
......@@ -705,7 +705,7 @@ fn resolveRelocInner(
705705 assert(rel.tag == .@"extern");
706706 assert(rel.meta.length == 2);
707707 assert(rel.meta.pcrel);
708 try writer.writeInt(i32, @intCast(G + A - P), .little);
708 try bw.writeInt(i32, @intCast(G + A - P), .little);
709709 },
710710
711711 .branch => {
......@@ -714,7 +714,7 @@ fn resolveRelocInner(
714714 assert(rel.tag == .@"extern");
715715
716716 switch (cpu_arch) {
717 .x86_64 => try writer.writeInt(i32, @intCast(S + A - P), .little),
717 .x86_64 => try bw.writeInt(i32, @intCast(S + A - P), .little),
718718 .aarch64 => {
719719 const disp: i28 = math.cast(i28, S + A - P) orelse blk: {
720720 const thunk = self.getThunk(macho_file);
......@@ -732,10 +732,10 @@ fn resolveRelocInner(
732732 assert(rel.meta.length == 2);
733733 assert(rel.meta.pcrel);
734734 if (rel.getTargetSymbol(self, macho_file).getSectionFlags().has_got) {
735 try writer.writeInt(i32, @intCast(G + A - P), .little);
735 try bw.writeInt(i32, @intCast(G + A - P), .little);
736736 } else {
737737 try x86_64.relaxGotLoad(self, code[rel_offset - 3 ..], rel, macho_file);
738 try writer.writeInt(i32, @intCast(S + A - P), .little);
738 try bw.writeInt(i32, @intCast(S + A - P), .little);
739739 }
740740 },
741741
......@@ -746,17 +746,17 @@ fn resolveRelocInner(
746746 const sym = rel.getTargetSymbol(self, macho_file);
747747 if (sym.getSectionFlags().tlv_ptr) {
748748 const S_: i64 = @intCast(sym.getTlvPtrAddress(macho_file));
749 try writer.writeInt(i32, @intCast(S_ + A - P), .little);
749 try bw.writeInt(i32, @intCast(S_ + A - P), .little);
750750 } else {
751751 try x86_64.relaxTlv(code[rel_offset - 3 ..], t);
752 try writer.writeInt(i32, @intCast(S + A - P), .little);
752 try bw.writeInt(i32, @intCast(S + A - P), .little);
753753 }
754754 },
755755
756756 .signed, .signed1, .signed2, .signed4 => {
757757 assert(rel.meta.length == 2);
758758 assert(rel.meta.pcrel);
759 try writer.writeInt(i32, @intCast(S + A - P), .little);
759 try bw.writeInt(i32, @intCast(S + A - P), .little);
760760 },
761761
762762 .page,
......@@ -808,7 +808,7 @@ fn resolveRelocInner(
808808 2 => try divExact(self, rel, @truncate(target), 4, macho_file),
809809 3 => try divExact(self, rel, @truncate(target), 8, macho_file),
810810 };
811 try writer.writeInt(u32, inst.toU32(), .little);
811 try bw.writeInt(u32, inst.toU32(), .little);
812812 }
813813 },
814814
......@@ -886,7 +886,7 @@ fn resolveRelocInner(
886886 .sf = @as(u1, @truncate(reg_info.size)),
887887 },
888888 };
889 try writer.writeInt(u32, inst.toU32(), .little);
889 try bw.writeInt(u32, inst.toU32(), .little);
890890 },
891891 }
892892}
......@@ -900,19 +900,19 @@ const x86_64 = struct {
900900 switch (old_inst.encoding.mnemonic) {
901901 .mov => {
902902 const inst = Instruction.new(old_inst.prefix, .lea, &old_inst.ops, t) catch return error.RelaxFail;
903 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
903 relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding });
904904 encode(&.{inst}, code) catch return error.RelaxFail;
905905 },
906906 else => |x| {
907907 var err = try diags.addErrorWithNotes(2);
908 try err.addMsg("{s}: 0x{x}: 0x{x}: failed to relax relocation of type {}", .{
908 try err.addMsg("{s}: 0x{x}: 0x{x}: failed to relax relocation of type {f}", .{
909909 self.getName(macho_file),
910910 self.getAddress(macho_file),
911911 rel.offset,
912912 rel.fmtPretty(.x86_64),
913913 });
914914 err.addNote("expected .mov instruction but found .{s}", .{@tagName(x)});
915 err.addNote("while parsing {}", .{self.getFile(macho_file).fmtPath()});
915 err.addNote("while parsing {f}", .{self.getFile(macho_file).fmtPath()});
916916 return error.RelaxFailUnexpectedInstruction;
917917 },
918918 }
......@@ -924,7 +924,7 @@ const x86_64 = struct {
924924 switch (old_inst.encoding.mnemonic) {
925925 .mov => {
926926 const inst = Instruction.new(old_inst.prefix, .lea, &old_inst.ops, t) catch return error.RelaxFail;
927 relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding });
927 relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding });
928928 encode(&.{inst}, code) catch return error.RelaxFail;
929929 },
930930 else => return error.RelaxFail,
......@@ -938,11 +938,9 @@ const x86_64 = struct {
938938 }
939939
940940 fn encode(insts: []const Instruction, code: []u8) !void {
941 var stream = std.io.fixedBufferStream(code);
942 const writer = stream.writer();
943 for (insts) |inst| {
944 try inst.encode(writer, .{});
945 }
941 var bw: std.io.BufferedWriter = undefined;
942 bw.initFixed(code);
943 for (insts) |inst| try inst.encode(&bw, .{});
946944 }
947945
948946 const bits = @import("../../arch/x86_64/bits.zig");
......@@ -1003,7 +1001,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r
10031001 }
10041002
10051003 switch (rel.tag) {
1006 .local => relocs_log.debug(" {}: [{x} => {d}({s},{s})] + {x}", .{
1004 .local => relocs_log.debug(" {f}: [{x} => {d}({s},{s})] + {x}", .{
10071005 rel.fmtPretty(cpu_arch),
10081006 r_address,
10091007 r_symbolnum,
......@@ -1011,7 +1009,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r
10111009 macho_file.sections.items(.header)[r_symbolnum - 1].sectName(),
10121010 addend,
10131011 }),
1014 .@"extern" => relocs_log.debug(" {}: [{x} => {d}({s})] + {x}", .{
1012 .@"extern" => relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{
10151013 rel.fmtPretty(cpu_arch),
10161014 r_address,
10171015 r_symbolnum,
......@@ -1142,33 +1140,27 @@ const FormatContext = struct {
11421140 macho_file: *MachO,
11431141};
11441142
1145fn format2(
1146 ctx: FormatContext,
1147 comptime unused_fmt_string: []const u8,
1148 options: std.fmt.FormatOptions,
1149 writer: anytype,
1150) !void {
1151 _ = options;
1143fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
11521144 _ = unused_fmt_string;
11531145 const atom = ctx.atom;
11541146 const macho_file = ctx.macho_file;
11551147 const file = atom.getFile(macho_file);
1156 try writer.print("atom({d}) : {s} : @{x} : sect({d}) : align({x}) : size({x}) : nreloc({d}) : thunk({d})", .{
1148 try bw.print("atom({d}) : {s} : @{x} : sect({d}) : align({x}) : size({x}) : nreloc({d}) : thunk({d})", .{
11571149 atom.atom_index, atom.getName(macho_file), atom.getAddress(macho_file),
11581150 atom.out_n_sect, atom.alignment, atom.size,
11591151 atom.getRelocs(macho_file).len, atom.getExtra(macho_file).thunk,
11601152 });
1161 if (!atom.isAlive()) try writer.writeAll(" : [*]");
1153 if (!atom.isAlive()) try bw.writeAll(" : [*]");
11621154 if (atom.getUnwindRecords(macho_file).len > 0) {
1163 try writer.writeAll(" : unwind{ ");
1155 try bw.writeAll(" : unwind{ ");
11641156 const extra = atom.getExtra(macho_file);
11651157 for (atom.getUnwindRecords(macho_file), extra.unwind_index..) |index, i| {
11661158 const rec = file.object.getUnwindRecord(index);
1167 try writer.print("{d}", .{index});
1168 if (!rec.alive) try writer.writeAll("([*])");
1169 if (i < extra.unwind_index + extra.unwind_count - 1) try writer.writeAll(", ");
1159 try bw.print("{d}", .{index});
1160 if (!rec.alive) try bw.writeAll("([*])");
1161 if (i < extra.unwind_index + extra.unwind_count - 1) try bw.writeAll(", ");
11701162 }
1171 try writer.writeAll(" }");
1163 try bw.writeAll(" }");
11721164 }
11731165}
11741166
src/link/MachO/CodeSignature.zig+13-9
......@@ -247,7 +247,7 @@ pub fn deinit(self: *CodeSignature, allocator: Allocator) void {
247247pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const u8) !void {
248248 const file = try fs.cwd().openFile(path, .{});
249249 defer file.close();
250 const inner = try file.readToEndAlloc(allocator, std.math.maxInt(u32));
250 const inner = try file.readToEndAlloc(allocator, .unlimited);
251251 self.entitlements = .{ .inner = inner };
252252}
253253
......@@ -304,10 +304,12 @@ pub fn writeAdhocSignature(
304304 var hash: [hash_size]u8 = undefined;
305305
306306 if (self.requirements) |*req| {
307 var buf = std.ArrayList(u8).init(allocator);
308 defer buf.deinit();
309 try req.write(buf.writer());
310 Sha256.hash(buf.items, &hash, .{});
307 var aw: std.io.AllocatingWriter = undefined;
308 aw.init(allocator);
309 defer aw.deinit();
310
311 try req.write(&aw.buffered_writer);
312 Sha256.hash(aw.getWritten(), &hash, .{});
311313 self.code_directory.addSpecialHash(req.slotType(), hash);
312314
313315 try blobs.append(.{ .requirements = req });
......@@ -316,10 +318,12 @@ pub fn writeAdhocSignature(
316318 }
317319
318320 if (self.entitlements) |*ents| {
319 var buf = std.ArrayList(u8).init(allocator);
320 defer buf.deinit();
321 try ents.write(buf.writer());
322 Sha256.hash(buf.items, &hash, .{});
321 var aw: std.io.AllocatingWriter = undefined;
322 aw.init(allocator);
323 defer aw.deinit();
324
325 try ents.write(&aw.buffered_writer);
326 Sha256.hash(aw.getWritten(), &hash, .{});
323327 self.code_directory.addSpecialHash(ents.slotType(), hash);
324328
325329 try blobs.append(.{ .entitlements = ents });
src/link/MachO/DebugSymbols.zig+12-16
......@@ -269,18 +269,15 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
269269
270270fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } {
271271 const gpa = self.allocator;
272 const needed_size = load_commands.calcLoadCommandsSizeDsym(macho_file, self);
273 const buffer = try gpa.alloc(u8, needed_size);
274 defer gpa.free(buffer);
275
276 var stream = std.io.fixedBufferStream(buffer);
277 const writer = stream.writer();
272 var bw: std.io.BufferedWriter = undefined;
273 bw.initFixed(try gpa.alloc(u8, load_commands.calcLoadCommandsSizeDsym(macho_file, self)));
274 defer gpa.free(bw.buffer);
278275
279276 var ncmds: usize = 0;
280277
281278 // UUID comes first presumably to speed up lookup by the consumer like lldb.
282279 @memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid);
283 try writer.writeStruct(self.uuid_cmd);
280 try bw.writeStruct(self.uuid_cmd);
284281 ncmds += 1;
285282
286283 // Segment and section load commands
......@@ -293,11 +290,11 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u
293290 var out_seg = seg;
294291 out_seg.fileoff = 0;
295292 out_seg.filesize = 0;
296 try writer.writeStruct(out_seg);
293 try bw.writeStruct(out_seg);
297294 for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| {
298295 var out_header = header;
299296 out_header.offset = 0;
300 try writer.writeStruct(out_header);
297 try bw.writeStruct(out_header);
301298 }
302299 sect_id += seg.nsects;
303300 }
......@@ -306,23 +303,22 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u
306303 // Next, commit DSYM's __LINKEDIT and __DWARF segments headers.
307304 sect_id = 0;
308305 for (self.segments.items) |seg| {
309 try writer.writeStruct(seg);
306 try bw.writeStruct(seg);
310307 for (self.sections.items[sect_id..][0..seg.nsects]) |header| {
311 try writer.writeStruct(header);
308 try bw.writeStruct(header);
312309 }
313310 sect_id += seg.nsects;
314311 }
315312 ncmds += self.segments.items.len;
316313 }
317314
318 try writer.writeStruct(self.symtab_cmd);
315 try bw.writeStruct(self.symtab_cmd);
319316 ncmds += 1;
320317
321 assert(stream.pos == needed_size);
322
323 try self.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
318 assert(bw.end == bw.buffer.len);
319 try self.file.?.pwriteAll(bw.buffer, @sizeOf(macho.mach_header_64));
324320
325 return .{ ncmds, buffer.len };
321 return .{ ncmds, bw.end };
326322}
327323
328324fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {
src/link/MachO/Dwarf.zig+20-30
......@@ -81,7 +81,7 @@ pub const InfoReader = struct {
8181 .dwarf64 => 12,
8282 } + cuh_length;
8383 while (p.pos < end_pos) {
84 const di_code = try p.readUleb128(u64);
84 const di_code = try p.readLeb128(u64);
8585 if (di_code == 0) return error.UnexpectedEndOfFile;
8686 if (di_code == code) return;
8787
......@@ -174,14 +174,14 @@ pub const InfoReader = struct {
174174 dw.FORM.block1 => try p.readByte(),
175175 dw.FORM.block2 => try p.readInt(u16),
176176 dw.FORM.block4 => try p.readInt(u32),
177 dw.FORM.block => try p.readUleb128(u64),
177 dw.FORM.block => try p.readLeb128(u64),
178178 else => unreachable,
179179 };
180180 return p.readNBytes(len);
181181 }
182182
183183 pub fn readExprLoc(p: *InfoReader) ![]const u8 {
184 const len: u64 = try p.readUleb128(u64);
184 const len: u64 = try p.readLeb128(u64);
185185 return p.readNBytes(len);
186186 }
187187
......@@ -191,8 +191,8 @@ pub const InfoReader = struct {
191191 dw.FORM.data2, dw.FORM.ref2 => try p.readInt(u16),
192192 dw.FORM.data4, dw.FORM.ref4 => try p.readInt(u32),
193193 dw.FORM.data8, dw.FORM.ref8, dw.FORM.ref_sig8 => try p.readInt(u64),
194 dw.FORM.udata, dw.FORM.ref_udata => try p.readUleb128(u64),
195 dw.FORM.sdata => @bitCast(try p.readIleb128(i64)),
194 dw.FORM.udata, dw.FORM.ref_udata => try p.readLeb128(u64),
195 dw.FORM.sdata => @bitCast(try p.readLeb128(i64)),
196196 else => return error.UnhandledConstantForm,
197197 };
198198 }
......@@ -203,7 +203,7 @@ pub const InfoReader = struct {
203203 dw.FORM.strx2, dw.FORM.addrx2 => try p.readInt(u16),
204204 dw.FORM.strx3, dw.FORM.addrx3 => error.UnhandledForm,
205205 dw.FORM.strx4, dw.FORM.addrx4 => try p.readInt(u32),
206 dw.FORM.strx, dw.FORM.addrx => try p.readUleb128(u64),
206 dw.FORM.strx, dw.FORM.addrx => try p.readLeb128(u64),
207207 else => return error.UnhandledIndexForm,
208208 };
209209 }
......@@ -272,20 +272,11 @@ pub const InfoReader = struct {
272272 };
273273 }
274274
275 pub fn readUleb128(p: *InfoReader, comptime Type: type) !Type {
276 var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]);
277 var creader = std.io.countingReader(stream.reader());
278 const value: Type = try leb.readUleb128(Type, creader.reader());
279 p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
280 return value;
281 }
282
283 pub fn readIleb128(p: *InfoReader, comptime Type: type) !Type {
284 var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]);
285 var creader = std.io.countingReader(stream.reader());
286 const value: Type = try leb.readIleb128(Type, creader.reader());
287 p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
288 return value;
275 pub fn readLeb128(p: *InfoReader, comptime Type: type) !Type {
276 var br: std.io.BufferedReader = undefined;
277 br.initFixed(p.bytes()[p.pos..]);
278 defer p.pos += br.seek;
279 return br.takeLeb128(Type);
289280 }
290281
291282 pub fn seekTo(p: *InfoReader, off: u64) !void {
......@@ -307,10 +298,10 @@ pub const AbbrevReader = struct {
307298
308299 pub fn readDecl(p: *AbbrevReader) !?AbbrevDecl {
309300 const pos = p.pos;
310 const code = try p.readUleb128(Code);
301 const code = try p.readLeb128(Code);
311302 if (code == 0) return null;
312303
313 const tag = try p.readUleb128(Tag);
304 const tag = try p.readLeb128(Tag);
314305 const has_children = (try p.readByte()) > 0;
315306 return .{
316307 .code = code,
......@@ -323,8 +314,8 @@ pub const AbbrevReader = struct {
323314
324315 pub fn readAttr(p: *AbbrevReader) !?AbbrevAttr {
325316 const pos = p.pos;
326 const at = try p.readUleb128(At);
327 const form = try p.readUleb128(Form);
317 const at = try p.readLeb128(At);
318 const form = try p.readLeb128(Form);
328319 return if (at == 0 and form == 0) null else .{
329320 .at = at,
330321 .form = form,
......@@ -339,12 +330,11 @@ pub const AbbrevReader = struct {
339330 return p.bytes()[p.pos];
340331 }
341332
342 pub fn readUleb128(p: *AbbrevReader, comptime Type: type) !Type {
343 var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]);
344 var creader = std.io.countingReader(stream.reader());
345 const value: Type = try leb.readUleb128(Type, creader.reader());
346 p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
347 return value;
333 pub fn readLeb128(p: *AbbrevReader, comptime Type: type) !Type {
334 var br: std.io.BufferedReader = undefined;
335 br.initFixed(p.bytes()[p.pos..]);
336 defer p.pos += br.seek;
337 return br.takeLeb128(Type);
348338 }
349339
350340 pub fn seekTo(p: *AbbrevReader, off: u64) !void {
src/link/MachO/Dylib.zig+26-72
......@@ -61,7 +61,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
6161 const file = macho_file.getFileHandle(self.file_handle);
6262 const offset = self.offset;
6363
64 log.debug("parsing dylib from binary: {}", .{@as(Path, self.path)});
64 log.debug("parsing dylib from binary: {f}", .{@as(Path, self.path)});
6565
6666 var header_buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined;
6767 {
......@@ -140,7 +140,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
140140
141141 if (self.platform) |platform| {
142142 if (!macho_file.platform.eqlTarget(platform)) {
143 try macho_file.reportParseError2(self.index, "invalid platform: {}", .{
143 try macho_file.reportParseError2(self.index, "invalid platform: {f}", .{
144144 platform.fmtTarget(macho_file.getTarget().cpu.arch),
145145 });
146146 return error.InvalidTarget;
......@@ -148,7 +148,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
148148 // TODO: this can cause the CI to fail so I'm commenting this check out so that
149149 // I can work out the rest of the changes first
150150 // if (macho_file.platform.version.order(platform.version) == .lt) {
151 // try macho_file.reportParseError2(self.index, "object file built for newer platform: {}: {} < {}", .{
151 // try macho_file.reportParseError2(self.index, "object file built for newer platform: {f}: {f} < {f}", .{
152152 // macho_file.platform.fmtTarget(macho_file.getTarget().cpu.arch),
153153 // macho_file.platform.version,
154154 // platform.version,
......@@ -158,46 +158,6 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
158158 }
159159}
160160
161const TrieIterator = struct {
162 data: []const u8,
163 pos: usize = 0,
164
165 fn getStream(it: *TrieIterator) std.io.FixedBufferStream([]const u8) {
166 return std.io.fixedBufferStream(it.data[it.pos..]);
167 }
168
169 fn readUleb128(it: *TrieIterator) !u64 {
170 var stream = it.getStream();
171 var creader = std.io.countingReader(stream.reader());
172 const reader = creader.reader();
173 const value = try std.leb.readUleb128(u64, reader);
174 it.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
175 return value;
176 }
177
178 fn readString(it: *TrieIterator) ![:0]const u8 {
179 var stream = it.getStream();
180 const reader = stream.reader();
181
182 var count: usize = 0;
183 while (true) : (count += 1) {
184 const byte = try reader.readByte();
185 if (byte == 0) break;
186 }
187
188 const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0];
189 it.pos += count + 1;
190 return str;
191 }
192
193 fn readByte(it: *TrieIterator) !u8 {
194 var stream = it.getStream();
195 const value = try stream.reader().readByte();
196 it.pos += 1;
197 return value;
198 }
199};
200
201161pub fn addExport(self: *Dylib, allocator: Allocator, name: []const u8, flags: Export.Flags) !void {
202162 try self.exports.append(allocator, .{
203163 .name = try self.addString(allocator, name),
......@@ -207,16 +167,16 @@ pub fn addExport(self: *Dylib, allocator: Allocator, name: []const u8, flags: Ex
207167
208168fn parseTrieNode(
209169 self: *Dylib,
210 it: *TrieIterator,
170 br: *std.io.BufferedReader,
211171 allocator: Allocator,
212172 arena: Allocator,
213173 prefix: []const u8,
214174) !void {
215175 const tracy = trace(@src());
216176 defer tracy.end();
217 const size = try it.readUleb128();
177 const size = try br.takeLeb128(u64);
218178 if (size > 0) {
219 const flags = try it.readUleb128();
179 const flags = try br.takeLeb128(u8);
220180 const kind = flags & macho.EXPORT_SYMBOL_FLAGS_KIND_MASK;
221181 const out_flags = Export.Flags{
222182 .abs = kind == macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE,
......@@ -224,29 +184,28 @@ fn parseTrieNode(
224184 .weak = flags & macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION != 0,
225185 };
226186 if (flags & macho.EXPORT_SYMBOL_FLAGS_REEXPORT != 0) {
227 _ = try it.readUleb128(); // dylib ordinal
228 const name = try it.readString();
187 _ = try br.takeLeb128(u64); // dylib ordinal
188 const name = try br.takeSentinel(0);
229189 try self.addExport(allocator, if (name.len > 0) name else prefix, out_flags);
230190 } else if (flags & macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER != 0) {
231 _ = try it.readUleb128(); // stub offset
232 _ = try it.readUleb128(); // resolver offset
191 _ = try br.takeLeb128(u64); // stub offset
192 _ = try br.takeLeb128(u64); // resolver offset
233193 try self.addExport(allocator, prefix, out_flags);
234194 } else {
235 _ = try it.readUleb128(); // VM offset
195 _ = try br.takeLeb128(u64); // VM offset
236196 try self.addExport(allocator, prefix, out_flags);
237197 }
238198 }
239199
240 const nedges = try it.readByte();
241
200 const nedges = try br.takeByte();
242201 for (0..nedges) |_| {
243 const label = try it.readString();
244 const off = try it.readUleb128();
202 const label = try br.takeSentinel(0);
203 const off = try br.takeLeb128(usize);
245204 const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label });
246 const curr = it.pos;
247 it.pos = math.cast(usize, off) orelse return error.Overflow;
248 try self.parseTrieNode(it, allocator, arena, prefix_label);
249 it.pos = curr;
205 const seek = br.seek;
206 br.seek = off;
207 try self.parseTrieNode(br, allocator, arena, prefix_label);
208 br.seek = seek;
250209 }
251210}
252211
......@@ -257,8 +216,9 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void {
257216 var arena = std.heap.ArenaAllocator.init(gpa);
258217 defer arena.deinit();
259218
260 var it: TrieIterator = .{ .data = data };
261 try self.parseTrieNode(&it, gpa, arena.allocator(), "");
219 var br: std.io.BufferedReader = undefined;
220 br.initFixed(data);
221 try self.parseTrieNode(&br, gpa, arena.allocator(), "");
262222}
263223
264224fn parseTbd(self: *Dylib, macho_file: *MachO) !void {
......@@ -267,7 +227,7 @@ fn parseTbd(self: *Dylib, macho_file: *MachO) !void {
267227
268228 const gpa = macho_file.base.comp.gpa;
269229
270 log.debug("parsing dylib from stub: {}", .{self.path});
230 log.debug("parsing dylib from stub: {f}", .{self.path});
271231
272232 const file = macho_file.getFileHandle(self.file_handle);
273233 var lib_stub = LibStub.loadFromFile(gpa, file) catch |err| {
......@@ -716,24 +676,18 @@ const FormatContext = struct {
716676 macho_file: *MachO,
717677};
718678
719fn formatSymtab(
720 ctx: FormatContext,
721 comptime unused_fmt_string: []const u8,
722 options: std.fmt.FormatOptions,
723 writer: anytype,
724) !void {
679fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
725680 _ = unused_fmt_string;
726 _ = options;
727681 const dylib = ctx.dylib;
728682 const macho_file = ctx.macho_file;
729 try writer.writeAll(" globals\n");
683 try bw.writeAll(" globals\n");
730684 for (dylib.symbols.items, 0..) |sym, i| {
731685 const ref = dylib.getSymbolRef(@intCast(i), macho_file);
732686 if (ref.getFile(macho_file) == null) {
733687 // TODO any better way of handling this?
734 try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
688 try bw.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
735689 } else {
736 try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
690 try bw.print(" {f}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
737691 }
738692 }
739693}
src/link/MachO/InternalObject.zig+8-20
......@@ -261,7 +261,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
261261
262262 sect.offset = @intCast(self.objc_methnames.items.len);
263263 try self.objc_methnames.ensureUnusedCapacity(gpa, methname.len + 1);
264 self.objc_methnames.writer(gpa).print("{s}\x00", .{methname}) catch unreachable;
264 self.objc_methnames.print(gpa, "{s}\x00", .{methname}) catch unreachable;
265265
266266 const name_str = try self.addString(gpa, "ltmp");
267267 const sym_index = try self.addSymbol(gpa);
......@@ -848,18 +848,12 @@ pub fn fmtAtoms(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(for
848848 } };
849849}
850850
851fn formatAtoms(
852 ctx: FormatContext,
853 comptime unused_fmt_string: []const u8,
854 options: std.fmt.FormatOptions,
855 writer: anytype,
856) !void {
851fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
857852 _ = unused_fmt_string;
858 _ = options;
859 try writer.writeAll(" atoms\n");
853 try bw.writeAll(" atoms\n");
860854 for (ctx.self.getAtoms()) |atom_index| {
861855 const atom = ctx.self.getAtom(atom_index) orelse continue;
862 try writer.print(" {}\n", .{atom.fmt(ctx.macho_file)});
856 try bw.print(" {f}\n", .{atom.fmt(ctx.macho_file)});
863857 }
864858}
865859
......@@ -870,24 +864,18 @@ pub fn fmtSymtab(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(fo
870864 } };
871865}
872866
873fn formatSymtab(
874 ctx: FormatContext,
875 comptime unused_fmt_string: []const u8,
876 options: std.fmt.FormatOptions,
877 writer: anytype,
878) !void {
867fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
879868 _ = unused_fmt_string;
880 _ = options;
881869 const macho_file = ctx.macho_file;
882870 const self = ctx.self;
883 try writer.writeAll(" symbols\n");
871 try bw.writeAll(" symbols\n");
884872 for (self.symbols.items, 0..) |sym, i| {
885873 const ref = self.getSymbolRef(@intCast(i), macho_file);
886874 if (ref.getFile(macho_file) == null) {
887875 // TODO any better way of handling this?
888 try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
876 try bw.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
889877 } else {
890 try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
878 try bw.print(" {f}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
891879 }
892880 }
893881}
src/link/MachO/Object.zig+39-92
......@@ -72,7 +72,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
7272 const tracy = trace(@src());
7373 defer tracy.end();
7474
75 log.debug("parsing {}", .{self.fmtPath()});
75 log.debug("parsing {f}", .{self.fmtPath()});
7676
7777 const gpa = macho_file.base.comp.gpa;
7878 const handle = macho_file.getFileHandle(self.file_handle);
......@@ -239,7 +239,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
239239
240240 if (self.platform) |platform| {
241241 if (!macho_file.platform.eqlTarget(platform)) {
242 try macho_file.reportParseError2(self.index, "invalid platform: {}", .{
242 try macho_file.reportParseError2(self.index, "invalid platform: {f}", .{
243243 platform.fmtTarget(cpu_arch),
244244 });
245245 return error.InvalidTarget;
......@@ -247,7 +247,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
247247 // TODO: this causes the CI to fail so I'm commenting this check out so that
248248 // I can work out the rest of the changes first
249249 // if (macho_file.platform.version.order(platform.version) == .lt) {
250 // try macho_file.reportParseError2(self.index, "object file built for newer platform: {}: {} < {}", .{
250 // try macho_file.reportParseError2(self.index, "object file built for newer platform: {f}: {f} < {f}", .{
251251 // macho_file.platform.fmtTarget(macho_file.getTarget().cpu.arch),
252252 // macho_file.platform.version,
253253 // platform.version,
......@@ -1065,7 +1065,8 @@ fn initEhFrameRecords(self: *Object, allocator: Allocator, sect_id: u8, file: Fi
10651065 }
10661066 }
10671067
1068 var it = eh_frame.Iterator{ .data = self.eh_frame_data.items };
1068 var it: eh_frame.Iterator = undefined;
1069 it.br.initFixed(self.eh_frame_data.items);
10691070 while (try it.next()) |rec| {
10701071 switch (rec.tag) {
10711072 .cie => try self.cies.append(allocator, .{
......@@ -1694,11 +1695,11 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void {
16941695 };
16951696}
16961697
1697pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void {
1698pub fn writeAr(self: Object, bw: *std.io.BufferedWriter, ar_format: Archive.Format, macho_file: *MachO) !void {
16981699 // Header
16991700 const size = try macho_file.cast(usize, self.output_ar_state.size);
17001701 const basename = std.fs.path.basename(self.path.sub_path);
1701 try Archive.writeHeader(basename, size, ar_format, writer);
1702 try Archive.writeHeader(bw, basename, size, ar_format);
17021703 // Data
17031704 const file = macho_file.getFileHandle(self.file_handle);
17041705 // TODO try using copyRangeAll
......@@ -1707,7 +1708,7 @@ pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writ
17071708 defer gpa.free(data);
17081709 const amt = try file.preadAll(data, self.offset);
17091710 if (amt != size) return error.InputOutput;
1710 try writer.writeAll(data);
1711 try bw.writeAll(data);
17111712}
17121713
17131714pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void {
......@@ -1861,7 +1862,7 @@ pub fn writeAtomsRelocatable(self: *Object, macho_file: *MachO) !void {
18611862 }
18621863 gpa.free(sections_data);
18631864 }
1864 @memset(sections_data, &[0]u8{});
1865 @memset(sections_data, &.{});
18651866 const file = macho_file.getFileHandle(self.file_handle);
18661867
18671868 for (headers, 0..) |header, n_sect| {
......@@ -2512,16 +2513,10 @@ pub fn readSectionData(self: Object, allocator: Allocator, file: File.Handle, n_
25122513 return data;
25132514}
25142515
2515pub fn format(
2516 self: *Object,
2517 comptime unused_fmt_string: []const u8,
2518 options: std.fmt.FormatOptions,
2519 writer: anytype,
2520) !void {
2516pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
25212517 _ = self;
2518 _ = bw;
25222519 _ = unused_fmt_string;
2523 _ = options;
2524 _ = writer;
25252520 @compileError("do not format objects directly");
25262521}
25272522
......@@ -2537,20 +2532,14 @@ pub fn fmtAtoms(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatAtoms
25372532 } };
25382533}
25392534
2540fn formatAtoms(
2541 ctx: FormatContext,
2542 comptime unused_fmt_string: []const u8,
2543 options: std.fmt.FormatOptions,
2544 writer: anytype,
2545) !void {
2535fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
25462536 _ = unused_fmt_string;
2547 _ = options;
25482537 const object = ctx.object;
25492538 const macho_file = ctx.macho_file;
2550 try writer.writeAll(" atoms\n");
2539 try bw.writeAll(" atoms\n");
25512540 for (object.getAtoms()) |atom_index| {
25522541 const atom = object.getAtom(atom_index) orelse continue;
2553 try writer.print(" {}\n", .{atom.fmt(macho_file)});
2542 try bw.print(" {f}\n", .{atom.fmt(macho_file)});
25542543 }
25552544}
25562545
......@@ -2561,18 +2550,12 @@ pub fn fmtCies(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatCies)
25612550 } };
25622551}
25632552
2564fn formatCies(
2565 ctx: FormatContext,
2566 comptime unused_fmt_string: []const u8,
2567 options: std.fmt.FormatOptions,
2568 writer: anytype,
2569) !void {
2553fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
25702554 _ = unused_fmt_string;
2571 _ = options;
25722555 const object = ctx.object;
2573 try writer.writeAll(" cies\n");
2556 try bw.writeAll(" cies\n");
25742557 for (object.cies.items, 0..) |cie, i| {
2575 try writer.print(" cie({d}) : {}\n", .{ i, cie.fmt(ctx.macho_file) });
2558 try bw.print(" cie({d}) : {f}\n", .{ i, cie.fmt(ctx.macho_file) });
25762559 }
25772560}
25782561
......@@ -2583,18 +2566,12 @@ pub fn fmtFdes(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatFdes)
25832566 } };
25842567}
25852568
2586fn formatFdes(
2587 ctx: FormatContext,
2588 comptime unused_fmt_string: []const u8,
2589 options: std.fmt.FormatOptions,
2590 writer: anytype,
2591) !void {
2569fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
25922570 _ = unused_fmt_string;
2593 _ = options;
25942571 const object = ctx.object;
2595 try writer.writeAll(" fdes\n");
2572 try bw.writeAll(" fdes\n");
25962573 for (object.fdes.items, 0..) |fde, i| {
2597 try writer.print(" fde({d}) : {}\n", .{ i, fde.fmt(ctx.macho_file) });
2574 try bw.print(" fde({d}) : {f}\n", .{ i, fde.fmt(ctx.macho_file) });
25982575 }
25992576}
26002577
......@@ -2605,19 +2582,13 @@ pub fn fmtUnwindRecords(self: *Object, macho_file: *MachO) std.fmt.Formatter(for
26052582 } };
26062583}
26072584
2608fn formatUnwindRecords(
2609 ctx: FormatContext,
2610 comptime unused_fmt_string: []const u8,
2611 options: std.fmt.FormatOptions,
2612 writer: anytype,
2613) !void {
2585fn formatUnwindRecords(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
26142586 _ = unused_fmt_string;
2615 _ = options;
26162587 const object = ctx.object;
26172588 const macho_file = ctx.macho_file;
2618 try writer.writeAll(" unwind records\n");
2589 try bw.writeAll(" unwind records\n");
26192590 for (object.unwind_records_indexes.items) |rec| {
2620 try writer.print(" rec({d}) : {}\n", .{ rec, object.getUnwindRecord(rec).fmt(macho_file) });
2591 try bw.print(" rec({d}) : {f}\n", .{ rec, object.getUnwindRecord(rec).fmt(macho_file) });
26212592 }
26222593}
26232594
......@@ -2628,34 +2599,28 @@ pub fn fmtSymtab(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatSymt
26282599 } };
26292600}
26302601
2631fn formatSymtab(
2632 ctx: FormatContext,
2633 comptime unused_fmt_string: []const u8,
2634 options: std.fmt.FormatOptions,
2635 writer: anytype,
2636) !void {
2602fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
26372603 _ = unused_fmt_string;
2638 _ = options;
26392604 const object = ctx.object;
26402605 const macho_file = ctx.macho_file;
2641 try writer.writeAll(" symbols\n");
2606 try bw.writeAll(" symbols\n");
26422607 for (object.symbols.items, 0..) |sym, i| {
26432608 const ref = object.getSymbolRef(@intCast(i), macho_file);
26442609 if (ref.getFile(macho_file) == null) {
26452610 // TODO any better way of handling this?
2646 try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
2611 try bw.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
26472612 } else {
2648 try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
2613 try bw.print(" {f}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
26492614 }
26502615 }
26512616 for (object.stab_files.items) |sf| {
2652 try writer.print(" stabs({s},{s},{s})\n", .{
2617 try bw.print(" stabs({s},{s},{s})\n", .{
26532618 sf.getCompDir(object.*),
26542619 sf.getTuName(object.*),
26552620 sf.getOsoPath(object.*),
26562621 });
26572622 for (sf.stabs.items) |stab| {
2658 try writer.print(" {}", .{stab.fmt(object.*)});
2623 try bw.print(" {f}", .{stab.fmt(object.*)});
26592624 }
26602625 }
26612626}
......@@ -2664,20 +2629,14 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) {
26642629 return .{ .data = self };
26652630}
26662631
2667fn formatPath(
2668 object: Object,
2669 comptime unused_fmt_string: []const u8,
2670 options: std.fmt.FormatOptions,
2671 writer: anytype,
2672) !void {
2632fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
26732633 _ = unused_fmt_string;
2674 _ = options;
26752634 if (object.in_archive) |ar| {
2676 try writer.print("{}({s})", .{
2677 @as(Path, ar.path), object.path.basename(),
2635 try bw.print("{f}({s})", .{
2636 ar.path, object.path.basename(),
26782637 });
26792638 } else {
2680 try writer.print("{}", .{@as(Path, object.path)});
2639 try bw.print("{f}", .{object.path});
26812640 }
26822641}
26832642
......@@ -2731,16 +2690,10 @@ const StabFile = struct {
27312690 return object.symbols.items[index];
27322691 }
27332692
2734 pub fn format(
2735 stab: Stab,
2736 comptime unused_fmt_string: []const u8,
2737 options: std.fmt.FormatOptions,
2738 writer: anytype,
2739 ) !void {
2693 pub fn format(stab: Stab, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
27402694 _ = stab;
2695 _ = bw;
27412696 _ = unused_fmt_string;
2742 _ = options;
2743 _ = writer;
27442697 @compileError("do not format stabs directly");
27452698 }
27462699
......@@ -2750,22 +2703,16 @@ const StabFile = struct {
27502703 return .{ .data = .{ stab, object } };
27512704 }
27522705
2753 fn format2(
2754 ctx: StabFormatContext,
2755 comptime unused_fmt_string: []const u8,
2756 options: std.fmt.FormatOptions,
2757 writer: anytype,
2758 ) !void {
2706 fn format2(ctx: StabFormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
27592707 _ = unused_fmt_string;
2760 _ = options;
27612708 const stab, const object = ctx;
27622709 const sym = stab.getSymbol(object).?;
27632710 if (stab.is_func) {
2764 try writer.print("func({d})", .{stab.index.?});
2711 try bw.print("func({d})", .{stab.index.?});
27652712 } else if (sym.visibility == .global) {
2766 try writer.print("gsym({d})", .{stab.index.?});
2713 try bw.print("gsym({d})", .{stab.index.?});
27672714 } else {
2768 try writer.print("stsym({d})", .{stab.index.?});
2715 try bw.print("stsym({d})", .{stab.index.?});
27692716 }
27702717 }
27712718 };
src/link/MachO/Relocation.zig+3-10
......@@ -76,16 +76,10 @@ pub fn fmtPretty(rel: Relocation, cpu_arch: std.Target.Cpu.Arch) std.fmt.Formatt
7676 return .{ .data = .{ rel, cpu_arch } };
7777}
7878
79fn formatPretty(
80 ctx: FormatCtx,
81 comptime unused_fmt_string: []const u8,
82 options: std.fmt.FormatOptions,
83 writer: anytype,
84) !void {
85 _ = options;
79fn formatPretty(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
8680 _ = unused_fmt_string;
8781 const rel, const cpu_arch = ctx;
88 const str = switch (rel.type) {
82 try bw.writeAll(switch (rel.type) {
8983 .signed => "X86_64_RELOC_SIGNED",
9084 .signed1 => "X86_64_RELOC_SIGNED_1",
9185 .signed2 => "X86_64_RELOC_SIGNED_2",
......@@ -118,8 +112,7 @@ fn formatPretty(
118112 .aarch64 => "ARM64_RELOC_UNSIGNED",
119113 else => unreachable,
120114 },
121 };
122 try writer.writeAll(str);
115 });
123116}
124117
125118pub const Type = enum {
src/link/MachO/Symbol.zig+14-26
......@@ -286,16 +286,10 @@ pub fn setOutputSym(symbol: Symbol, macho_file: *MachO, out: *macho.nlist_64) vo
286286 }
287287}
288288
289pub fn format(
290 symbol: Symbol,
291 comptime unused_fmt_string: []const u8,
292 options: std.fmt.FormatOptions,
293 writer: anytype,
294) !void {
289pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
295290 _ = symbol;
291 _ = bw;
296292 _ = unused_fmt_string;
297 _ = options;
298 _ = writer;
299293 @compileError("do not format symbols directly");
300294}
301295
......@@ -311,26 +305,20 @@ pub fn fmt(symbol: Symbol, macho_file: *MachO) std.fmt.Formatter(format2) {
311305 } };
312306}
313307
314fn format2(
315 ctx: FormatContext,
316 comptime unused_fmt_string: []const u8,
317 options: std.fmt.FormatOptions,
318 writer: anytype,
319) !void {
320 _ = options;
308fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
321309 _ = unused_fmt_string;
322310 const symbol = ctx.symbol;
323 try writer.print("%{d} : {s} : @{x}", .{
311 try bw.print("%{d} : {s} : @{x}", .{
324312 symbol.nlist_idx,
325313 symbol.getName(ctx.macho_file),
326314 symbol.getAddress(.{}, ctx.macho_file),
327315 });
328316 if (symbol.getFile(ctx.macho_file)) |file| {
329317 if (symbol.getOutputSectionIndex(ctx.macho_file) != 0) {
330 try writer.print(" : sect({d})", .{symbol.getOutputSectionIndex(ctx.macho_file)});
318 try bw.print(" : sect({d})", .{symbol.getOutputSectionIndex(ctx.macho_file)});
331319 }
332320 if (symbol.getAtom(ctx.macho_file)) |atom| {
333 try writer.print(" : atom({d})", .{atom.atom_index});
321 try bw.print(" : atom({d})", .{atom.atom_index});
334322 }
335323 var buf: [3]u8 = .{'_'} ** 3;
336324 if (symbol.flags.@"export") buf[0] = 'E';
......@@ -340,16 +328,16 @@ fn format2(
340328 .hidden => buf[2] = 'H',
341329 .global => buf[2] = 'G',
342330 }
343 try writer.print(" : {s}", .{&buf});
344 if (symbol.flags.weak) try writer.writeAll(" : weak");
345 if (symbol.isSymbolStab(ctx.macho_file)) try writer.writeAll(" : stab");
331 try bw.print(" : {s}", .{&buf});
332 if (symbol.flags.weak) try bw.writeAll(" : weak");
333 if (symbol.isSymbolStab(ctx.macho_file)) try bw.writeAll(" : stab");
346334 switch (file) {
347 .zig_object => |x| try writer.print(" : zig_object({d})", .{x.index}),
348 .internal => |x| try writer.print(" : internal({d})", .{x.index}),
349 .object => |x| try writer.print(" : object({d})", .{x.index}),
350 .dylib => |x| try writer.print(" : dylib({d})", .{x.index}),
335 .zig_object => |x| try bw.print(" : zig_object({d})", .{x.index}),
336 .internal => |x| try bw.print(" : internal({d})", .{x.index}),
337 .object => |x| try bw.print(" : object({d})", .{x.index}),
338 .dylib => |x| try bw.print(" : dylib({d})", .{x.index}),
351339 }
352 } else try writer.writeAll(" : unresolved");
340 } else try bw.writeAll(" : unresolved");
353341}
354342
355343pub const Flags = packed struct {
src/link/MachO/Thunk.zig+9-21
......@@ -20,16 +20,16 @@ pub fn getTargetAddress(thunk: Thunk, ref: MachO.Ref, macho_file: *MachO) u64 {
2020 return thunk.getAddress(macho_file) + thunk.symbols.getIndex(ref).? * trampoline_size;
2121}
2222
23pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void {
23pub fn write(thunk: Thunk, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
2424 for (thunk.symbols.keys(), 0..) |ref, i| {
2525 const sym = ref.getSymbol(macho_file).?;
2626 const saddr = thunk.getAddress(macho_file) + i * trampoline_size;
2727 const taddr = sym.getAddress(.{}, macho_file);
2828 const pages = try aarch64.calcNumberOfPages(@intCast(saddr), @intCast(taddr));
29 try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
29 try bw.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
3030 const off: u12 = @truncate(taddr);
31 try writer.writeInt(u32, aarch64.Instruction.add(.x16, .x16, off, false).toU32(), .little);
32 try writer.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
31 try bw.writeInt(u32, aarch64.Instruction.add(.x16, .x16, off, false).toU32(), .little);
32 try bw.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
3333 }
3434}
3535
......@@ -61,16 +61,10 @@ pub fn writeSymtab(thunk: Thunk, macho_file: *MachO, ctx: anytype) void {
6161 }
6262}
6363
64pub fn format(
65 thunk: Thunk,
66 comptime unused_fmt_string: []const u8,
67 options: std.fmt.FormatOptions,
68 writer: anytype,
69) !void {
64pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
7065 _ = thunk;
66 _ = bw;
7167 _ = unused_fmt_string;
72 _ = options;
73 _ = writer;
7468 @compileError("do not format Thunk directly");
7569}
7670
......@@ -86,20 +80,14 @@ const FormatContext = struct {
8680 macho_file: *MachO,
8781};
8882
89fn format2(
90 ctx: FormatContext,
91 comptime unused_fmt_string: []const u8,
92 options: std.fmt.FormatOptions,
93 writer: anytype,
94) !void {
95 _ = options;
83fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
9684 _ = unused_fmt_string;
9785 const thunk = ctx.thunk;
9886 const macho_file = ctx.macho_file;
99 try writer.print("@{x} : size({x})\n", .{ thunk.value, thunk.size() });
87 try bw.print("@{x} : size({x})\n", .{ thunk.value, thunk.size() });
10088 for (thunk.symbols.keys()) |ref| {
10189 const sym = ref.getSymbol(macho_file).?;
102 try writer.print(" {} : {s} : @{x}\n", .{ ref, sym.getName(macho_file), sym.value });
90 try bw.print(" {f} : {s} : @{x}\n", .{ ref, sym.getName(macho_file), sym.value });
10391 }
10492}
10593
src/link/MachO/UnwindInfo.zig+32-68
......@@ -133,7 +133,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
133133 for (info.records.items) |ref| {
134134 const rec = ref.getUnwindRecord(macho_file);
135135 const atom = rec.getAtom(macho_file);
136 log.debug("@{x}-{x} : {s} : rec({d}) : object({d}) : {}", .{
136 log.debug("@{x}-{x} : {s} : rec({d}) : object({d}) : {f}", .{
137137 rec.getAtomAddress(macho_file),
138138 rec.getAtomAddress(macho_file) + rec.length,
139139 atom.getName(macho_file),
......@@ -202,7 +202,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
202202 if (i >= max_common_encodings) break;
203203 if (slice[i].count < 2) continue;
204204 info.appendCommonEncoding(slice[i].enc);
205 log.debug("adding common encoding: {d} => {}", .{ i, slice[i].enc });
205 log.debug("adding common encoding: {d} => {f}", .{ i, slice[i].enc });
206206 }
207207 }
208208
......@@ -255,7 +255,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
255255 page.kind = .compressed;
256256 }
257257
258 log.debug("{}", .{page.fmt(info.*)});
258 log.debug("{f}", .{page.fmt(info.*)});
259259
260260 try info.pages.append(gpa, page);
261261 }
......@@ -289,13 +289,10 @@ pub fn calcSize(info: UnwindInfo) usize {
289289 return total_size;
290290}
291291
292pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
292pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *std.io.BufferedWriter) anyerror!void {
293293 const seg = macho_file.getTextSegment();
294294 const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?];
295295
296 var stream = std.io.fixedBufferStream(buffer);
297 const writer = stream.writer();
298
299296 const common_encodings_offset: u32 = @sizeOf(macho.unwind_info_section_header);
300297 const common_encodings_count: u32 = info.common_encodings_count;
301298 const personalities_offset: u32 = common_encodings_offset + common_encodings_count * @sizeOf(u32);
......@@ -303,7 +300,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
303300 const indexes_offset: u32 = personalities_offset + personalities_count * @sizeOf(u32);
304301 const indexes_count: u32 = @as(u32, @intCast(info.pages.items.len + 1));
305302
306 try writer.writeStruct(macho.unwind_info_section_header{
303 try bw.writeStruct(macho.unwind_info_section_header{
307304 .commonEncodingsArraySectionOffset = common_encodings_offset,
308305 .commonEncodingsArrayCount = common_encodings_count,
309306 .personalityArraySectionOffset = personalities_offset,
......@@ -312,11 +309,11 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
312309 .indexCount = indexes_count,
313310 });
314311
315 try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count]));
312 try bw.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count]));
316313
317314 for (info.personalities[0..info.personalities_count]) |ref| {
318315 const sym = ref.getSymbol(macho_file).?;
319 try writer.writeInt(u32, @intCast(sym.getGotAddress(macho_file) - seg.vmaddr), .little);
316 try bw.writeInt(u32, @intCast(sym.getGotAddress(macho_file) - seg.vmaddr), .little);
320317 }
321318
322319 const pages_base_offset = @as(u32, @intCast(header.size - (info.pages.items.len * second_level_page_bytes)));
......@@ -325,7 +322,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
325322 for (info.pages.items, 0..) |page, i| {
326323 assert(page.count > 0);
327324 const rec = info.records.items[page.start].getUnwindRecord(macho_file);
328 try writer.writeStruct(macho.unwind_info_section_header_index_entry{
325 try bw.writeStruct(macho.unwind_info_section_header_index_entry{
329326 .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)),
330327 .secondLevelPagesSectionOffset = @as(u32, @intCast(pages_base_offset + i * second_level_page_bytes)),
331328 .lsdaIndexArraySectionOffset = lsda_base_offset +
......@@ -335,7 +332,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
335332
336333 const last_rec = info.records.items[info.records.items.len - 1].getUnwindRecord(macho_file);
337334 const sentinel_address = @as(u32, @intCast(last_rec.getAtomAddress(macho_file) + last_rec.length - seg.vmaddr));
338 try writer.writeStruct(macho.unwind_info_section_header_index_entry{
335 try bw.writeStruct(macho.unwind_info_section_header_index_entry{
339336 .functionOffset = sentinel_address,
340337 .secondLevelPagesSectionOffset = 0,
341338 .lsdaIndexArraySectionOffset = lsda_base_offset +
......@@ -344,23 +341,20 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
344341
345342 for (info.lsdas.items) |index| {
346343 const rec = info.records.items[index].getUnwindRecord(macho_file);
347 try writer.writeStruct(macho.unwind_info_section_header_lsda_index_entry{
344 try bw.writeStruct(macho.unwind_info_section_header_lsda_index_entry{
348345 .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)),
349346 .lsdaOffset = @as(u32, @intCast(rec.getLsdaAddress(macho_file) - seg.vmaddr)),
350347 });
351348 }
352349
353350 for (info.pages.items) |page| {
354 const start = stream.pos;
355 try page.write(info, macho_file, writer);
356 const nwritten = stream.pos - start;
357 if (nwritten < second_level_page_bytes) {
358 const padding = math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow;
359 try writer.writeByteNTimes(0, padding);
360 }
351 const start = bw.count;
352 try page.write(info, macho_file, bw);
353 const nwritten = bw.count - start;
354 try bw.splatByteAll(0, math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow);
361355 }
362356
363 @memset(buffer[stream.pos..], 0);
357 @memset(bw.unusedCapacitySlice(), 0);
364358}
365359
366360fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 {
......@@ -455,15 +449,9 @@ pub const Encoding = extern struct {
455449 return enc.enc == other.enc;
456450 }
457451
458 pub fn format(
459 enc: Encoding,
460 comptime unused_fmt_string: []const u8,
461 options: std.fmt.FormatOptions,
462 writer: anytype,
463 ) !void {
452 pub fn format(enc: Encoding, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
464453 _ = unused_fmt_string;
465 _ = options;
466 try writer.print("0x{x:0>8}", .{enc.enc});
454 try bw.print("0x{x:0>8}", .{enc.enc});
467455 }
468456};
469457
......@@ -517,16 +505,10 @@ pub const Record = struct {
517505 return lsda.getAddress(macho_file) + rec.lsda_offset;
518506 }
519507
520 pub fn format(
521 rec: Record,
522 comptime unused_fmt_string: []const u8,
523 options: std.fmt.FormatOptions,
524 writer: anytype,
525 ) !void {
508 pub fn format(rec: Record, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
526509 _ = rec;
510 _ = bw;
527511 _ = unused_fmt_string;
528 _ = options;
529 _ = writer;
530512 @compileError("do not format UnwindInfo.Records directly");
531513 }
532514
......@@ -542,22 +524,16 @@ pub const Record = struct {
542524 macho_file: *MachO,
543525 };
544526
545 fn format2(
546 ctx: FormatContext,
547 comptime unused_fmt_string: []const u8,
548 options: std.fmt.FormatOptions,
549 writer: anytype,
550 ) !void {
527 fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
551528 _ = unused_fmt_string;
552 _ = options;
553529 const rec = ctx.rec;
554530 const macho_file = ctx.macho_file;
555 try writer.print("{x} : len({x})", .{
531 try bw.print("{x} : len({x})", .{
556532 rec.enc.enc, rec.length,
557533 });
558 if (rec.enc.isDwarf(macho_file)) try writer.print(" : fde({d})", .{rec.fde});
559 try writer.print(" : {s}", .{rec.getAtom(macho_file).getName(macho_file)});
560 if (!rec.alive) try writer.writeAll(" : [*]");
534 if (rec.enc.isDwarf(macho_file)) try bw.print(" : fde({d})", .{rec.fde});
535 try bw.print(" : {s}", .{rec.getAtom(macho_file).getName(macho_file)});
536 if (!rec.alive) try bw.writeAll(" : [*]");
561537 }
562538
563539 pub const Index = u32;
......@@ -613,16 +589,10 @@ const Page = struct {
613589 return null;
614590 }
615591
616 fn format(
617 page: *const Page,
618 comptime unused_format_string: []const u8,
619 options: std.fmt.FormatOptions,
620 writer: anytype,
621 ) !void {
592 fn format(page: *const Page, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
622593 _ = page;
594 _ = bw;
623595 _ = unused_format_string;
624 _ = options;
625 _ = writer;
626596 @compileError("do not format Page directly; use page.fmt()");
627597 }
628598
......@@ -631,23 +601,17 @@ const Page = struct {
631601 info: UnwindInfo,
632602 };
633603
634 fn format2(
635 ctx: FormatPageContext,
636 comptime unused_format_string: []const u8,
637 options: std.fmt.FormatOptions,
638 writer: anytype,
639 ) @TypeOf(writer).Error!void {
640 _ = options;
604 fn format2(ctx: FormatPageContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
641605 _ = unused_format_string;
642 try writer.writeAll("Page:\n");
643 try writer.print(" kind: {s}\n", .{@tagName(ctx.page.kind)});
644 try writer.print(" entries: {d} - {d}\n", .{
606 try bw.writeAll("Page:\n");
607 try bw.print(" kind: {s}\n", .{@tagName(ctx.page.kind)});
608 try bw.print(" entries: {d} - {d}\n", .{
645609 ctx.page.start,
646610 ctx.page.start + ctx.page.count,
647611 });
648 try writer.print(" encodings (count = {d})\n", .{ctx.page.page_encodings_count});
612 try bw.print(" encodings (count = {d})\n", .{ctx.page.page_encodings_count});
649613 for (ctx.page.page_encodings[0..ctx.page.page_encodings_count], 0..) |enc, i| {
650 try writer.print(" {d}: {}\n", .{ ctx.info.common_encodings_count + i, enc });
614 try bw.print(" {d}: {f}\n", .{ ctx.info.common_encodings_count + i, enc });
651615 }
652616 }
653617
src/link/MachO/ZigObject.zig+16-30
......@@ -317,12 +317,12 @@ pub fn updateArSize(self: *ZigObject) void {
317317 self.output_ar_state.size = self.data.items.len;
318318}
319319
320pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !void {
320pub fn writeAr(self: ZigObject, bw: *std.io.BufferedWriter, ar_format: Archive.Format) anyerror!void {
321321 // Header
322322 const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow;
323 try Archive.writeHeader(self.basename, size, ar_format, writer);
323 try Archive.writeHeader(bw, self.basename, size, ar_format);
324324 // Data
325 try writer.writeAll(self.data.items);
325 try bw.writeAll(self.data.items);
326326}
327327
328328pub fn claimUnresolved(self: *ZigObject, macho_file: *MachO) void {
......@@ -618,7 +618,7 @@ pub fn getNavVAddr(
618618 const zcu = pt.zcu;
619619 const ip = &zcu.intern_pool;
620620 const nav = ip.getNav(nav_index);
621 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
621 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
622622 const sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol(
623623 macho_file,
624624 nav.name.toSlice(ip),
......@@ -884,7 +884,6 @@ pub fn updateNav(
884884 defer debug_wip_nav.deinit();
885885 dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) {
886886 error.OutOfMemory => return error.OutOfMemory,
887 error.Overflow => return error.Overflow,
888887 else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
889888 };
890889 }
......@@ -921,7 +920,6 @@ pub fn updateNav(
921920
922921 if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) {
923922 error.OutOfMemory => return error.OutOfMemory,
924 error.Overflow => return error.Overflow,
925923 else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
926924 };
927925 } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
......@@ -943,7 +941,7 @@ fn updateNavCode(
943941 const ip = &zcu.intern_pool;
944942 const nav = ip.getNav(nav_index);
945943
946 log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
944 log.debug("updateNavCode {f} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
947945
948946 const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
949947 const required_alignment = switch (pt.navAlignment(nav_index)) {
......@@ -981,7 +979,7 @@ fn updateNavCode(
981979 if (need_realloc) {
982980 atom.grow(macho_file) catch |err|
983981 return macho_file.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(err)});
984 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom.value });
982 log.debug("growing {f} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom.value });
985983 if (old_vaddr != atom.value) {
986984 sym.value = 0;
987985 nlist.n_value = 0;
......@@ -1023,7 +1021,7 @@ fn updateTlv(
10231021 const ip = &pt.zcu.intern_pool;
10241022 const nav = ip.getNav(nav_index);
10251023
1026 log.debug("updateTlv {} (0x{x})", .{ nav.fqn.fmt(ip), nav_index });
1024 log.debug("updateTlv {f} (0x{x})", .{ nav.fqn.fmt(ip), nav_index });
10271025
10281026 // 1. Lower TLV initializer
10291027 const init_sym_index = try self.createTlvInitializer(
......@@ -1351,7 +1349,7 @@ fn updateLazySymbol(
13511349 defer code_buffer.deinit(gpa);
13521350
13531351 const name_str = blk: {
1354 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1352 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
13551353 @tagName(lazy_sym.kind),
13561354 Type.fromInterned(lazy_sym.ty).fmt(pt),
13571355 });
......@@ -1430,7 +1428,7 @@ pub fn deleteExport(
14301428 } orelse return;
14311429 const nlist_index = metadata.@"export"(self, name.toSlice(&zcu.intern_pool)) orelse return;
14321430
1433 log.debug("deleting export '{}'", .{name.fmt(&zcu.intern_pool)});
1431 log.debug("deleting export '{f}'", .{name.fmt(&zcu.intern_pool)});
14341432
14351433 const nlist = &self.symtab.items(.nlist)[nlist_index.*];
14361434 self.symtab.items(.size)[nlist_index.*] = 0;
......@@ -1690,24 +1688,18 @@ const FormatContext = struct {
16901688 macho_file: *MachO,
16911689};
16921690
1693fn formatSymtab(
1694 ctx: FormatContext,
1695 comptime unused_fmt_string: []const u8,
1696 options: std.fmt.FormatOptions,
1697 writer: anytype,
1698) !void {
1691fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
16991692 _ = unused_fmt_string;
1700 _ = options;
1701 try writer.writeAll(" symbols\n");
1693 try bw.writeAll(" symbols\n");
17021694 const self = ctx.self;
17031695 const macho_file = ctx.macho_file;
17041696 for (self.symbols.items, 0..) |sym, i| {
17051697 const ref = self.getSymbolRef(@intCast(i), macho_file);
17061698 if (ref.getFile(macho_file) == null) {
17071699 // TODO any better way of handling this?
1708 try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
1700 try bw.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
17091701 } else {
1710 try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
1702 try bw.print(" {f}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
17111703 }
17121704 }
17131705}
......@@ -1719,20 +1711,14 @@ pub fn fmtAtoms(self: *ZigObject, macho_file: *MachO) std.fmt.Formatter(formatAt
17191711 } };
17201712}
17211713
1722fn formatAtoms(
1723 ctx: FormatContext,
1724 comptime unused_fmt_string: []const u8,
1725 options: std.fmt.FormatOptions,
1726 writer: anytype,
1727) !void {
1714fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
17281715 _ = unused_fmt_string;
1729 _ = options;
17301716 const self = ctx.self;
17311717 const macho_file = ctx.macho_file;
1732 try writer.writeAll(" atoms\n");
1718 try bw.writeAll(" atoms\n");
17331719 for (self.getAtoms()) |atom_index| {
17341720 const atom = self.getAtom(atom_index) orelse continue;
1735 try writer.print(" {}\n", .{atom.fmt(macho_file)});
1721 try bw.print(" {f}\n", .{atom.fmt(macho_file)});
17361722 }
17371723}
17381724
src/link/MachO/dead_strip.zig+3-9
......@@ -117,7 +117,7 @@ fn mark(roots: []*Atom, objects: []const File.Index, macho_file: *MachO) void {
117117fn markLive(atom: *Atom, macho_file: *MachO) void {
118118 assert(atom.visited.load(.seq_cst));
119119 atom.setAlive(true);
120 track_live_log.debug("{}marking live atom({d},{s})", .{
120 track_live_log.debug("{f}marking live atom({d},{s})", .{
121121 track_live_level,
122122 atom.atom_index,
123123 atom.getName(macho_file),
......@@ -196,15 +196,9 @@ const Level = struct {
196196 self.value += 1;
197197 }
198198
199 pub fn format(
200 self: *const @This(),
201 comptime unused_fmt_string: []const u8,
202 options: std.fmt.FormatOptions,
203 writer: anytype,
204 ) !void {
199 pub fn format(self: *const @This(), bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
205200 _ = unused_fmt_string;
206 _ = options;
207 try writer.writeByteNTimes(' ', self.value);
201 try bw.splatByteAll(' ', self.value);
208202 }
209203};
210204
src/link/MachO/dyld_info/Rebase.zig+45-45
......@@ -3,7 +3,7 @@ buffer: std.ArrayListUnmanaged(u8) = .empty,
33
44pub const Entry = struct {
55 offset: u64,
6 segment_id: u8,
6 segment_id: u4,
77
88 pub fn lessThan(ctx: void, entry: Entry, other: Entry) bool {
99 _ = ctx;
......@@ -110,33 +110,35 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
110110fn finalize(rebase: *Rebase, gpa: Allocator) !void {
111111 if (rebase.entries.items.len == 0) return;
112112
113 const writer = rebase.buffer.writer(gpa);
113 var aw: std.io.AllocatingWriter = undefined;
114 const bw = aw.fromArrayList(gpa, &rebase.buffer);
115 defer rebase.buffer = aw.toArrayList();
114116
115117 log.debug("rebase opcodes", .{});
116118
117119 std.mem.sort(Entry, rebase.entries.items, {}, Entry.lessThan);
118120
119 try setTypePointer(writer);
121 try setTypePointer(bw);
120122
121123 var start: usize = 0;
122124 var seg_id: ?u8 = null;
123125 for (rebase.entries.items, 0..) |entry, i| {
124126 if (seg_id != null and seg_id.? == entry.segment_id) continue;
125 try finalizeSegment(rebase.entries.items[start..i], writer);
127 try finalizeSegment(rebase.entries.items[start..i], bw);
126128 seg_id = entry.segment_id;
127129 start = i;
128130 }
129131
130 try finalizeSegment(rebase.entries.items[start..], writer);
131 try done(writer);
132 try finalizeSegment(rebase.entries.items[start..], bw);
133 try done(bw);
132134}
133135
134fn finalizeSegment(entries: []const Entry, writer: anytype) !void {
136fn finalizeSegment(entries: []const Entry, bw: *std.io.BufferedWriter) anyerror!void {
135137 if (entries.len == 0) return;
136138
137139 const segment_id = entries[0].segment_id;
138140 var offset = entries[0].offset;
139 try setSegmentOffset(segment_id, offset, writer);
141 try setSegmentOffset(segment_id, offset, bw);
140142
141143 var count: usize = 0;
142144 var skip: u64 = 0;
......@@ -155,7 +157,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void {
155157 .start => {
156158 if (offset < current_offset) {
157159 const delta = current_offset - offset;
158 try addAddr(delta, writer);
160 try addAddr(delta, bw);
159161 offset += delta;
160162 }
161163 state = .times;
......@@ -175,7 +177,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void {
175177 offset += skip;
176178 i -= 1;
177179 } else {
178 try rebaseTimes(count, writer);
180 try rebaseTimes(count, bw);
179181 state = .start;
180182 i -= 1;
181183 }
......@@ -184,9 +186,9 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void {
184186 if (current_offset < offset) {
185187 count -= 1;
186188 if (count == 1) {
187 try rebaseAddAddr(skip, writer);
189 try rebaseAddAddr(skip, bw);
188190 } else {
189 try rebaseTimesSkip(count, skip, writer);
191 try rebaseTimesSkip(count, skip, bw);
190192 }
191193 state = .start;
192194 offset = offset - (@sizeOf(u64) + skip);
......@@ -199,7 +201,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void {
199201 count += 1;
200202 offset += @sizeOf(u64) + skip;
201203 } else {
202 try rebaseTimesSkip(count, skip, writer);
204 try rebaseTimesSkip(count, skip, bw);
203205 state = .start;
204206 i -= 1;
205207 }
......@@ -210,68 +212,66 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void {
210212 switch (state) {
211213 .start => unreachable,
212214 .times => {
213 try rebaseTimes(count, writer);
215 try rebaseTimes(count, bw);
214216 },
215217 .times_skip => {
216 try rebaseTimesSkip(count, skip, writer);
218 try rebaseTimesSkip(count, skip, bw);
217219 },
218220 }
219221}
220222
221fn setTypePointer(writer: anytype) !void {
223fn setTypePointer(bw: *std.io.BufferedWriter) anyerror!void {
222224 log.debug(">>> set type: {d}", .{macho.REBASE_TYPE_POINTER});
223 try writer.writeByte(macho.REBASE_OPCODE_SET_TYPE_IMM | @as(u4, @truncate(macho.REBASE_TYPE_POINTER)));
225 try bw.writeByte(macho.REBASE_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.REBASE_TYPE_POINTER)));
224226}
225227
226fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void {
228fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) anyerror!void {
227229 log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset });
228 try writer.writeByte(macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id)));
229 try std.leb.writeUleb128(writer, offset);
230 try bw.writeByte(macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id)));
231 try bw.writeLeb128(offset);
230232}
231233
232fn rebaseAddAddr(addr: u64, writer: anytype) !void {
234fn rebaseAddAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void {
233235 log.debug(">>> rebase with add: {x}", .{addr});
234 try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB);
235 try std.leb.writeUleb128(writer, addr);
236 try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB);
237 try bw.writeLeb128(addr);
236238}
237239
238fn rebaseTimes(count: usize, writer: anytype) !void {
240fn rebaseTimes(count: usize, bw: *std.io.BufferedWriter) anyerror!void {
239241 log.debug(">>> rebase with count: {d}", .{count});
240242 if (count <= 0xf) {
241 try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_IMM_TIMES | @as(u4, @truncate(count)));
243 try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_IMM_TIMES | @as(u4, @truncate(count)));
242244 } else {
243 try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES);
244 try std.leb.writeUleb128(writer, count);
245 try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES);
246 try bw.writeLeb128(count);
245247 }
246248}
247249
248fn rebaseTimesSkip(count: usize, skip: u64, writer: anytype) !void {
250fn rebaseTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) anyerror!void {
249251 log.debug(">>> rebase with count: {d} and skip: {x}", .{ count, skip });
250 try writer.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB);
251 try std.leb.writeUleb128(writer, count);
252 try std.leb.writeUleb128(writer, skip);
252 try bw.writeByte(macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB);
253 try bw.writeLeb128(count);
254 try bw.writeLeb128(skip);
253255}
254256
255fn addAddr(addr: u64, writer: anytype) !void {
257fn addAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void {
256258 log.debug(">>> add: {x}", .{addr});
257 if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) {
258 const imm = @divExact(addr, @sizeOf(u64));
259 if (imm <= 0xf) {
260 try writer.writeByte(macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED | @as(u4, @truncate(imm)));
261 return;
262 }
263 }
264 try writer.writeByte(macho.REBASE_OPCODE_ADD_ADDR_ULEB);
265 try std.leb.writeUleb128(writer, addr);
259 if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| {
260 if (std.math.cast(u4, scaled)) |imm_scaled| return bw.writeByte(
261 macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED | imm_scaled,
262 );
263 } else |_| {}
264 try bw.writeByte(macho.REBASE_OPCODE_ADD_ADDR_ULEB);
265 try bw.writeLeb128(addr);
266266}
267267
268fn done(writer: anytype) !void {
268fn done(bw: *std.io.BufferedWriter) anyerror!void {
269269 log.debug(">>> done", .{});
270 try writer.writeByte(macho.REBASE_OPCODE_DONE);
270 try bw.writeByte(macho.REBASE_OPCODE_DONE);
271271}
272272
273pub fn write(rebase: Rebase, writer: anytype) !void {
274 try writer.writeAll(rebase.buffer.items);
273pub fn write(rebase: Rebase, bw: *std.io.BufferedWriter) anyerror!void {
274 try bw.writeAll(rebase.buffer.items);
275275}
276276
277277test "rebase - no entries" {
src/link/MachO/dyld_info/Trie.zig+32-35
......@@ -31,7 +31,7 @@
3131
3232/// The root node of the trie.
3333root: ?Node.Index = null,
34buffer: std.ArrayListUnmanaged(u8) = .empty,
34buffer: []u8 = &.{},
3535nodes: std.MultiArrayList(Node) = .{},
3636edges: std.ArrayListUnmanaged(Edge) = .empty,
3737
......@@ -123,7 +123,7 @@ pub fn updateSize(self: *Trie, macho_file: *MachO) !void {
123123
124124 try self.finalize(gpa);
125125
126 macho_file.dyld_info_cmd.export_size = mem.alignForward(u32, @intCast(self.buffer.items.len), @alignOf(u64));
126 macho_file.dyld_info_cmd.export_size = mem.alignForward(u32, @intCast(self.buffer.len), @alignOf(u64));
127127}
128128
129129/// Finalizes this trie for writing to a byte stream.
......@@ -164,9 +164,12 @@ fn finalize(self: *Trie, allocator: Allocator) !void {
164164 }
165165 }
166166
167 try self.buffer.ensureTotalCapacityPrecise(allocator, size);
167 assert(self.buffer.len == 0);
168 self.buffer = try allocator.alloc(u8, size);
169 var bw: std.io.BufferedWriter = undefined;
170 bw.initFixed(self.buffer);
168171 for (ordered_nodes.items) |node_index| {
169 try self.writeNode(node_index, self.buffer.writer(allocator));
172 try self.writeNode(node_index, &bw);
170173 }
171174}
172175
......@@ -181,17 +184,20 @@ const FinalizeNodeResult = struct {
181184
182185/// Updates offset of this node in the output byte stream.
183186fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult {
184 var stream = std.io.countingWriter(std.io.null_writer);
185 const writer = stream.writer();
187 var buf: [1024]u8 = undefined;
188 var bw: std.io.BufferedWriter = .{
189 .unbuffered_writer = .null,
190 .buffer = &buf,
191 };
186192 const slice = self.nodes.slice();
187193
188194 var node_size: u32 = 0;
189195 if (slice.items(.is_terminal)[node_index]) {
190196 const export_flags = slice.items(.export_flags)[node_index];
191197 const vmaddr_offset = slice.items(.vmaddr_offset)[node_index];
192 try leb.writeULEB128(writer, export_flags);
193 try leb.writeULEB128(writer, vmaddr_offset);
194 try leb.writeULEB128(writer, stream.bytes_written);
198 try bw.writeLeb128(export_flags);
199 try bw.writeLeb128(vmaddr_offset);
200 try bw.writeLeb128(bw.count);
195201 } else {
196202 node_size += 1; // 0x0 for non-terminal nodes
197203 }
......@@ -201,13 +207,13 @@ fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !Final
201207 const edge = &self.edges.items[edge_index];
202208 const next_node_offset = slice.items(.trie_offset)[edge.node];
203209 node_size += @intCast(edge.label.len + 1);
204 try leb.writeULEB128(writer, next_node_offset);
210 try bw.writeLeb128(next_node_offset);
205211 }
206212
207213 const trie_offset = slice.items(.trie_offset)[node_index];
208214 const updated = offset_in_trie != trie_offset;
209215 slice.items(.trie_offset)[node_index] = offset_in_trie;
210 node_size += @intCast(stream.bytes_written);
216 node_size += @intCast(bw.count);
211217
212218 return .{ .node_size = node_size, .updated = updated };
213219}
......@@ -223,12 +229,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {
223229 }
224230 self.nodes.deinit(allocator);
225231 self.edges.deinit(allocator);
226 self.buffer.deinit(allocator);
232 allocator.free(self.buffer);
227233}
228234
229pub fn write(self: Trie, writer: anytype) !void {
230 if (self.buffer.items.len == 0) return;
231 try writer.writeAll(self.buffer.items);
235pub fn write(self: Trie, bw: *std.io.BufferedWriter) anyerror!void {
236 try bw.writeAll(self.buffer);
232237}
233238
234239/// Writes this node to a byte stream.
......@@ -237,7 +242,7 @@ pub fn write(self: Trie, writer: anytype) !void {
237242/// iterate over `Trie.ordered_nodes` and call this method on each node.
238243/// This is one of the requirements of the MachO.
239244/// Panics if `finalize` was not called before calling this method.
240fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void {
245fn writeNode(self: *Trie, node_index: Node.Index, bw: *std.io.BufferedWriter) !void {
241246 const slice = self.nodes.slice();
242247 const edges = slice.items(.edges)[node_index];
243248 const is_terminal = slice.items(.is_terminal)[node_index];
......@@ -245,36 +250,28 @@ fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void {
245250 const vmaddr_offset = slice.items(.vmaddr_offset)[node_index];
246251
247252 if (is_terminal) {
248 // Terminal node info: encode export flags and vmaddr offset of this symbol.
249 var info_buf: [@sizeOf(u64) * 2]u8 = undefined;
250 var info_stream = std.io.fixedBufferStream(&info_buf);
253 const start = bw.count;
251254 // TODO Implement for special flags.
252255 assert(export_flags & macho.EXPORT_SYMBOL_FLAGS_REEXPORT == 0 and
253256 export_flags & macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER == 0);
254 try leb.writeULEB128(info_stream.writer(), export_flags);
255 try leb.writeULEB128(info_stream.writer(), vmaddr_offset);
256
257 // Terminal node info: encode export flags and vmaddr offset of this symbol.
258 try bw.writeLeb128(export_flags);
259 try bw.writeLeb128(vmaddr_offset);
257260 // Encode the size of the terminal node info.
258 var size_buf: [@sizeOf(u64)]u8 = undefined;
259 var size_stream = std.io.fixedBufferStream(&size_buf);
260 try leb.writeULEB128(size_stream.writer(), info_stream.pos);
261
262 // Now, write them to the output stream.
263 try writer.writeAll(size_buf[0..size_stream.pos]);
264 try writer.writeAll(info_buf[0..info_stream.pos]);
261 try bw.writeLeb128(bw.count - start);
265262 } else {
266263 // Non-terminal node is delimited by 0 byte.
267 try writer.writeByte(0);
264 try bw.writeByte(0);
268265 }
269 // Write number of edges (max legal number of edges is 256).
270 try writer.writeByte(@as(u8, @intCast(edges.items.len)));
266 // Write number of edges (max legal number of edges is 255).
267 try bw.writeByte(@intCast(edges.items.len));
271268
272269 for (edges.items) |edge_index| {
273270 const edge = self.edges.items[edge_index];
274271 // Write edge label and offset to next node in trie.
275 try writer.writeAll(edge.label);
276 try writer.writeByte(0);
277 try leb.writeULEB128(writer, slice.items(.trie_offset)[edge.node]);
272 try bw.writeAll(edge.label);
273 try bw.writeByte(0);
274 try bw.writeLeb128(slice.items(.trie_offset)[edge.node]);
278275 }
279276}
280277
src/link/MachO/dyld_info/bind.zig+151-184
......@@ -1,7 +1,7 @@
11pub const Entry = struct {
22 target: MachO.Ref,
33 offset: u64,
4 segment_id: u8,
4 segment_id: u4,
55 addend: i64,
66
77 pub fn lessThan(ctx: *MachO, entry: Entry, other: Entry) bool {
......@@ -20,14 +20,12 @@ pub const Bind = struct {
2020 entries: std.ArrayListUnmanaged(Entry) = .empty,
2121 buffer: std.ArrayListUnmanaged(u8) = .empty,
2222
23 const Self = @This();
24
25 pub fn deinit(self: *Self, gpa: Allocator) void {
26 self.entries.deinit(gpa);
27 self.buffer.deinit(gpa);
23 pub fn deinit(bind: *Bind, gpa: Allocator) void {
24 bind.entries.deinit(gpa);
25 bind.buffer.deinit(gpa);
2826 }
2927
30 pub fn updateSize(self: *Self, macho_file: *MachO) !void {
28 pub fn updateSize(bind: *Bind, macho_file: *MachO) !void {
3129 const tracy = trace(@src());
3230 defer tracy.end();
3331
......@@ -56,15 +54,12 @@ pub const Bind = struct {
5654 const addend = rel.addend + rel.getRelocAddend(cpu_arch);
5755 const sym = rel.getTargetSymbol(atom.*, macho_file);
5856 if (sym.isTlvInit(macho_file)) continue;
59 const entry = Entry{
57 if (sym.flags.import or (!(sym.flags.@"export" and sym.flags.weak) and sym.flags.interposable)) (try bind.entries.addOne(gpa)).* = .{
6058 .target = rel.getTargetSymbolRef(atom.*, macho_file),
6159 .offset = atom_addr + rel_offset - seg.vmaddr,
6260 .segment_id = seg_id,
6361 .addend = addend,
6462 };
65 if (sym.flags.import or (!(sym.flags.@"export" and sym.flags.weak) and sym.flags.interposable)) {
66 try self.entries.append(gpa, entry);
67 }
6863 }
6964 }
7065 }
......@@ -75,15 +70,12 @@ pub const Bind = struct {
7570 for (macho_file.got.symbols.items, 0..) |ref, idx| {
7671 const sym = ref.getSymbol(macho_file).?;
7772 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
78 const entry = Entry{
73 if (sym.flags.import or (sym.flags.@"export" and sym.flags.interposable and !sym.flags.weak)) (try bind.entries.addOne(gpa)).* = .{
7974 .target = ref,
8075 .offset = addr - seg.vmaddr,
8176 .segment_id = seg_id,
8277 .addend = 0,
8378 };
84 if (sym.flags.import or (sym.flags.@"export" and sym.flags.interposable and !sym.flags.weak)) {
85 try self.entries.append(gpa, entry);
86 }
8779 }
8880 }
8981
......@@ -94,15 +86,12 @@ pub const Bind = struct {
9486 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
9587 const sym = ref.getSymbol(macho_file).?;
9688 const addr = sect.addr + idx * @sizeOf(u64);
97 const bind_entry = Entry{
89 if (sym.flags.import and sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{
9890 .target = ref,
9991 .offset = addr - seg.vmaddr,
10092 .segment_id = seg_id,
10193 .addend = 0,
10294 };
103 if (sym.flags.import and sym.flags.weak) {
104 try self.entries.append(gpa, bind_entry);
105 }
10695 }
10796 }
10897
......@@ -113,49 +102,48 @@ pub const Bind = struct {
113102 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
114103 const sym = ref.getSymbol(macho_file).?;
115104 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
116 const entry = Entry{
105 if (sym.flags.import or (sym.flags.@"export" and sym.flags.interposable and !sym.flags.weak)) (try bind.entries.addOne(gpa)).* = .{
117106 .target = ref,
118107 .offset = addr - seg.vmaddr,
119108 .segment_id = seg_id,
120109 .addend = 0,
121110 };
122 if (sym.flags.import or (sym.flags.@"export" and sym.flags.interposable and !sym.flags.weak)) {
123 try self.entries.append(gpa, entry);
124 }
125111 }
126112 }
127113
128 try self.finalize(gpa, macho_file);
129 macho_file.dyld_info_cmd.bind_size = mem.alignForward(u32, @intCast(self.buffer.items.len), @alignOf(u64));
114 try bind.finalize(gpa, macho_file);
115 macho_file.dyld_info_cmd.bind_size = mem.alignForward(u32, @intCast(bind.buffer.items.len), @alignOf(u64));
130116 }
131117
132 fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void {
133 if (self.entries.items.len == 0) return;
118 fn finalize(bind: *Bind, gpa: Allocator, ctx: *MachO) !void {
119 if (bind.entries.items.len == 0) return;
134120
135 const writer = self.buffer.writer(gpa);
121 var aw: std.io.AllocatingWriter = undefined;
122 const bw = aw.fromArrayList(gpa, &bind.buffer);
123 defer bind.buffer = aw.toArrayList();
136124
137125 log.debug("bind opcodes", .{});
138126
139 std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan);
127 std.mem.sort(Entry, bind.entries.items, ctx, Entry.lessThan);
140128
141129 var start: usize = 0;
142130 var seg_id: ?u8 = null;
143 for (self.entries.items, 0..) |entry, i| {
131 for (bind.entries.items, 0..) |entry, i| {
144132 if (seg_id != null and seg_id.? == entry.segment_id) continue;
145 try finalizeSegment(self.entries.items[start..i], ctx, writer);
133 try finalizeSegment(bind.entries.items[start..i], ctx, bw);
146134 seg_id = entry.segment_id;
147135 start = i;
148136 }
149137
150 try finalizeSegment(self.entries.items[start..], ctx, writer);
151 try done(writer);
138 try finalizeSegment(bind.entries.items[start..], ctx, bw);
139 try done(bw);
152140 }
153141
154 fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: anytype) !void {
142 fn finalizeSegment(entries: []const Entry, ctx: *MachO, bw: *std.io.BufferedWriter) anyerror!void {
155143 if (entries.len == 0) return;
156144
157145 const seg_id = entries[0].segment_id;
158 try setSegmentOffset(seg_id, 0, writer);
146 try setSegmentOffset(seg_id, 0, bw);
159147
160148 var offset: u64 = 0;
161149 var addend: i64 = 0;
......@@ -175,15 +163,15 @@ pub const Bind = struct {
175163 if (target == null or !target.?.eql(current.target)) {
176164 switch (state) {
177165 .start => {},
178 .bind_single => try doBind(writer),
179 .bind_times_skip => try doBindTimesSkip(count, skip, writer),
166 .bind_single => try doBind(bw),
167 .bind_times_skip => try doBindTimesSkip(count, skip, bw),
180168 }
181169 state = .start;
182170 target = current.target;
183171
184172 const sym = current.target.getSymbol(ctx).?;
185173 const name = sym.getName(ctx);
186 const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
174 const flags: u4 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
187175 const ordinal: i16 = ord: {
188176 if (sym.flags.interposable) break :ord macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
189177 if (sym.flags.import) {
......@@ -195,13 +183,13 @@ pub const Bind = struct {
195183 break :ord macho.BIND_SPECIAL_DYLIB_SELF;
196184 };
197185
198 try setSymbol(name, flags, writer);
199 try setTypePointer(writer);
200 try setDylibOrdinal(ordinal, writer);
186 try setSymbol(name, flags, bw);
187 try setTypePointer(bw);
188 try setDylibOrdinal(ordinal, bw);
201189
202190 if (current.addend != addend) {
203191 addend = current.addend;
204 try setAddend(addend, writer);
192 try setAddend(addend, bw);
205193 }
206194 }
207195
......@@ -210,11 +198,11 @@ pub const Bind = struct {
210198 switch (state) {
211199 .start => {
212200 if (current.offset < offset) {
213 try addAddr(@bitCast(@as(i64, @intCast(current.offset)) - @as(i64, @intCast(offset))), writer);
201 try addAddr(@bitCast(@as(i64, @intCast(current.offset)) - @as(i64, @intCast(offset))), bw);
214202 offset = offset - (offset - current.offset);
215203 } else if (current.offset > offset) {
216204 const delta = current.offset - offset;
217 try addAddr(delta, writer);
205 try addAddr(delta, bw);
218206 offset += delta;
219207 }
220208 state = .bind_single;
......@@ -223,7 +211,7 @@ pub const Bind = struct {
223211 },
224212 .bind_single => {
225213 if (current.offset == offset) {
226 try doBind(writer);
214 try doBind(bw);
227215 state = .start;
228216 } else if (current.offset > offset) {
229217 const delta = current.offset - offset;
......@@ -237,9 +225,9 @@ pub const Bind = struct {
237225 if (current.offset < offset) {
238226 count -= 1;
239227 if (count == 1) {
240 try doBindAddAddr(skip, writer);
228 try doBindAddAddr(skip, bw);
241229 } else {
242 try doBindTimesSkip(count, skip, writer);
230 try doBindTimesSkip(count, skip, bw);
243231 }
244232 state = .start;
245233 offset = offset - (@sizeOf(u64) + skip);
......@@ -248,7 +236,7 @@ pub const Bind = struct {
248236 count += 1;
249237 offset += @sizeOf(u64) + skip;
250238 } else {
251 try doBindTimesSkip(count, skip, writer);
239 try doBindTimesSkip(count, skip, bw);
252240 state = .start;
253241 i -= 1;
254242 }
......@@ -258,13 +246,13 @@ pub const Bind = struct {
258246
259247 switch (state) {
260248 .start => unreachable,
261 .bind_single => try doBind(writer),
262 .bind_times_skip => try doBindTimesSkip(count, skip, writer),
249 .bind_single => try doBind(bw),
250 .bind_times_skip => try doBindTimesSkip(count, skip, bw),
263251 }
264252 }
265253
266 pub fn write(self: Self, writer: anytype) !void {
267 try writer.writeAll(self.buffer.items);
254 pub fn write(bind: Bind, bw: *std.io.BufferedWriter) anyerror!void {
255 try bw.writeAll(bind.buffer.items);
268256 }
269257};
270258
......@@ -272,14 +260,12 @@ pub const WeakBind = struct {
272260 entries: std.ArrayListUnmanaged(Entry) = .empty,
273261 buffer: std.ArrayListUnmanaged(u8) = .empty,
274262
275 const Self = @This();
276
277 pub fn deinit(self: *Self, gpa: Allocator) void {
278 self.entries.deinit(gpa);
279 self.buffer.deinit(gpa);
263 pub fn deinit(bind: *WeakBind, gpa: Allocator) void {
264 bind.entries.deinit(gpa);
265 bind.buffer.deinit(gpa);
280266 }
281267
282 pub fn updateSize(self: *Self, macho_file: *MachO) !void {
268 pub fn updateSize(bind: *WeakBind, macho_file: *MachO) !void {
283269 const tracy = trace(@src());
284270 defer tracy.end();
285271
......@@ -308,15 +294,12 @@ pub const WeakBind = struct {
308294 const addend = rel.addend + rel.getRelocAddend(cpu_arch);
309295 const sym = rel.getTargetSymbol(atom.*, macho_file);
310296 if (sym.isTlvInit(macho_file)) continue;
311 const entry = Entry{
297 if (!sym.isLocal() and sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{
312298 .target = rel.getTargetSymbolRef(atom.*, macho_file),
313299 .offset = atom_addr + rel_offset - seg.vmaddr,
314300 .segment_id = seg_id,
315301 .addend = addend,
316302 };
317 if (!sym.isLocal() and sym.flags.weak) {
318 try self.entries.append(gpa, entry);
319 }
320303 }
321304 }
322305 }
......@@ -327,15 +310,12 @@ pub const WeakBind = struct {
327310 for (macho_file.got.symbols.items, 0..) |ref, idx| {
328311 const sym = ref.getSymbol(macho_file).?;
329312 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
330 const entry = Entry{
313 if (sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{
331314 .target = ref,
332315 .offset = addr - seg.vmaddr,
333316 .segment_id = seg_id,
334317 .addend = 0,
335318 };
336 if (sym.flags.weak) {
337 try self.entries.append(gpa, entry);
338 }
339319 }
340320 }
341321
......@@ -347,15 +327,12 @@ pub const WeakBind = struct {
347327 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
348328 const sym = ref.getSymbol(macho_file).?;
349329 const addr = sect.addr + idx * @sizeOf(u64);
350 const bind_entry = Entry{
330 if (sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{
351331 .target = ref,
352332 .offset = addr - seg.vmaddr,
353333 .segment_id = seg_id,
354334 .addend = 0,
355335 };
356 if (sym.flags.weak) {
357 try self.entries.append(gpa, bind_entry);
358 }
359336 }
360337 }
361338
......@@ -366,49 +343,48 @@ pub const WeakBind = struct {
366343 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
367344 const sym = ref.getSymbol(macho_file).?;
368345 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
369 const entry = Entry{
346 if (sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{
370347 .target = ref,
371348 .offset = addr - seg.vmaddr,
372349 .segment_id = seg_id,
373350 .addend = 0,
374351 };
375 if (sym.flags.weak) {
376 try self.entries.append(gpa, entry);
377 }
378352 }
379353 }
380354
381 try self.finalize(gpa, macho_file);
382 macho_file.dyld_info_cmd.weak_bind_size = mem.alignForward(u32, @intCast(self.buffer.items.len), @alignOf(u64));
355 try bind.finalize(gpa, macho_file);
356 macho_file.dyld_info_cmd.weak_bind_size = mem.alignForward(u32, @intCast(bind.buffer.items.len), @alignOf(u64));
383357 }
384358
385 fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void {
386 if (self.entries.items.len == 0) return;
359 fn finalize(bind: *WeakBind, gpa: Allocator, ctx: *MachO) !void {
360 if (bind.entries.items.len == 0) return;
387361
388 const writer = self.buffer.writer(gpa);
362 var aw: std.io.AllocatingWriter = undefined;
363 const bw = aw.fromArrayList(gpa, &bind.buffer);
364 defer bind.buffer = aw.toArrayList();
389365
390366 log.debug("weak bind opcodes", .{});
391367
392 std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan);
368 std.mem.sort(Entry, bind.entries.items, ctx, Entry.lessThan);
393369
394370 var start: usize = 0;
395371 var seg_id: ?u8 = null;
396 for (self.entries.items, 0..) |entry, i| {
372 for (bind.entries.items, 0..) |entry, i| {
397373 if (seg_id != null and seg_id.? == entry.segment_id) continue;
398 try finalizeSegment(self.entries.items[start..i], ctx, writer);
374 try finalizeSegment(bind.entries.items[start..i], ctx, bw);
399375 seg_id = entry.segment_id;
400376 start = i;
401377 }
402378
403 try finalizeSegment(self.entries.items[start..], ctx, writer);
404 try done(writer);
379 try finalizeSegment(bind.entries.items[start..], ctx, bw);
380 try done(bw);
405381 }
406382
407 fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: anytype) !void {
383 fn finalizeSegment(entries: []const Entry, ctx: *MachO, bw: *std.io.BufferedWriter) anyerror!void {
408384 if (entries.len == 0) return;
409385
410386 const seg_id = entries[0].segment_id;
411 try setSegmentOffset(seg_id, 0, writer);
387 try setSegmentOffset(seg_id, 0, bw);
412388
413389 var offset: u64 = 0;
414390 var addend: i64 = 0;
......@@ -428,8 +404,8 @@ pub const WeakBind = struct {
428404 if (target == null or !target.?.eql(current.target)) {
429405 switch (state) {
430406 .start => {},
431 .bind_single => try doBind(writer),
432 .bind_times_skip => try doBindTimesSkip(count, skip, writer),
407 .bind_single => try doBind(bw),
408 .bind_times_skip => try doBindTimesSkip(count, skip, bw),
433409 }
434410 state = .start;
435411 target = current.target;
......@@ -438,12 +414,12 @@ pub const WeakBind = struct {
438414 const name = sym.getName(ctx);
439415 const flags: u8 = 0; // TODO NON_WEAK_DEFINITION
440416
441 try setSymbol(name, flags, writer);
442 try setTypePointer(writer);
417 try setSymbol(name, flags, bw);
418 try setTypePointer(bw);
443419
444420 if (current.addend != addend) {
445421 addend = current.addend;
446 try setAddend(addend, writer);
422 try setAddend(addend, bw);
447423 }
448424 }
449425
......@@ -452,11 +428,11 @@ pub const WeakBind = struct {
452428 switch (state) {
453429 .start => {
454430 if (current.offset < offset) {
455 try addAddr(@as(u64, @bitCast(@as(i64, @intCast(current.offset)) - @as(i64, @intCast(offset)))), writer);
431 try addAddr(@as(u64, @bitCast(@as(i64, @intCast(current.offset)) - @as(i64, @intCast(offset)))), bw);
456432 offset = offset - (offset - current.offset);
457433 } else if (current.offset > offset) {
458434 const delta = current.offset - offset;
459 try addAddr(delta, writer);
435 try addAddr(delta, bw);
460436 offset += delta;
461437 }
462438 state = .bind_single;
......@@ -465,7 +441,7 @@ pub const WeakBind = struct {
465441 },
466442 .bind_single => {
467443 if (current.offset == offset) {
468 try doBind(writer);
444 try doBind(bw);
469445 state = .start;
470446 } else if (current.offset > offset) {
471447 const delta = current.offset - offset;
......@@ -479,9 +455,9 @@ pub const WeakBind = struct {
479455 if (current.offset < offset) {
480456 count -= 1;
481457 if (count == 1) {
482 try doBindAddAddr(skip, writer);
458 try doBindAddAddr(skip, bw);
483459 } else {
484 try doBindTimesSkip(count, skip, writer);
460 try doBindTimesSkip(count, skip, bw);
485461 }
486462 state = .start;
487463 offset = offset - (@sizeOf(u64) + skip);
......@@ -490,7 +466,7 @@ pub const WeakBind = struct {
490466 count += 1;
491467 offset += @sizeOf(u64) + skip;
492468 } else {
493 try doBindTimesSkip(count, skip, writer);
469 try doBindTimesSkip(count, skip, bw);
494470 state = .start;
495471 i -= 1;
496472 }
......@@ -500,13 +476,13 @@ pub const WeakBind = struct {
500476
501477 switch (state) {
502478 .start => unreachable,
503 .bind_single => try doBind(writer),
504 .bind_times_skip => try doBindTimesSkip(count, skip, writer),
479 .bind_single => try doBind(bw),
480 .bind_times_skip => try doBindTimesSkip(count, skip, bw),
505481 }
506482 }
507483
508 pub fn write(self: Self, writer: anytype) !void {
509 try writer.writeAll(self.buffer.items);
484 pub fn write(bind: WeakBind, bw: *std.io.BufferedWriter) anyerror!void {
485 try bw.writeAll(bind.buffer.items);
510486 }
511487};
512488
......@@ -515,15 +491,13 @@ pub const LazyBind = struct {
515491 buffer: std.ArrayListUnmanaged(u8) = .empty,
516492 offsets: std.ArrayListUnmanaged(u32) = .empty,
517493
518 const Self = @This();
519
520 pub fn deinit(self: *Self, gpa: Allocator) void {
521 self.entries.deinit(gpa);
522 self.buffer.deinit(gpa);
523 self.offsets.deinit(gpa);
494 pub fn deinit(bind: *LazyBind, gpa: Allocator) void {
495 bind.entries.deinit(gpa);
496 bind.buffer.deinit(gpa);
497 bind.offsets.deinit(gpa);
524498 }
525499
526 pub fn updateSize(self: *Self, macho_file: *MachO) !void {
500 pub fn updateSize(bind: *LazyBind, macho_file: *MachO) !void {
527501 const tracy = trace(@src());
528502 defer tracy.end();
529503
......@@ -537,36 +511,35 @@ pub const LazyBind = struct {
537511 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
538512 const sym = ref.getSymbol(macho_file).?;
539513 const addr = sect.addr + idx * @sizeOf(u64);
540 const bind_entry = Entry{
514 if ((sym.flags.import and !sym.flags.weak) or (sym.flags.interposable and !sym.flags.weak)) (try bind.entries.addOne(gpa)).* = .{
541515 .target = ref,
542516 .offset = addr - seg.vmaddr,
543517 .segment_id = seg_id,
544518 .addend = 0,
545519 };
546 if ((sym.flags.import and !sym.flags.weak) or (sym.flags.interposable and !sym.flags.weak)) {
547 try self.entries.append(gpa, bind_entry);
548 }
549520 }
550521
551 try self.finalize(gpa, macho_file);
552 macho_file.dyld_info_cmd.lazy_bind_size = mem.alignForward(u32, @intCast(self.buffer.items.len), @alignOf(u64));
522 try bind.finalize(gpa, macho_file);
523 macho_file.dyld_info_cmd.lazy_bind_size = mem.alignForward(u32, @intCast(bind.buffer.items.len), @alignOf(u64));
553524 }
554525
555 fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void {
556 try self.offsets.ensureTotalCapacityPrecise(gpa, self.entries.items.len);
526 fn finalize(bind: *LazyBind, gpa: Allocator, ctx: *MachO) !void {
527 try bind.offsets.ensureTotalCapacityPrecise(gpa, bind.entries.items.len);
557528
558 const writer = self.buffer.writer(gpa);
529 var aw: std.io.AllocatingWriter = undefined;
530 const bw = aw.fromArrayList(gpa, &bind.buffer);
531 defer bind.buffer = aw.toArrayList();
559532
560533 log.debug("lazy bind opcodes", .{});
561534
562535 var addend: i64 = 0;
563536
564 for (self.entries.items) |entry| {
565 self.offsets.appendAssumeCapacity(@intCast(self.buffer.items.len));
537 for (bind.entries.items) |entry| {
538 bind.offsets.appendAssumeCapacity(@intCast(bind.buffer.items.len));
566539
567540 const sym = entry.target.getSymbol(ctx).?;
568541 const name = sym.getName(ctx);
569 const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
542 const flags: u4 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
570543 const ordinal: i16 = ord: {
571544 if (sym.flags.interposable) break :ord macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
572545 if (sym.flags.import) {
......@@ -578,109 +551,103 @@ pub const LazyBind = struct {
578551 break :ord macho.BIND_SPECIAL_DYLIB_SELF;
579552 };
580553
581 try setSegmentOffset(entry.segment_id, entry.offset, writer);
582 try setSymbol(name, flags, writer);
583 try setDylibOrdinal(ordinal, writer);
554 try setSegmentOffset(entry.segment_id, entry.offset, bw);
555 try setSymbol(name, flags, bw);
556 try setDylibOrdinal(ordinal, bw);
584557
585558 if (entry.addend != addend) {
586 try setAddend(entry.addend, writer);
559 try setAddend(entry.addend, bw);
587560 addend = entry.addend;
588561 }
589562
590 try doBind(writer);
591 try done(writer);
563 try doBind(bw);
564 try done(bw);
592565 }
593566 }
594567
595 pub fn write(self: Self, writer: anytype) !void {
596 try writer.writeAll(self.buffer.items);
568 pub fn write(bind: LazyBind, bw: *std.io.BufferedWriter) anyerror!void {
569 try bw.writeAll(bind.buffer.items);
597570 }
598571};
599572
600fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void {
573fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) anyerror!void {
601574 log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset });
602 try writer.writeByte(macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id)));
603 try std.leb.writeUleb128(writer, offset);
575 try bw.writeByte(macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segment_id);
576 try bw.writeLeb128(offset);
604577}
605578
606fn setSymbol(name: []const u8, flags: u8, writer: anytype) !void {
579fn setSymbol(name: []const u8, flags: u4, bw: *std.io.BufferedWriter) anyerror!void {
607580 log.debug(">>> set symbol: {s} with flags: {x}", .{ name, flags });
608 try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | @as(u4, @truncate(flags)));
609 try writer.writeAll(name);
610 try writer.writeByte(0);
581 try bw.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | flags);
582 try bw.writeAll(name);
583 try bw.writeByte(0);
611584}
612585
613fn setTypePointer(writer: anytype) !void {
586fn setTypePointer(bw: *std.io.BufferedWriter) anyerror!void {
614587 log.debug(">>> set type: {d}", .{macho.BIND_TYPE_POINTER});
615 try writer.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @as(u4, @truncate(macho.BIND_TYPE_POINTER)));
588 try bw.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @as(u4, @intCast(macho.BIND_TYPE_POINTER)));
616589}
617590
618fn setDylibOrdinal(ordinal: i16, writer: anytype) !void {
619 if (ordinal <= 0) {
620 switch (ordinal) {
621 macho.BIND_SPECIAL_DYLIB_SELF,
622 macho.BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE,
623 macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP,
624 => {},
625 else => unreachable, // Invalid dylib special binding
626 }
627 log.debug(">>> set dylib special: {d}", .{ordinal});
628 const cast = @as(u16, @bitCast(ordinal));
629 try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | @as(u4, @truncate(cast)));
630 } else {
631 const cast = @as(u16, @bitCast(ordinal));
632 log.debug(">>> set dylib ordinal: {d}", .{ordinal});
633 if (cast <= 0xf) {
634 try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | @as(u4, @truncate(cast)));
635 } else {
636 try writer.writeByte(macho.BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
637 try std.leb.writeUleb128(writer, cast);
638 }
591fn setDylibOrdinal(ordinal: i16, bw: *std.io.BufferedWriter) anyerror!void {
592 switch (ordinal) {
593 else => unreachable, // Invalid dylib special binding
594 macho.BIND_SPECIAL_DYLIB_SELF,
595 macho.BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE,
596 macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP,
597 => {
598 log.debug(">>> set dylib special: {d}", .{ordinal});
599 try bw.writeByte(macho.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | @as(u4, @bitCast(@as(i4, @intCast(ordinal)))));
600 },
601 1...std.math.maxInt(i16) => {
602 log.debug(">>> set dylib ordinal: {d}", .{ordinal});
603 if (std.math.cast(u4, ordinal)) |imm| {
604 try bw.writeByte(macho.BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | imm);
605 } else {
606 try bw.writeByte(macho.BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
607 try bw.writeUleb128(ordinal);
608 }
609 },
639610 }
640611}
641612
642fn setAddend(addend: i64, writer: anytype) !void {
613fn setAddend(addend: i64, bw: *std.io.BufferedWriter) anyerror!void {
643614 log.debug(">>> set addend: {x}", .{addend});
644 try writer.writeByte(macho.BIND_OPCODE_SET_ADDEND_SLEB);
645 try std.leb.writeIleb128(writer, addend);
615 try bw.writeByte(macho.BIND_OPCODE_SET_ADDEND_SLEB);
616 try bw.writeLeb128(addend);
646617}
647618
648fn doBind(writer: anytype) !void {
619fn doBind(bw: *std.io.BufferedWriter) anyerror!void {
649620 log.debug(">>> bind", .{});
650 try writer.writeByte(macho.BIND_OPCODE_DO_BIND);
621 try bw.writeByte(macho.BIND_OPCODE_DO_BIND);
651622}
652623
653fn doBindAddAddr(addr: u64, writer: anytype) !void {
624fn doBindAddAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void {
654625 log.debug(">>> bind with add: {x}", .{addr});
655 if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) {
656 const imm = @divExact(addr, @sizeOf(u64));
657 if (imm <= 0xf) {
658 try writer.writeByte(
659 macho.BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED | @as(u4, @truncate(imm)),
660 );
661 return;
662 }
663 }
664 try writer.writeByte(macho.BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB);
665 try std.leb.writeUleb128(writer, addr);
626 if (std.math.divExact(u64, addr, @sizeOf(u64))) |scaled| {
627 if (std.math.cast(u4, scaled)) |imm_scaled| return bw.writeByte(
628 macho.BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED | imm_scaled,
629 );
630 } else |_| {}
631 try bw.writeByte(macho.BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB);
632 try bw.writeLeb128(addr);
666633}
667634
668fn doBindTimesSkip(count: usize, skip: u64, writer: anytype) !void {
635fn doBindTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) anyerror!void {
669636 log.debug(">>> bind with count: {d} and skip: {x}", .{ count, skip });
670 try writer.writeByte(macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB);
671 try std.leb.writeUleb128(writer, count);
672 try std.leb.writeUleb128(writer, skip);
637 try bw.writeByte(macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB);
638 try bw.writeLeb128(count);
639 try bw.writeLeb128(skip);
673640}
674641
675fn addAddr(addr: u64, writer: anytype) !void {
642fn addAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void {
676643 log.debug(">>> add: {x}", .{addr});
677 try writer.writeByte(macho.BIND_OPCODE_ADD_ADDR_ULEB);
678 try std.leb.writeUleb128(writer, addr);
644 try bw.writeByte(macho.BIND_OPCODE_ADD_ADDR_ULEB);
645 try bw.writeLeb128(addr);
679646}
680647
681fn done(writer: anytype) !void {
648fn done(bw: *std.io.BufferedWriter) anyerror!void {
682649 log.debug(">>> done", .{});
683 try writer.writeByte(macho.BIND_OPCODE_DONE);
650 try bw.writeByte(macho.BIND_OPCODE_DONE);
684651}
685652
686653const assert = std.debug.assert;
src/link/MachO/eh_frame.zig+37-53
......@@ -12,36 +12,34 @@ pub const Cie = struct {
1212 const tracy = trace(@src());
1313 defer tracy.end();
1414
15 const data = cie.getData(macho_file);
16 const aug = std.mem.sliceTo(@as([*:0]const u8, @ptrCast(data.ptr + 9)), 0);
15 var br: std.io.BufferedReader = undefined;
16 br.initFixed(cie.getData(macho_file));
1717
18 try br.discard(9);
19 const aug = try br.takeSentinel(0);
1820 if (aug[0] != 'z') return; // TODO should we error out?
1921
20 var stream = std.io.fixedBufferStream(data[9 + aug.len + 1 ..]);
21 var creader = std.io.countingReader(stream.reader());
22 const reader = creader.reader();
23
24 _ = try leb.readUleb128(u64, reader); // code alignment factor
25 _ = try leb.readUleb128(u64, reader); // data alignment factor
26 _ = try leb.readUleb128(u64, reader); // return address register
27 _ = try leb.readUleb128(u64, reader); // augmentation data length
22 _ = try br.takeLeb128(u64); // code alignment factor
23 _ = try br.takeLeb128(u64); // data alignment factor
24 _ = try br.takeLeb128(u64); // return address register
25 _ = try br.takeLeb128(u64); // augmentation data length
2826
2927 for (aug[1..]) |ch| switch (ch) {
3028 'R' => {
31 const enc = try reader.readByte();
29 const enc = try br.takeByte();
3230 if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) {
3331 @panic("unexpected pointer encoding"); // TODO error
3432 }
3533 },
3634 'P' => {
37 const enc = try reader.readByte();
35 const enc = try br.takeByte();
3836 if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) {
3937 @panic("unexpected personality pointer encoding"); // TODO error
4038 }
41 _ = try reader.readInt(u32, .little); // personality pointer
39 _ = try br.takeInt(u32, .little); // personality pointer
4240 },
4341 'L' => {
44 const enc = try reader.readByte();
42 const enc = try br.takeByte();
4543 switch (enc & DW_EH_PE.type_mask) {
4644 DW_EH_PE.sdata4 => cie.lsda_size = .p32,
4745 DW_EH_PE.absptr => cie.lsda_size = .p64,
......@@ -106,20 +104,14 @@ pub const Cie = struct {
106104 macho_file: *MachO,
107105 };
108106
109 fn format2(
110 ctx: FormatContext,
111 comptime unused_fmt_string: []const u8,
112 options: std.fmt.FormatOptions,
113 writer: anytype,
114 ) !void {
107 fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
115108 _ = unused_fmt_string;
116 _ = options;
117109 const cie = ctx.cie;
118 try writer.print("@{x} : size({x})", .{
110 try bw.print("@{x} : size({x})", .{
119111 cie.offset,
120112 cie.getSize(),
121113 });
122 if (!cie.alive) try writer.writeAll(" : [*]");
114 if (!cie.alive) try bw.writeAll(" : [*]");
123115 }
124116
125117 pub const Index = u32;
......@@ -148,12 +140,17 @@ pub const Fde = struct {
148140 const tracy = trace(@src());
149141 defer tracy.end();
150142
151 const data = fde.getData(macho_file);
152143 const object = fde.getObject(macho_file);
153144 const sect = object.sections.items(.header)[object.eh_frame_sect_index.?];
154145
146 var br: std.io.BufferedReader = undefined;
147 br.initFixed(fde.getData(macho_file));
148
149 try br.discard(4);
150 const cie_ptr = try br.takeInt(u32, .little);
151 const pc_begin = try br.takeInt(i64, .little);
152
155153 // Parse target atom index
156 const pc_begin = std.mem.readInt(i64, data[8..][0..8], .little);
157154 const taddr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + 8)) + pc_begin);
158155 fde.atom = object.findAtom(taddr) orelse {
159156 try macho_file.reportParseError2(object.index, "{s},{s}: 0x{x}: invalid function reference in FDE", .{
......@@ -165,7 +162,6 @@ pub const Fde = struct {
165162 fde.atom_offset = @intCast(taddr - atom.getInputAddress(macho_file));
166163
167164 // Associate with a CIE
168 const cie_ptr = std.mem.readInt(u32, data[4..8], .little);
169165 const cie_offset = fde.offset + 4 - cie_ptr;
170166 const cie_index = for (object.cies.items, 0..) |cie, cie_index| {
171167 if (cie.offset == cie_offset) break @as(Cie.Index, @intCast(cie_index));
......@@ -183,14 +179,12 @@ pub const Fde = struct {
183179
184180 // Parse LSDA atom index if any
185181 if (cie.lsda_size) |lsda_size| {
186 var stream = std.io.fixedBufferStream(data[24..]);
187 var creader = std.io.countingReader(stream.reader());
188 const reader = creader.reader();
189 _ = try leb.readUleb128(u64, reader); // augmentation length
190 fde.lsda_ptr_offset = @intCast(creader.bytes_read + 24);
182 try br.discard(8);
183 _ = try br.takeLeb128(u64); // augmentation length
184 fde.lsda_ptr_offset = @intCast(br.seek);
191185 const lsda_ptr = switch (lsda_size) {
192 .p32 => try reader.readInt(i32, .little),
193 .p64 => try reader.readInt(i64, .little),
186 .p32 => try br.takeInt(i32, .little),
187 .p64 => try br.takeInt(i64, .little),
194188 };
195189 const lsda_addr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + fde.lsda_ptr_offset)) + lsda_ptr);
196190 fde.lsda = object.findAtom(lsda_addr) orelse {
......@@ -256,31 +250,24 @@ pub const Fde = struct {
256250 macho_file: *MachO,
257251 };
258252
259 fn format2(
260 ctx: FormatContext,
261 comptime unused_fmt_string: []const u8,
262 options: std.fmt.FormatOptions,
263 writer: anytype,
264 ) !void {
253 fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
265254 _ = unused_fmt_string;
266 _ = options;
267255 const fde = ctx.fde;
268256 const macho_file = ctx.macho_file;
269 try writer.print("@{x} : size({x}) : cie({d}) : {s}", .{
257 try bw.print("@{x} : size({x}) : cie({d}) : {s}", .{
270258 fde.offset,
271259 fde.getSize(),
272260 fde.cie,
273261 fde.getAtom(macho_file).getName(macho_file),
274262 });
275 if (!fde.alive) try writer.writeAll(" : [*]");
263 if (!fde.alive) try bw.writeAll(" : [*]");
276264 }
277265
278266 pub const Index = u32;
279267};
280268
281269pub const Iterator = struct {
282 data: []const u8,
283 pos: u32 = 0,
270 br: std.io.BufferedReader,
284271
285272 pub const Record = struct {
286273 tag: enum { fde, cie },
......@@ -289,21 +276,18 @@ pub const Iterator = struct {
289276 };
290277
291278 pub fn next(it: *Iterator) !?Record {
292 if (it.pos >= it.data.len) return null;
293
294 var stream = std.io.fixedBufferStream(it.data[it.pos..]);
295 const reader = stream.reader();
279 if (it.br.seek >= it.br.storageBuffer().len) return null;
296280
297 const size = try reader.readInt(u32, .little);
281 const size = try it.br.takeInt(u32, .little);
298282 if (size == 0xFFFFFFFF) @panic("DWARF CFI is 32bit on macOS");
299283
300 const id = try reader.readInt(u32, .little);
301 const record = Record{
284 const id = try it.br.takeInt(u32, .little);
285 const record: Record = .{
302286 .tag = if (id == 0) .cie else .fde,
303 .offset = it.pos,
287 .offset = @intCast(it.br.seek),
304288 .size = size,
305289 };
306 it.pos += size + 4;
290 try it.br.discard(size);
307291
308292 return record;
309293 }
src/link/MachO/file.zig+8-14
......@@ -14,19 +14,13 @@ pub const File = union(enum) {
1414 return .{ .data = file };
1515 }
1616
17 fn formatPath(
18 file: File,
19 comptime unused_fmt_string: []const u8,
20 options: std.fmt.FormatOptions,
21 writer: anytype,
22 ) !void {
17 fn formatPath(file: File, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void {
2318 _ = unused_fmt_string;
24 _ = options;
2519 switch (file) {
26 .zig_object => |zo| try writer.writeAll(zo.basename),
27 .internal => try writer.writeAll("internal"),
28 .object => |x| try writer.print("{}", .{x.fmtPath()}),
29 .dylib => |dl| try writer.print("{}", .{@as(Path, dl.path)}),
20 .zig_object => |zo| try bw.writeAll(zo.basename),
21 .internal => try bw.writeAll("internal"),
22 .object => |x| try bw.print("{f}", .{x.fmtPath()}),
23 .dylib => |dl| try bw.print("{f}", .{@as(Path, dl.path)}),
3024 }
3125 }
3226
......@@ -328,11 +322,11 @@ pub const File = union(enum) {
328322 };
329323 }
330324
331 pub fn writeAr(file: File, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void {
325 pub fn writeAr(file: File, bw: *std.io.BufferedWriter, ar_format: Archive.Format, macho_file: *MachO) anyerror!void {
332326 return switch (file) {
333327 .dylib, .internal => unreachable,
334 .zig_object => |x| x.writeAr(ar_format, writer),
335 .object => |x| x.writeAr(ar_format, macho_file, writer),
328 .zig_object => |x| x.writeAr(bw, ar_format),
329 .object => |x| x.writeAr(bw, ar_format, macho_file),
336330 };
337331 }
338332
src/link/MachO/load_commands.zig+21-30
......@@ -180,23 +180,20 @@ pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 {
180180 return offset;
181181}
182182
183pub fn writeDylinkerLC(writer: anytype) !void {
183pub fn writeDylinkerLC(bw: *std.io.BufferedWriter) anyerror!void {
184184 const name_len = mem.sliceTo(default_dyld_path, 0).len;
185185 const cmdsize = @as(u32, @intCast(mem.alignForward(
186186 u64,
187187 @sizeOf(macho.dylinker_command) + name_len,
188188 @sizeOf(u64),
189189 )));
190 try writer.writeStruct(macho.dylinker_command{
190 try bw.writeStruct(macho.dylinker_command{
191191 .cmd = .LOAD_DYLINKER,
192192 .cmdsize = cmdsize,
193193 .name = @sizeOf(macho.dylinker_command),
194194 });
195 try writer.writeAll(mem.sliceTo(default_dyld_path, 0));
196 const padding = cmdsize - @sizeOf(macho.dylinker_command) - name_len;
197 if (padding > 0) {
198 try writer.writeByteNTimes(0, padding);
199 }
195 try bw.writeAll(mem.sliceTo(default_dyld_path, 0));
196 try bw.splatByteAll(0, cmdsize - @sizeOf(macho.dylinker_command) - name_len);
200197}
201198
202199const WriteDylibLCCtx = struct {
......@@ -207,14 +204,14 @@ const WriteDylibLCCtx = struct {
207204 compatibility_version: u32 = 0x10000,
208205};
209206
210pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void {
207pub fn writeDylibLC(ctx: WriteDylibLCCtx, bw: *std.io.BufferedWriter) !void {
211208 const name_len = ctx.name.len + 1;
212 const cmdsize = @as(u32, @intCast(mem.alignForward(
209 const cmdsize: u32 = @intCast(mem.alignForward(
213210 u64,
214211 @sizeOf(macho.dylib_command) + name_len,
215212 @sizeOf(u64),
216 )));
217 try writer.writeStruct(macho.dylib_command{
213 ));
214 try bw.writeStruct(macho.dylib_command{
218215 .cmd = ctx.cmd,
219216 .cmdsize = cmdsize,
220217 .dylib = .{
......@@ -224,12 +221,9 @@ pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void {
224221 .compatibility_version = ctx.compatibility_version,
225222 },
226223 });
227 try writer.writeAll(ctx.name);
228 try writer.writeByte(0);
229 const padding = cmdsize - @sizeOf(macho.dylib_command) - name_len;
230 if (padding > 0) {
231 try writer.writeByteNTimes(0, padding);
232 }
224 try bw.writeAll(ctx.name);
225 try bw.writeByte(0);
226 try bw.splatByteAll(0, cmdsize - @sizeOf(macho.dylib_command) - name_len);
233227}
234228
235229pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void {
......@@ -258,26 +252,23 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void {
258252 }, writer);
259253}
260254
261pub fn writeRpathLC(rpath: []const u8, writer: anytype) !void {
255pub fn writeRpathLC(bw: *std.io.BufferedWriter, rpath: []const u8) !void {
262256 const rpath_len = rpath.len + 1;
263257 const cmdsize = @as(u32, @intCast(mem.alignForward(
264258 u64,
265259 @sizeOf(macho.rpath_command) + rpath_len,
266260 @sizeOf(u64),
267261 )));
268 try writer.writeStruct(macho.rpath_command{
262 try bw.writeStruct(macho.rpath_command{
269263 .cmdsize = cmdsize,
270264 .path = @sizeOf(macho.rpath_command),
271265 });
272 try writer.writeAll(rpath);
273 try writer.writeByte(0);
274 const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len;
275 if (padding > 0) {
276 try writer.writeByteNTimes(0, padding);
277 }
266 try bw.writeAll(rpath);
267 try bw.writeByte(0);
268 try bw.splatByteAll(0, cmdsize - @sizeOf(macho.rpath_command) - rpath_len);
278269}
279270
280pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void {
271pub fn writeVersionMinLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) anyerror!void {
281272 const cmd: macho.LC = switch (platform.os_tag) {
282273 .macos => .VERSION_MIN_MACOSX,
283274 .ios => .VERSION_MIN_IPHONEOS,
......@@ -285,7 +276,7 @@ pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVer
285276 .watchos => .VERSION_MIN_WATCHOS,
286277 else => unreachable,
287278 };
288 try writer.writeAll(mem.asBytes(&macho.version_min_command{
279 try bw.writeAll(mem.asBytes(&macho.version_min_command{
289280 .cmd = cmd,
290281 .version = platform.toAppleVersion(),
291282 .sdk = if (sdk_version) |ver|
......@@ -295,9 +286,9 @@ pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVer
295286 }));
296287}
297288
298pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void {
289pub fn writeBuildVersionLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) anyerror!void {
299290 const cmdsize = @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);
300 try writer.writeStruct(macho.build_version_command{
291 try bw.writeStruct(macho.build_version_command{
301292 .cmdsize = cmdsize,
302293 .platform = platform.toApplePlatform(),
303294 .minos = platform.toAppleVersion(),
......@@ -307,7 +298,7 @@ pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticV
307298 platform.toAppleVersion(),
308299 .ntools = 1,
309300 });
310 try writer.writeAll(mem.asBytes(&macho.build_tool_version{
301 try bw.writeAll(mem.asBytes(&macho.build_tool_version{
311302 .tool = .ZIG,
312303 .version = 0x0,
313304 }));
src/link/MachO/relocatable.zig+33-58
......@@ -20,13 +20,13 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
2020 // the *only* input file over.
2121 const path = positionals.items[0].path().?;
2222 const in_file = path.root_dir.handle.openFile(path.sub_path, .{}) catch |err|
23 return diags.fail("failed to open {}: {s}", .{ path, @errorName(err) });
23 return diags.fail("failed to open {f}: {s}", .{ path, @errorName(err) });
2424 const stat = in_file.stat() catch |err|
25 return diags.fail("failed to stat {}: {s}", .{ path, @errorName(err) });
25 return diags.fail("failed to stat {f}: {s}", .{ path, @errorName(err) });
2626 const amt = in_file.copyRangeAll(0, macho_file.base.file.?, 0, stat.size) catch |err|
27 return diags.fail("failed to copy range of file {}: {s}", .{ path, @errorName(err) });
27 return diags.fail("failed to copy range of file {f}: {s}", .{ path, @errorName(err) });
2828 if (amt != stat.size)
29 return diags.fail("unexpected short write in copy range of file {}", .{path});
29 return diags.fail("unexpected short write in copy range of file {f}", .{path});
3030 return;
3131 }
3232
......@@ -62,12 +62,12 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
6262 allocateSegment(macho_file);
6363
6464 if (build_options.enable_logging) {
65 state_log.debug("{}", .{macho_file.dumpState()});
65 state_log.debug("{f}", .{macho_file.dumpState()});
6666 }
6767
6868 try writeSections(macho_file);
6969 sortRelocs(macho_file);
70 try writeSectionsToFile(macho_file);
70 writeSectionsToFile(macho_file) catch |err| return @errorCast(err);
7171
7272 // In order to please Apple ld (and possibly other MachO linkers in the wild),
7373 // we will now sanitize segment names of Zig-specific segments.
......@@ -126,12 +126,12 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
126126 allocateSegment(macho_file);
127127
128128 if (build_options.enable_logging) {
129 state_log.debug("{}", .{macho_file.dumpState()});
129 state_log.debug("{f}", .{macho_file.dumpState()});
130130 }
131131
132132 try writeSections(macho_file);
133133 sortRelocs(macho_file);
134 try writeSectionsToFile(macho_file);
134 writeSectionsToFile(macho_file) catch |err| return @errorCast(err);
135135
136136 // In order to please Apple ld (and possibly other MachO linkers in the wild),
137137 // we will now sanitize segment names of Zig-specific segments.
......@@ -202,38 +202,32 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
202202 };
203203
204204 if (build_options.enable_logging) {
205 state_log.debug("ar_symtab\n{}\n", .{ar_symtab.fmt(macho_file)});
205 state_log.debug("ar_symtab\n{f}\n", .{ar_symtab.fmt(macho_file)});
206206 }
207207
208 var buffer = std.ArrayList(u8).init(gpa);
209 defer buffer.deinit();
210 try buffer.ensureTotalCapacityPrecise(total_size);
211 const writer = buffer.writer();
208 var bw: std.io.BufferedWriter = undefined;
209 bw.initFixed(try gpa.alloc(u8, total_size));
210 defer gpa.free(bw.buffer);
212211
213212 // Write magic
214 try writer.writeAll(Archive.ARMAG);
213 bw.writeAll(Archive.ARMAG) catch unreachable;
215214
216215 // Write symtab
217 ar_symtab.write(format, macho_file, writer) catch |err| switch (err) {
218 error.OutOfMemory => return error.OutOfMemory,
216 ar_symtab.write(&bw, format, macho_file) catch |err| switch (err) {
217 error.OutOfMemory => unreachable,
219218 else => |e| return diags.fail("failed to write archive symbol table: {s}", .{@errorName(e)}),
220219 };
221220
222221 // Write object files
223222 for (files.items) |index| {
224 const aligned = mem.alignForward(usize, buffer.items.len, 2);
225 const padding = aligned - buffer.items.len;
226 if (padding > 0) {
227 try writer.writeByteNTimes(0, padding);
228 }
229 macho_file.getFile(index).?.writeAr(format, macho_file, writer) catch |err|
223 bw.splatByteAll(0, mem.alignForward(usize, bw.end, 2) - bw.end) catch unreachable;
224 macho_file.getFile(index).?.writeAr(&bw, format, macho_file) catch |err|
230225 return diags.fail("failed to write archive: {s}", .{@errorName(err)});
231226 }
232227
233 assert(buffer.items.len == total_size);
234
235 try macho_file.setEndPos(total_size);
236 try macho_file.pwriteAll(buffer.items, 0);
228 assert(bw.end == bw.buffer.len);
229 try macho_file.setEndPos(bw.end);
230 try macho_file.pwriteAll(bw.buffer, 0);
237231
238232 if (diags.hasErrors()) return error.LinkFailure;
239233}
......@@ -689,12 +683,9 @@ fn writeSectionsToFile(macho_file: *MachO) !void {
689683
690684fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struct { usize, usize } {
691685 const gpa = macho_file.base.comp.gpa;
692 const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file);
693 const buffer = try gpa.alloc(u8, needed_size);
694 defer gpa.free(buffer);
695
696 var stream = std.io.fixedBufferStream(buffer);
697 const writer = stream.writer();
686 var bw: std.io.BufferedWriter = undefined;
687 bw.initFixed(try gpa.alloc(u8, load_commands.calcLoadCommandsSizeObject(macho_file)));
688 defer gpa.free(bw.buffer);
698689
699690 var ncmds: usize = 0;
700691
......@@ -702,47 +693,31 @@ fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struc
702693 {
703694 assert(macho_file.segments.items.len == 1);
704695 const seg = macho_file.segments.items[0];
705 writer.writeStruct(seg) catch |err| switch (err) {
706 error.NoSpaceLeft => unreachable,
707 };
696 bw.writeStruct(seg) catch unreachable;
708697 for (macho_file.sections.items(.header)) |header| {
709 writer.writeStruct(header) catch |err| switch (err) {
710 error.NoSpaceLeft => unreachable,
711 };
698 bw.writeStruct(header) catch unreachable;
712699 }
713700 ncmds += 1;
714701 }
715702
716 writer.writeStruct(macho_file.data_in_code_cmd) catch |err| switch (err) {
717 error.NoSpaceLeft => unreachable,
718 };
703 bw.writeStruct(macho_file.data_in_code_cmd) catch unreachable;
719704 ncmds += 1;
720 writer.writeStruct(macho_file.symtab_cmd) catch |err| switch (err) {
721 error.NoSpaceLeft => unreachable,
722 };
705 bw.writeStruct(macho_file.symtab_cmd) catch unreachable;
723706 ncmds += 1;
724 writer.writeStruct(macho_file.dysymtab_cmd) catch |err| switch (err) {
725 error.NoSpaceLeft => unreachable,
726 };
707 bw.writeStruct(macho_file.dysymtab_cmd) catch unreachable;
727708 ncmds += 1;
728709
729710 if (macho_file.platform.isBuildVersionCompatible()) {
730 load_commands.writeBuildVersionLC(macho_file.platform, macho_file.sdk_version, writer) catch |err| switch (err) {
731 error.NoSpaceLeft => unreachable,
732 };
711 load_commands.writeBuildVersionLC(&bw, macho_file.platform, macho_file.sdk_version) catch unreachable;
733712 ncmds += 1;
734713 } else {
735 load_commands.writeVersionMinLC(macho_file.platform, macho_file.sdk_version, writer) catch |err| switch (err) {
736 error.NoSpaceLeft => unreachable,
737 };
714 load_commands.writeVersionMinLC(&bw, macho_file.platform, macho_file.sdk_version) catch unreachable;
738715 ncmds += 1;
739716 }
740717
741 assert(stream.pos == needed_size);
742
743 try macho_file.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
744
745 return .{ ncmds, buffer.len };
718 assert(bw.end == bw.buffer.len);
719 try macho_file.pwriteAll(bw.buffer, @sizeOf(macho.mach_header_64));
720 return .{ ncmds, bw.end };
746721}
747722
748723fn writeHeader(macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void {
src/link/MachO/synthetic.zig+62-70
......@@ -27,13 +27,13 @@ pub const GotSection = struct {
2727 return got.symbols.items.len * @sizeOf(u64);
2828 }
2929
30 pub fn write(got: GotSection, macho_file: *MachO, writer: anytype) !void {
30 pub fn write(got: GotSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
3131 const tracy = trace(@src());
3232 defer tracy.end();
3333 for (got.symbols.items) |ref| {
3434 const sym = ref.getSymbol(macho_file).?;
3535 const value = if (sym.flags.import) @as(u64, 0) else sym.getAddress(.{}, macho_file);
36 try writer.writeInt(u64, value, .little);
36 try bw.writeInt(u64, value, .little);
3737 }
3838 }
3939
......@@ -48,15 +48,13 @@ pub const GotSection = struct {
4848
4949 pub fn format2(
5050 ctx: FormatCtx,
51 bw: *std.io.BufferedWriter,
5152 comptime unused_fmt_string: []const u8,
52 options: std.fmt.FormatOptions,
53 writer: anytype,
5453 ) !void {
55 _ = options;
5654 _ = unused_fmt_string;
5755 for (ctx.got.symbols.items, 0..) |ref, i| {
5856 const symbol = ref.getSymbol(ctx.macho_file).?;
59 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
57 try bw.print(" {d}@0x{x} => {f}@0x{x} ({s})\n", .{
6058 i,
6159 symbol.getGotAddress(ctx.macho_file),
6260 ref,
......@@ -96,7 +94,7 @@ pub const StubsSection = struct {
9694 return stubs.symbols.items.len * header.reserved2;
9795 }
9896
99 pub fn write(stubs: StubsSection, macho_file: *MachO, writer: anytype) !void {
97 pub fn write(stubs: StubsSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
10098 const tracy = trace(@src());
10199 defer tracy.end();
102100 const cpu_arch = macho_file.getTarget().cpu.arch;
......@@ -108,20 +106,20 @@ pub const StubsSection = struct {
108106 const target = laptr_sect.addr + idx * @sizeOf(u64);
109107 switch (cpu_arch) {
110108 .x86_64 => {
111 try writer.writeAll(&.{ 0xff, 0x25 });
112 try writer.writeInt(i32, @intCast(target - source - 2 - 4), .little);
109 try bw.writeAll(&.{ 0xff, 0x25 });
110 try bw.writeInt(i32, @intCast(target - source - 2 - 4), .little);
113111 },
114112 .aarch64 => {
115113 // TODO relax if possible
116114 const pages = try aarch64.calcNumberOfPages(@intCast(source), @intCast(target));
117 try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
115 try bw.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
118116 const off = try math.divExact(u12, @truncate(target), 8);
119 try writer.writeInt(
117 try bw.writeInt(
120118 u32,
121119 aarch64.Instruction.ldr(.x16, .x16, aarch64.Instruction.LoadStoreOffset.imm(off)).toU32(),
122120 .little,
123121 );
124 try writer.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
122 try bw.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
125123 },
126124 else => unreachable,
127125 }
......@@ -139,15 +137,13 @@ pub const StubsSection = struct {
139137
140138 pub fn format2(
141139 ctx: FormatCtx,
140 bw: *std.io.BufferedWriter,
142141 comptime unused_fmt_string: []const u8,
143 options: std.fmt.FormatOptions,
144 writer: anytype,
145142 ) !void {
146 _ = options;
147143 _ = unused_fmt_string;
148144 for (ctx.stubs.symbols.items, 0..) |ref, i| {
149145 const symbol = ref.getSymbol(ctx.macho_file).?;
150 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
146 try bw.print(" {d}@0x{x} => {f}@0x{x} ({s})\n", .{
151147 i,
152148 symbol.getStubsAddress(ctx.macho_file),
153149 ref,
......@@ -189,11 +185,11 @@ pub const StubsHelperSection = struct {
189185 return s;
190186 }
191187
192 pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void {
188 pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
193189 const tracy = trace(@src());
194190 defer tracy.end();
195191
196 try stubs_helper.writePreamble(macho_file, writer);
192 try stubs_helper.writePreamble(macho_file, bw);
197193
198194 const cpu_arch = macho_file.getTarget().cpu.arch;
199195 const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?];
......@@ -209,24 +205,24 @@ pub const StubsHelperSection = struct {
209205 const target: i64 = @intCast(sect.addr);
210206 switch (cpu_arch) {
211207 .x86_64 => {
212 try writer.writeByte(0x68);
213 try writer.writeInt(u32, offset, .little);
214 try writer.writeByte(0xe9);
215 try writer.writeInt(i32, @intCast(target - source - 6 - 4), .little);
208 try bw.writeByte(0x68);
209 try bw.writeInt(u32, offset, .little);
210 try bw.writeByte(0xe9);
211 try bw.writeInt(i32, @intCast(target - source - 6 - 4), .little);
216212 },
217213 .aarch64 => {
218214 const literal = blk: {
219215 const div_res = try std.math.divExact(u64, entry_size - @sizeOf(u32), 4);
220216 break :blk std.math.cast(u18, div_res) orelse return error.Overflow;
221217 };
222 try writer.writeInt(u32, aarch64.Instruction.ldrLiteral(
218 try bw.writeInt(u32, aarch64.Instruction.ldrLiteral(
223219 .w16,
224220 literal,
225221 ).toU32(), .little);
226222 const disp = math.cast(i28, @as(i64, @intCast(target)) - @as(i64, @intCast(source + 4))) orelse
227223 return error.Overflow;
228 try writer.writeInt(u32, aarch64.Instruction.b(disp).toU32(), .little);
229 try writer.writeAll(&.{ 0x0, 0x0, 0x0, 0x0 });
224 try bw.writeInt(u32, aarch64.Instruction.b(disp).toU32(), .little);
225 try bw.writeAll(&.{ 0x0, 0x0, 0x0, 0x0 });
230226 },
231227 else => unreachable,
232228 }
......@@ -234,7 +230,7 @@ pub const StubsHelperSection = struct {
234230 }
235231 }
236232
237 fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void {
233 fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
238234 _ = stubs_helper;
239235 const obj = macho_file.getInternalObject().?;
240236 const cpu_arch = macho_file.getTarget().cpu.arch;
......@@ -249,21 +245,21 @@ pub const StubsHelperSection = struct {
249245 };
250246 switch (cpu_arch) {
251247 .x86_64 => {
252 try writer.writeAll(&.{ 0x4c, 0x8d, 0x1d });
253 try writer.writeInt(i32, @intCast(dyld_private_addr - sect.addr - 3 - 4), .little);
254 try writer.writeAll(&.{ 0x41, 0x53, 0xff, 0x25 });
255 try writer.writeInt(i32, @intCast(dyld_stub_binder_addr - sect.addr - 11 - 4), .little);
256 try writer.writeByte(0x90);
248 try bw.writeAll(&.{ 0x4c, 0x8d, 0x1d });
249 try bw.writeInt(i32, @intCast(dyld_private_addr - sect.addr - 3 - 4), .little);
250 try bw.writeAll(&.{ 0x41, 0x53, 0xff, 0x25 });
251 try bw.writeInt(i32, @intCast(dyld_stub_binder_addr - sect.addr - 11 - 4), .little);
252 try bw.writeByte(0x90);
257253 },
258254 .aarch64 => {
259255 {
260256 // TODO relax if possible
261257 const pages = try aarch64.calcNumberOfPages(@intCast(sect.addr), @intCast(dyld_private_addr));
262 try writer.writeInt(u32, aarch64.Instruction.adrp(.x17, pages).toU32(), .little);
258 try bw.writeInt(u32, aarch64.Instruction.adrp(.x17, pages).toU32(), .little);
263259 const off: u12 = @truncate(dyld_private_addr);
264 try writer.writeInt(u32, aarch64.Instruction.add(.x17, .x17, off, false).toU32(), .little);
260 try bw.writeInt(u32, aarch64.Instruction.add(.x17, .x17, off, false).toU32(), .little);
265261 }
266 try writer.writeInt(u32, aarch64.Instruction.stp(
262 try bw.writeInt(u32, aarch64.Instruction.stp(
267263 .x16,
268264 .x17,
269265 aarch64.Register.sp,
......@@ -272,15 +268,15 @@ pub const StubsHelperSection = struct {
272268 {
273269 // TODO relax if possible
274270 const pages = try aarch64.calcNumberOfPages(@intCast(sect.addr + 12), @intCast(dyld_stub_binder_addr));
275 try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
271 try bw.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
276272 const off = try math.divExact(u12, @truncate(dyld_stub_binder_addr), 8);
277 try writer.writeInt(u32, aarch64.Instruction.ldr(
273 try bw.writeInt(u32, aarch64.Instruction.ldr(
278274 .x16,
279275 .x16,
280276 aarch64.Instruction.LoadStoreOffset.imm(off),
281277 ).toU32(), .little);
282278 }
283 try writer.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
279 try bw.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
284280 },
285281 else => unreachable,
286282 }
......@@ -293,7 +289,7 @@ pub const LaSymbolPtrSection = struct {
293289 return macho_file.stubs.symbols.items.len * @sizeOf(u64);
294290 }
295291
296 pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, writer: anytype) !void {
292 pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
297293 const tracy = trace(@src());
298294 defer tracy.end();
299295 _ = laptr;
......@@ -304,12 +300,12 @@ pub const LaSymbolPtrSection = struct {
304300 const sym = ref.getSymbol(macho_file).?;
305301 if (sym.flags.weak) {
306302 const value = sym.getAddress(.{ .stubs = false }, macho_file);
307 try writer.writeInt(u64, @intCast(value), .little);
303 try bw.writeInt(u64, @intCast(value), .little);
308304 } else {
309305 const value = sect.addr + StubsHelperSection.preambleSize(cpu_arch) +
310306 StubsHelperSection.entrySize(cpu_arch) * stub_helper_idx;
311307 stub_helper_idx += 1;
312 try writer.writeInt(u64, @intCast(value), .little);
308 try bw.writeInt(u64, @intCast(value), .little);
313309 }
314310 }
315311 }
......@@ -343,16 +339,16 @@ pub const TlvPtrSection = struct {
343339 return tlv.symbols.items.len * @sizeOf(u64);
344340 }
345341
346 pub fn write(tlv: TlvPtrSection, macho_file: *MachO, writer: anytype) !void {
342 pub fn write(tlv: TlvPtrSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
347343 const tracy = trace(@src());
348344 defer tracy.end();
349345
350346 for (tlv.symbols.items) |ref| {
351347 const sym = ref.getSymbol(macho_file).?;
352348 if (sym.flags.import) {
353 try writer.writeInt(u64, 0, .little);
349 try bw.writeInt(u64, 0, .little);
354350 } else {
355 try writer.writeInt(u64, sym.getAddress(.{}, macho_file), .little);
351 try bw.writeInt(u64, sym.getAddress(.{}, macho_file), .little);
356352 }
357353 }
358354 }
......@@ -368,15 +364,13 @@ pub const TlvPtrSection = struct {
368364
369365 pub fn format2(
370366 ctx: FormatCtx,
367 bw: *std.io.BufferedWriter,
371368 comptime unused_fmt_string: []const u8,
372 options: std.fmt.FormatOptions,
373 writer: anytype,
374369 ) !void {
375 _ = options;
376370 _ = unused_fmt_string;
377371 for (ctx.tlv.symbols.items, 0..) |ref, i| {
378372 const symbol = ref.getSymbol(ctx.macho_file).?;
379 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
373 try bw.print(" {d}@0x{x} => {f}@0x{x} ({s})\n", .{
380374 i,
381375 symbol.getTlvPtrAddress(ctx.macho_file),
382376 ref,
......@@ -421,7 +415,7 @@ pub const ObjcStubsSection = struct {
421415 return objc.symbols.items.len * entrySize(macho_file.getTarget().cpu.arch);
422416 }
423417
424 pub fn write(objc: ObjcStubsSection, macho_file: *MachO, writer: anytype) !void {
418 pub fn write(objc: ObjcStubsSection, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
425419 const tracy = trace(@src());
426420 defer tracy.end();
427421
......@@ -432,18 +426,18 @@ pub const ObjcStubsSection = struct {
432426 const addr = objc.getAddress(@intCast(idx), macho_file);
433427 switch (macho_file.getTarget().cpu.arch) {
434428 .x86_64 => {
435 try writer.writeAll(&.{ 0x48, 0x8b, 0x35 });
429 try bw.writeAll(&.{ 0x48, 0x8b, 0x35 });
436430 {
437431 const target = sym.getObjcSelrefsAddress(macho_file);
438432 const source = addr;
439 try writer.writeInt(i32, @intCast(target - source - 3 - 4), .little);
433 try bw.writeInt(i32, @intCast(target - source - 3 - 4), .little);
440434 }
441 try writer.writeAll(&.{ 0xff, 0x25 });
435 try bw.writeAll(&.{ 0xff, 0x25 });
442436 {
443437 const target_sym = obj.getObjcMsgSendRef(macho_file).?.getSymbol(macho_file).?;
444438 const target = target_sym.getGotAddress(macho_file);
445439 const source = addr + 7;
446 try writer.writeInt(i32, @intCast(target - source - 2 - 4), .little);
440 try bw.writeInt(i32, @intCast(target - source - 2 - 4), .little);
447441 }
448442 },
449443 .aarch64 => {
......@@ -451,9 +445,9 @@ pub const ObjcStubsSection = struct {
451445 const target = sym.getObjcSelrefsAddress(macho_file);
452446 const source = addr;
453447 const pages = try aarch64.calcNumberOfPages(@intCast(source), @intCast(target));
454 try writer.writeInt(u32, aarch64.Instruction.adrp(.x1, pages).toU32(), .little);
448 try bw.writeInt(u32, aarch64.Instruction.adrp(.x1, pages).toU32(), .little);
455449 const off = try math.divExact(u12, @truncate(target), 8);
456 try writer.writeInt(
450 try bw.writeInt(
457451 u32,
458452 aarch64.Instruction.ldr(.x1, .x1, aarch64.Instruction.LoadStoreOffset.imm(off)).toU32(),
459453 .little,
......@@ -464,18 +458,18 @@ pub const ObjcStubsSection = struct {
464458 const target = target_sym.getGotAddress(macho_file);
465459 const source = addr + 2 * @sizeOf(u32);
466460 const pages = try aarch64.calcNumberOfPages(@intCast(source), @intCast(target));
467 try writer.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
461 try bw.writeInt(u32, aarch64.Instruction.adrp(.x16, pages).toU32(), .little);
468462 const off = try math.divExact(u12, @truncate(target), 8);
469 try writer.writeInt(
463 try bw.writeInt(
470464 u32,
471465 aarch64.Instruction.ldr(.x16, .x16, aarch64.Instruction.LoadStoreOffset.imm(off)).toU32(),
472466 .little,
473467 );
474468 }
475 try writer.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
476 try writer.writeInt(u32, aarch64.Instruction.brk(1).toU32(), .little);
477 try writer.writeInt(u32, aarch64.Instruction.brk(1).toU32(), .little);
478 try writer.writeInt(u32, aarch64.Instruction.brk(1).toU32(), .little);
469 try bw.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little);
470 try bw.writeInt(u32, aarch64.Instruction.brk(1).toU32(), .little);
471 try bw.writeInt(u32, aarch64.Instruction.brk(1).toU32(), .little);
472 try bw.writeInt(u32, aarch64.Instruction.brk(1).toU32(), .little);
479473 },
480474 else => unreachable,
481475 }
......@@ -493,15 +487,13 @@ pub const ObjcStubsSection = struct {
493487
494488 pub fn format2(
495489 ctx: FormatCtx,
490 bw: *std.io.BufferedWriter,
496491 comptime unused_fmt_string: []const u8,
497 options: std.fmt.FormatOptions,
498 writer: anytype,
499492 ) !void {
500 _ = options;
501493 _ = unused_fmt_string;
502494 for (ctx.objc.symbols.items, 0..) |ref, i| {
503495 const symbol = ref.getSymbol(ctx.macho_file).?;
504 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
496 try bw.print(" {d}@0x{x} => {f}@0x{x} ({s})\n", .{
505497 i,
506498 symbol.getObjcStubsAddress(ctx.macho_file),
507499 ref,
......@@ -524,7 +516,7 @@ pub const Indsymtab = struct {
524516 macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file);
525517 }
526518
527 pub fn write(ind: Indsymtab, macho_file: *MachO, writer: anytype) !void {
519 pub fn write(ind: Indsymtab, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
528520 const tracy = trace(@src());
529521 defer tracy.end();
530522
......@@ -533,21 +525,21 @@ pub const Indsymtab = struct {
533525 for (macho_file.stubs.symbols.items) |ref| {
534526 const sym = ref.getSymbol(macho_file).?;
535527 if (sym.getOutputSymtabIndex(macho_file)) |idx| {
536 try writer.writeInt(u32, idx, .little);
528 try bw.writeInt(u32, idx, .little);
537529 }
538530 }
539531
540532 for (macho_file.got.symbols.items) |ref| {
541533 const sym = ref.getSymbol(macho_file).?;
542534 if (sym.getOutputSymtabIndex(macho_file)) |idx| {
543 try writer.writeInt(u32, idx, .little);
535 try bw.writeInt(u32, idx, .little);
544536 }
545537 }
546538
547539 for (macho_file.stubs.symbols.items) |ref| {
548540 const sym = ref.getSymbol(macho_file).?;
549541 if (sym.getOutputSymtabIndex(macho_file)) |idx| {
550 try writer.writeInt(u32, idx, .little);
542 try bw.writeInt(u32, idx, .little);
551543 }
552544 }
553545 }
......@@ -601,7 +593,7 @@ pub const DataInCode = struct {
601593 macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow;
602594 }
603595
604 pub fn write(dice: DataInCode, macho_file: *MachO, writer: anytype) !void {
596 pub fn write(dice: DataInCode, macho_file: *MachO, bw: *std.io.BufferedWriter) !void {
605597 const base_address = if (!macho_file.base.isRelocatable())
606598 macho_file.getTextSegment().vmaddr
607599 else
......@@ -609,7 +601,7 @@ pub const DataInCode = struct {
609601 for (dice.entries.items) |entry| {
610602 const atom_address = entry.atom_ref.getAtom(macho_file).?.getAddress(macho_file);
611603 const offset = atom_address + entry.offset - base_address;
612 try writer.writeStruct(macho.data_in_code_entry{
604 try bw.writeStruct(macho.data_in_code_entry{
613605 .offset = @intCast(offset),
614606 .length = entry.length,
615607 .kind = entry.kind,
src/link/Plan9.zig+60-56
......@@ -202,7 +202,7 @@ pub const Atom = struct {
202202/// after every opcode, add the quanta of the instruction size to the pc
203203pub const DebugInfoOutput = struct {
204204 /// the actual opcodes
205 dbg_line: std.ArrayList(u8),
205 dbg_line: std.ArrayListUnmanaged(u8),
206206 /// what line the debuginfo starts on
207207 /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
208208 start_line: ?u32,
......@@ -336,23 +336,26 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void
336336 };
337337 try fn_map_res.value_ptr.functions.put(gpa, nav_index, out);
338338
339 var a = std.ArrayList(u8).init(arena);
340 errdefer a.deinit();
339 var aw: std.io.AllocatingWriter = undefined;
340 aw.init(arena);
341 defer aw.deinit();
342 const bw = &aw.buffered_writer;
343
341344 // every 'z' starts with 0
342 try a.append(0);
345 try bw.writeByte(0);
343346 // path component value of '/'
344 try a.writer().writeInt(u16, 1, .big);
347 try bw.writeInt(u16, 1, .big);
345348
346349 // getting the full file path
347350 {
348351 const full_path = try file.path.toAbsolute(comp.dirs, gpa);
349352 defer gpa.free(full_path);
350 try self.addPathComponents(full_path, &a);
353 try self.addPathComponents(full_path, bw);
351354 }
352355
353356 // null terminate
354 try a.append(0);
355 const final = try a.toOwnedSlice();
357 try bw.writeByte(0);
358 const final = try aw.toOwnedSlice();
356359 self.syms.items[fn_map_res.value_ptr.sym_index - 1] = .{
357360 .type = .z,
358361 .value = 1,
......@@ -367,17 +370,17 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void
367370 }
368371}
369372
370fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !void {
373fn addPathComponents(self: *Plan9, path: []const u8, bw: *std.io.BufferedWriter) !void {
371374 const gpa = self.base.comp.gpa;
372375 const sep = std.fs.path.sep;
373376 var it = std.mem.tokenizeScalar(u8, path, sep);
374377 while (it.next()) |component| {
375378 if (self.file_segments.get(component)) |num| {
376 try a.writer().writeInt(u16, num, .big);
379 try bw.writeInt(u16, num, .big);
377380 } else {
378381 self.file_segments_i += 1;
379382 try self.file_segments.put(gpa, component, self.file_segments_i);
380 try a.writer().writeInt(u16, self.file_segments_i, .big);
383 try bw.writeInt(u16, self.file_segments_i, .big);
381384 }
382385 }
383386}
......@@ -402,14 +405,14 @@ pub fn updateFunc(
402405 var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
403406 defer code_buffer.deinit(gpa);
404407 var dbg_info_output: DebugInfoOutput = .{
405 .dbg_line = std.ArrayList(u8).init(gpa),
408 .dbg_line = .empty,
406409 .start_line = null,
407410 .end_line = undefined,
408411 .pcop_change_index = null,
409412 // we have already checked the target in the linker to make sure it is compatable
410413 .pc_quanta = aout.getPCQuant(target.cpu.arch) catch unreachable,
411414 };
412 defer dbg_info_output.dbg_line.deinit();
415 defer dbg_info_output.dbg_line.deinit(gpa);
413416
414417 try codegen.emitFunction(
415418 &self.base,
......@@ -427,7 +430,7 @@ pub fn updateFunc(
427430 };
428431 const out: FnNavOutput = .{
429432 .code = code,
430 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),
433 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(gpa),
431434 .start_line = dbg_info_output.start_line.?,
432435 .end_line = dbg_info_output.end_line,
433436 };
......@@ -445,7 +448,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
445448 .func => return,
446449 .variable => |variable| Value.fromInterned(variable.init),
447450 .@"extern" => {
448 log.debug("found extern decl: {}", .{nav.name.fmt(ip)});
451 log.debug("found extern decl: {f}", .{nav.name.fmt(ip)});
449452 return;
450453 },
451454 else => nav_val,
......@@ -524,16 +527,14 @@ fn allocateGotIndex(self: *Plan9) usize {
524527 }
525528}
526529
527pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
530pub fn changeLine(bw: *std.io.Writer, delta_line: i32) !void {
528531 if (delta_line > 0 and delta_line < 65) {
529 const toappend = @as(u8, @intCast(delta_line));
530 try l.append(toappend);
532 try bw.writeByte(@intCast(delta_line));
531533 } else if (delta_line < 0 and delta_line > -65) {
532 const toadd: u8 = @as(u8, @intCast(-delta_line + 64));
533 try l.append(toadd);
534 try bw.writeByte(@intCast(-delta_line + 64));
534535 } else if (delta_line != 0) {
535 try l.append(0);
536 try l.writer().writeInt(i32, delta_line, .big);
536 try bw.writeByte(0);
537 try bw.writeInt(i32, delta_line, .big);
537538 }
538539}
539540
......@@ -645,10 +646,12 @@ pub fn flush(
645646 var iovecs_i: usize = 1;
646647 var text_i: u64 = 0;
647648
648 var linecountinfo = std.ArrayList(u8).init(gpa);
649 defer linecountinfo.deinit();
649 var linecountinfo_aw: std.io.AllocatingWriter = undefined;
650 linecountinfo_aw.init(gpa);
651 defer linecountinfo_aw.deinit();
650652 // text
651653 {
654 const linecountinfo_bw = &linecountinfo_aw.buffered_writer;
652655 var linecount: i64 = -1;
653656 var it_file = self.fn_nav_table.iterator();
654657 while (it_file.next()) |fentry| {
......@@ -662,11 +665,11 @@ pub fn flush(
662665 // connect the previous decl to the next
663666 const delta_line = @as(i32, @intCast(out.start_line)) - @as(i32, @intCast(linecount));
664667
665 try changeLine(&linecountinfo, delta_line);
668 changeLine(linecountinfo_bw, delta_line) catch |err| return @errorCast(err);
666669 // TODO change the pc too (maybe?)
667670
668671 // write out the actual info that was generated in codegen now
669 try linecountinfo.appendSlice(out.lineinfo);
672 linecountinfo_bw.writeAll(out.lineinfo) catch |err| return @errorCast(err);
670673 linecount = out.end_line;
671674 }
672675 foff += out.code.len;
......@@ -675,7 +678,7 @@ pub fn flush(
675678 const off = self.getAddr(text_i, .t);
676679 text_i += out.code.len;
677680 atom.offset = off;
678 log.debug("write text nav 0x{x} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ nav_index, nav.name.fmt(&pt.zcu.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
681 log.debug("write text nav 0x{x} ({f}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ nav_index, nav.name.fmt(&pt.zcu.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
679682 if (!self.sixtyfour_bit) {
680683 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @intCast(off), target.cpu.arch.endian());
681684 } else {
......@@ -687,11 +690,12 @@ pub fn flush(
687690 }
688691 }
689692 }
690 if (linecountinfo.items.len & 1 == 1) {
693 if (linecountinfo_aw.getWritten().len & 1 == 1) {
691694 // just a nop to make it even, the plan9 linker does this
692 try linecountinfo.append(129);
695 linecountinfo_bw.writeByte(129) catch |err| return @errorCast(err);
693696 }
694697 }
698 const linecountinfo = linecountinfo_aw.getWritten();
695699 // the text lazy symbols
696700 {
697701 var it = self.lazy_syms.iterator();
......@@ -815,25 +819,26 @@ pub fn flush(
815819 }
816820 }
817821 }
818 var sym_buf = std.ArrayList(u8).init(gpa);
819 try self.writeSyms(&sym_buf);
820 const syms = try sym_buf.toOwnedSlice();
821 defer gpa.free(syms);
822 var syms_aw: std.io.AllocatingWriter = undefined;
823 syms_aw.init(gpa);
824 defer syms_aw.deinit();
825 self.writeSyms(&syms_aw.buffered_writer) catch |err| return @errorCast(err);
826 const syms = syms_aw.getWritten();
822827 assert(2 + self.atomCount() - self.externCount() == iovecs_i); // we didn't write all the decls
823828 iovecs[iovecs_i] = .{ .base = syms.ptr, .len = syms.len };
824829 iovecs_i += 1;
825 iovecs[iovecs_i] = .{ .base = linecountinfo.items.ptr, .len = linecountinfo.items.len };
830 iovecs[iovecs_i] = .{ .base = linecountinfo.ptr, .len = linecountinfo.len };
826831 iovecs_i += 1;
827832 // generate the header
828833 self.hdr = .{
829834 .magic = self.magic,
830 .text = @as(u32, @intCast(text_i)),
831 .data = @as(u32, @intCast(data_i)),
832 .syms = @as(u32, @intCast(syms.len)),
835 .text = @intCast(text_i),
836 .data = @intCast(data_i),
837 .syms = @intCast(syms.len),
833838 .bss = 0,
834839 .spsz = 0,
835 .pcsz = @as(u32, @intCast(linecountinfo.items.len)),
836 .entry = @as(u32, @intCast(self.entry_val.?)),
840 .pcsz = @intCast(linecountinfo.len),
841 .entry = @intCast(self.entry_val.?),
837842 };
838843 @memcpy(hdr_slice, self.hdr.toU8s()[0..hdr_size]);
839844 // write the fat header for 64 bit entry points
......@@ -974,11 +979,11 @@ pub fn seeNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
974979 self.etext_edata_end_atom_indices[2] = atom_idx;
975980 }
976981 try self.updateFinish(pt, nav_index);
977 log.debug("seeNav(extern) for {} (got_addr=0x{x})", .{
982 log.debug("seeNav(extern) for {f} (got_addr=0x{x})", .{
978983 nav.name.fmt(ip),
979984 self.getAtom(atom_idx).getOffsetTableAddress(self),
980985 });
981 } else log.debug("seeNav for {}", .{nav.name.fmt(ip)});
986 } else log.debug("seeNav for {f}", .{nav.name.fmt(ip)});
982987 return atom_idx;
983988}
984989
......@@ -1043,7 +1048,7 @@ fn updateLazySymbolAtom(
10431048 defer code_buffer.deinit(gpa);
10441049
10451050 // create the symbol for the name
1046 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1051 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
10471052 @tagName(sym.kind),
10481053 Type.fromInterned(sym.ty).fmt(pt),
10491054 });
......@@ -1200,17 +1205,16 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
12001205 try w.writeByte(0);
12011206}
12021207
1203pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1208pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void {
12041209 const zcu = self.base.comp.zcu.?;
12051210 const ip = &zcu.intern_pool;
1206 const writer = buf.writer();
12071211 // write __GOT
1208 try self.writeSym(writer, self.syms.items[0]);
1212 try self.writeSym(bw, self.syms.items[0]);
12091213 // write the f symbols
12101214 {
12111215 var it = self.file_segments.iterator();
12121216 while (it.next()) |entry| {
1213 try self.writeSym(writer, .{
1217 try self.writeSym(bw, .{
12141218 .type = .f,
12151219 .value = entry.value_ptr.*,
12161220 .name = entry.key_ptr.*,
......@@ -1226,12 +1230,12 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12261230 const nav_metadata = self.navs.get(nav_index).?;
12271231 const atom = self.getAtom(nav_metadata.index);
12281232 const sym = self.syms.items[atom.sym_index.?];
1229 try self.writeSym(writer, sym);
1233 try self.writeSym(bw, sym);
12301234 if (self.nav_exports.get(nav_index)) |export_indices| {
12311235 for (export_indices) |export_idx| {
12321236 const exp = export_idx.ptr(zcu);
12331237 if (nav_metadata.getExport(self, exp.opts.name.toSlice(ip))) |exp_i| {
1234 try self.writeSym(writer, self.syms.items[exp_i]);
1238 try self.writeSym(bw, self.syms.items[exp_i]);
12351239 }
12361240 }
12371241 }
......@@ -1244,7 +1248,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12441248 const meta = kv.value_ptr;
12451249 const data_atom = if (meta.rodata_state != .unused) self.getAtomPtr(meta.rodata_atom) else continue;
12461250 const sym = self.syms.items[data_atom.sym_index.?];
1247 try self.writeSym(writer, sym);
1251 try self.writeSym(bw, sym);
12481252 }
12491253 }
12501254 // text symbols are the hardest:
......@@ -1255,8 +1259,8 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12551259 while (it_file.next()) |fentry| {
12561260 var symidx_and_submap = fentry.value_ptr;
12571261 // write the z symbols
1258 try self.writeSym(writer, self.syms.items[symidx_and_submap.sym_index - 1]);
1259 try self.writeSym(writer, self.syms.items[symidx_and_submap.sym_index]);
1262 try self.writeSym(bw, self.syms.items[symidx_and_submap.sym_index - 1]);
1263 try self.writeSym(bw, self.syms.items[symidx_and_submap.sym_index]);
12601264
12611265 // write all the decls come from the file of the z symbol
12621266 var submap_it = symidx_and_submap.functions.iterator();
......@@ -1265,7 +1269,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12651269 const nav_metadata = self.navs.get(nav_index).?;
12661270 const atom = self.getAtom(nav_metadata.index);
12671271 const sym = self.syms.items[atom.sym_index.?];
1268 try self.writeSym(writer, sym);
1272 try self.writeSym(bw, sym);
12691273 if (self.nav_exports.get(nav_index)) |export_indices| {
12701274 for (export_indices) |export_idx| {
12711275 const exp = export_idx.ptr(zcu);
......@@ -1273,7 +1277,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12731277 const s = self.syms.items[exp_i];
12741278 if (mem.eql(u8, s.name, "_start"))
12751279 self.entry_val = s.value;
1276 try self.writeSym(writer, s);
1280 try self.writeSym(bw, s);
12771281 }
12781282 }
12791283 }
......@@ -1286,7 +1290,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12861290 const meta = kv.value_ptr;
12871291 const text_atom = if (meta.text_state != .unused) self.getAtomPtr(meta.text_atom) else continue;
12881292 const sym = self.syms.items[text_atom.sym_index.?];
1289 try self.writeSym(writer, sym);
1293 try self.writeSym(bw, sym);
12901294 }
12911295 }
12921296 }
......@@ -1295,7 +1299,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
12951299 if (idx) |atom_idx| {
12961300 const atom = self.getAtom(atom_idx);
12971301 const sym = self.syms.items[atom.sym_index.?];
1298 try self.writeSym(writer, sym);
1302 try self.writeSym(bw, sym);
12991303 }
13001304 }
13011305}
......@@ -1314,7 +1318,7 @@ pub fn getNavVAddr(
13141318) !u64 {
13151319 const ip = &pt.zcu.intern_pool;
13161320 const nav = ip.getNav(nav_index);
1317 log.debug("getDeclVAddr for {}", .{nav.name.fmt(ip)});
1321 log.debug("getDeclVAddr for {f}", .{nav.name.fmt(ip)});
13181322 if (nav.getExtern(ip) != null) {
13191323 if (nav.name.eqlSlice("etext", ip)) {
13201324 try self.addReloc(reloc_info.parent.atom_index, .{
src/link/SpirV.zig+9-8
......@@ -117,7 +117,7 @@ pub fn updateNav(self: *SpirV, pt: Zcu.PerThread, nav: InternPool.Nav.Index) lin
117117 }
118118
119119 const ip = &pt.zcu.intern_pool;
120 log.debug("lowering nav {}({d})", .{ ip.getNav(nav).fqn.fmt(ip), nav });
120 log.debug("lowering nav {f}({d})", .{ ip.getNav(nav).fqn.fmt(ip), nav });
121121
122122 try self.object.updateNav(pt, nav);
123123}
......@@ -203,10 +203,11 @@ pub fn flush(
203203 // We need to export the list of error names somewhere so that we can pretty-print them in the
204204 // executor. This is not really an important thing though, so we can just dump it in any old
205205 // nonsemantic instruction. For now, just put it in OpSourceExtension with a special name.
206 var error_info = std.ArrayList(u8).init(self.object.gpa);
206 var error_info: std.io.AllocatingWriter = undefined;
207 error_info.init(self.object.gpa);
207208 defer error_info.deinit();
208209
209 try error_info.appendSlice("zig_errors:");
210 error_info.buffered_writer.writeAll("zig_errors:") catch |err| return @errorCast(err);
210211 const ip = &self.base.comp.zcu.?.intern_pool;
211212 for (ip.global_error_set.getNamesFromMainThread()) |name| {
212213 // Errors can contain pretty much any character - to encode them in a string we must escape
......@@ -214,9 +215,9 @@ pub fn flush(
214215 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.
215216 // We're using : as separator, which is a reserved character.
216217
217 try error_info.append(':');
218 try std.Uri.Component.percentEncode(
219 error_info.writer(),
218 error_info.buffered_writer.writeByte(':') catch |err| return @errorCast(err);
219 std.Uri.Component.percentEncode(
220 &error_info.buffered_writer,
220221 name.toSlice(ip),
221222 struct {
222223 fn isValidChar(c: u8) bool {
......@@ -226,10 +227,10 @@ pub fn flush(
226227 };
227228 }
228229 }.isValidChar,
229 );
230 ) catch |err| return @errorCast(err);
230231 }
231232 try spv.sections.debug_strings.emit(gpa, .OpSourceExtension, .{
232 .extension = error_info.items,
233 .extension = error_info.getWritten(),
233234 });
234235
235236 const module = try spv.finalize(arena);
src/link/SpirV/deduplicate.zig+1-1
......@@ -110,7 +110,7 @@ const ModuleInfo = struct {
110110 .TypeDeclaration, .ConstantCreation => {
111111 const entry = try entities.getOrPut(result_id);
112112 if (entry.found_existing) {
113 log.err("type or constant {} has duplicate definition", .{result_id});
113 log.err("type or constant {f} has duplicate definition", .{result_id});
114114 return error.DuplicateId;
115115 }
116116 entry.value_ptr.* = entity;
src/link/SpirV/lower_invocation_globals.zig+9-9
......@@ -92,7 +92,7 @@ const ModuleInfo = struct {
9292 const entry_point: ResultId = @enumFromInt(inst.operands[1]);
9393 const entry = try entry_points.getOrPut(entry_point);
9494 if (entry.found_existing) {
95 log.err("Entry point type {} has duplicate definition", .{entry_point});
95 log.err("Entry point type {f} has duplicate definition", .{entry_point});
9696 return error.DuplicateId;
9797 }
9898 },
......@@ -103,7 +103,7 @@ const ModuleInfo = struct {
103103
104104 const entry = try fn_types.getOrPut(fn_type);
105105 if (entry.found_existing) {
106 log.err("Function type {} has duplicate definition", .{fn_type});
106 log.err("Function type {f} has duplicate definition", .{fn_type});
107107 return error.DuplicateId;
108108 }
109109
......@@ -135,7 +135,7 @@ const ModuleInfo = struct {
135135 },
136136 .OpFunction => {
137137 if (maybe_current_function) |current_function| {
138 log.err("OpFunction {} does not have an OpFunctionEnd", .{current_function});
138 log.err("OpFunction {f} does not have an OpFunctionEnd", .{current_function});
139139 return error.InvalidPhysicalFormat;
140140 }
141141
......@@ -154,7 +154,7 @@ const ModuleInfo = struct {
154154 };
155155 const entry = try functions.getOrPut(current_function);
156156 if (entry.found_existing) {
157 log.err("Function {} has duplicate definition", .{current_function});
157 log.err("Function {f} has duplicate definition", .{current_function});
158158 return error.DuplicateId;
159159 }
160160
......@@ -162,7 +162,7 @@ const ModuleInfo = struct {
162162 try callee_store.appendSlice(calls.keys());
163163
164164 const fn_type = fn_types.get(fn_ty_id) orelse {
165 log.err("Function {} has invalid OpFunction type", .{current_function});
165 log.err("Function {f} has invalid OpFunction type", .{current_function});
166166 return error.InvalidId;
167167 };
168168
......@@ -187,7 +187,7 @@ const ModuleInfo = struct {
187187 }
188188
189189 if (maybe_current_function) |current_function| {
190 log.err("OpFunction {} does not have an OpFunctionEnd", .{current_function});
190 log.err("OpFunction {f} does not have an OpFunctionEnd", .{current_function});
191191 return error.InvalidPhysicalFormat;
192192 }
193193
......@@ -222,7 +222,7 @@ const ModuleInfo = struct {
222222 seen: *std.DynamicBitSetUnmanaged,
223223 ) !void {
224224 const index = self.functions.getIndex(id) orelse {
225 log.err("function calls invalid function {}", .{id});
225 log.err("function calls invalid function {f}", .{id});
226226 return error.InvalidId;
227227 };
228228
......@@ -261,7 +261,7 @@ const ModuleInfo = struct {
261261 seen: *std.DynamicBitSetUnmanaged,
262262 ) !void {
263263 const index = self.invocation_globals.getIndex(id) orelse {
264 log.err("invalid invocation global {}", .{id});
264 log.err("invalid invocation global {f}", .{id});
265265 return error.InvalidId;
266266 };
267267
......@@ -276,7 +276,7 @@ const ModuleInfo = struct {
276276 }
277277
278278 const initializer = self.functions.get(info.initializer) orelse {
279 log.err("invocation global {} has invalid initializer {}", .{ id, info.initializer });
279 log.err("invocation global {f} has invalid initializer {f}", .{ id, info.initializer });
280280 return error.InvalidId;
281281 };
282282
src/link/SpirV/prune_unused.zig+4-4
......@@ -128,7 +128,7 @@ const ModuleInfo = struct {
128128 switch (inst.opcode) {
129129 .OpFunction => {
130130 if (maybe_current_function) |current_function| {
131 log.err("OpFunction {} does not have an OpFunctionEnd", .{current_function});
131 log.err("OpFunction {f} does not have an OpFunctionEnd", .{current_function});
132132 return error.InvalidPhysicalFormat;
133133 }
134134
......@@ -145,7 +145,7 @@ const ModuleInfo = struct {
145145 };
146146 const entry = try functions.getOrPut(current_function);
147147 if (entry.found_existing) {
148 log.err("Function {} has duplicate definition", .{current_function});
148 log.err("Function {f} has duplicate definition", .{current_function});
149149 return error.DuplicateId;
150150 }
151151
......@@ -163,7 +163,7 @@ const ModuleInfo = struct {
163163 }
164164
165165 if (maybe_current_function) |current_function| {
166 log.err("OpFunction {} does not have an OpFunctionEnd", .{current_function});
166 log.err("OpFunction {f} does not have an OpFunctionEnd", .{current_function});
167167 return error.InvalidPhysicalFormat;
168168 }
169169
......@@ -184,7 +184,7 @@ const AliveMarker = struct {
184184
185185 fn markAlive(self: *AliveMarker, result_id: ResultId) BinaryModule.ParseError!void {
186186 const index = self.info.result_id_to_code_offset.getIndex(result_id) orelse {
187 log.err("undefined result-id {}", .{result_id});
187 log.err("undefined result-id {f}", .{result_id});
188188 return error.InvalidId;
189189 };
190190
src/link/Wasm.zig+27-34
......@@ -547,7 +547,7 @@ pub const SourceLocation = enum(u32) {
547547 switch (sl.unpack(wasm)) {
548548 .none => unreachable,
549549 .zig_object_nofile => diags.addError("zig compilation unit: " ++ f, args),
550 .object_index => |i| diags.addError("{}: " ++ f, .{i.ptr(wasm).path} ++ args),
550 .object_index => |i| diags.addError("{f}: " ++ f, .{i.ptr(wasm).path} ++ args),
551551 .source_location_index => @panic("TODO"),
552552 }
553553 }
......@@ -579,9 +579,9 @@ pub const SourceLocation = enum(u32) {
579579 .object_index => |i| {
580580 const obj = i.ptr(wasm);
581581 return if (obj.archive_member_name.slice(wasm)) |obj_name|
582 try bundle.printString("{} ({s}): {s}", .{ obj.path, std.fs.path.basename(obj_name), msg })
582 try bundle.printString("{f} ({s}): {s}", .{ obj.path, std.fs.path.basename(obj_name), msg })
583583 else
584 try bundle.printString("{}: {s}", .{ obj.path, msg });
584 try bundle.printString("{f}: {s}", .{ obj.path, msg });
585585 },
586586 .source_location_index => @panic("TODO"),
587587 };
......@@ -2087,11 +2087,10 @@ pub const Expr = enum(u32) {
20872087 pub const end = @intFromEnum(std.wasm.Opcode.end);
20882088
20892089 pub fn slice(index: Expr, wasm: *const Wasm) [:end]const u8 {
2090 const start_slice = wasm.string_bytes.items[@intFromEnum(index)..];
2091 const end_pos = Object.exprEndPos(start_slice, 0) catch |err| switch (err) {
2092 error.InvalidInitOpcode => unreachable,
2093 };
2094 return start_slice[0..end_pos :end];
2090 var br: std.io.BufferedReader = undefined;
2091 br.initFixed(wasm.string_bytes.items[@intFromEnum(index)..]);
2092 Object.skipInit(&br) catch unreachable;
2093 return br.storageBuffer()[0 .. br.seek - 1 :end];
20952094 }
20962095};
20972096
......@@ -2126,32 +2125,26 @@ pub const FunctionType = extern struct {
21262125 wasm: *const Wasm,
21272126 ft: FunctionType,
21282127
2129 pub fn format(
2130 self: Formatter,
2131 comptime format_string: []const u8,
2132 options: std.fmt.FormatOptions,
2133 writer: anytype,
2134 ) !void {
2128 pub fn format(self: Formatter, bw: *std.io.BufferedWriter, comptime format_string: []const u8) anyerror!void {
21352129 if (format_string.len != 0) std.fmt.invalidFmtError(format_string, self);
2136 _ = options;
21372130 const params = self.ft.params.slice(self.wasm);
21382131 const returns = self.ft.returns.slice(self.wasm);
21392132
2140 try writer.writeByte('(');
2133 try bw.writeByte('(');
21412134 for (params, 0..) |param, i| {
2142 try writer.print("{s}", .{@tagName(param)});
2135 try bw.print("{s}", .{@tagName(param)});
21432136 if (i + 1 != params.len) {
2144 try writer.writeAll(", ");
2137 try bw.writeAll(", ");
21452138 }
21462139 }
2147 try writer.writeAll(") -> ");
2140 try bw.writeAll(") -> ");
21482141 if (returns.len == 0) {
2149 try writer.writeAll("nil");
2142 try bw.writeAll("nil");
21502143 } else {
21512144 for (returns, 0..) |return_ty, i| {
2152 try writer.print("{s}", .{@tagName(return_ty)});
2145 try bw.print("{s}", .{@tagName(return_ty)});
21532146 if (i + 1 != returns.len) {
2154 try writer.writeAll(", ");
2147 try bw.writeAll(", ");
21552148 }
21562149 }
21572150 }
......@@ -2912,10 +2905,9 @@ pub const Feature = packed struct(u8) {
29122905 @"=",
29132906 };
29142907
2915 pub fn format(feature: Feature, comptime fmt: []const u8, opt: std.fmt.FormatOptions, writer: anytype) !void {
2916 _ = opt;
2908 pub fn format(feature: Feature, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
29172909 _ = fmt;
2918 try writer.print("{s} {s}", .{ @tagName(feature.prefix), @tagName(feature.tag) });
2910 try bw.print("{s} {s}", .{ @tagName(feature.prefix), @tagName(feature.tag) });
29192911 }
29202912
29212913 pub fn lessThan(_: void, a: Feature, b: Feature) bool {
......@@ -3036,7 +3028,7 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void {
30363028}
30373029
30383030fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void {
3039 log.debug("parseObject {}", .{obj.path});
3031 log.debug("parseObject {f}", .{obj.path});
30403032 const gpa = wasm.base.comp.gpa;
30413033 const gc_sections = wasm.base.gc_sections;
30423034
......@@ -3046,21 +3038,22 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void {
30463038 const stat = try obj.file.stat();
30473039 const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig;
30483040
3049 const file_contents = try gpa.alloc(u8, size);
3050 defer gpa.free(file_contents);
3041 var br: std.io.BufferedReader = undefined;
3042 br.initFixed(try gpa.alloc(u8, size));
3043 defer gpa.free(br.storageBuffer());
30513044
3052 const n = try obj.file.preadAll(file_contents, 0);
3053 if (n != file_contents.len) return error.UnexpectedEndOfFile;
3045 const n = try obj.file.preadAll(br.storageBuffer(), 0);
3046 if (n != br.storageBuffer().len) return error.UnexpectedEndOfFile;
30543047
30553048 var ss: Object.ScratchSpace = .{};
30563049 defer ss.deinit(gpa);
30573050
3058 const object = try Object.parse(wasm, file_contents, obj.path, null, wasm.object_host_name, &ss, obj.must_link, gc_sections);
3051 const object = try Object.parse(wasm, &br, obj.path, null, wasm.object_host_name, &ss, obj.must_link, gc_sections);
30593052 wasm.objects.appendAssumeCapacity(object);
30603053}
30613054
30623055fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void {
3063 log.debug("parseArchive {}", .{obj.path});
3056 log.debug("parseArchive {f}", .{obj.path});
30643057 const gpa = wasm.base.comp.gpa;
30653058 const gc_sections = wasm.base.gc_sections;
30663059
......@@ -3196,7 +3189,7 @@ pub fn updateFunc(
31963189 const is_obj = zcu.comp.config.output_mode == .Obj;
31973190 const target = &zcu.comp.root_mod.resolved_target.result;
31983191 const owner_nav = zcu.funcInfo(func_index).owner_nav;
3199 log.debug("updateFunc {}", .{ip.getNav(owner_nav).fqn.fmt(ip)});
3192 log.debug("updateFunc {f}", .{ip.getNav(owner_nav).fqn.fmt(ip)});
32003193
32013194 // For Wasm, we do not lower the MIR to code just yet. That lowering happens during `flush`,
32023195 // after garbage collection, which can affect function and global indexes, which affects the
......@@ -4347,7 +4340,7 @@ fn resolveFunctionSynthetic(
43474340 });
43484341 if (import.type != correct_func_type) {
43494342 const diags = &wasm.base.comp.link_diags;
4350 return import.source_location.fail(diags, "synthetic function {s} {} imported with incorrect signature {}", .{
4343 return import.source_location.fail(diags, "synthetic function {s} {f} imported with incorrect signature {f}", .{
43514344 @tagName(res), correct_func_type.fmt(wasm), import.type.fmt(wasm),
43524345 });
43534346 }
src/link/Wasm/Archive.zig+3-2
......@@ -167,9 +167,10 @@ pub fn parseObject(
167167 };
168168
169169 const object_file_size = try header.parsedSize();
170 const contents = file_contents[object_offset + @sizeOf(Header) ..][0..object_file_size];
170 var br: std.io.BufferedReader = undefined;
171 br.initFixed(file_contents[object_offset + @sizeOf(Header) ..][0..object_file_size]);
171172
172 return Object.parse(wasm, contents, path, object_name, host_name, scratch_space, must_link, gc_sections);
173 return Object.parse(wasm, &br, path, object_name, host_name, scratch_space, must_link, gc_sections);
173174}
174175
175176const Archive = @This();
src/link/Wasm/Flush.zig+469-554
......@@ -16,7 +16,6 @@ const build_options = @import("build_options");
1616const std = @import("std");
1717const Allocator = std.mem.Allocator;
1818const mem = std.mem;
19const leb = std.leb;
2019const log = std.log.scoped(.link);
2120const assert = std.debug.assert;
2221
......@@ -557,13 +556,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
557556 // Index of the data section. Used to tell relocation table where the section lives.
558557 var data_section_index: ?u32 = null;
559558
560 const binary_bytes = &f.binary_bytes;
561 assert(binary_bytes.items.len == 0);
559 assert(f.binary_bytes.items.len == 0);
560 var aw: std.io.AllocatingWriter = undefined;
561 const bw = aw.fromArrayList(gpa, &f.binary_bytes);
562 defer f.binary_bytes = aw.toArrayList();
562563
563 try binary_bytes.appendSlice(gpa, &std.wasm.magic ++ &std.wasm.version);
564 assert(binary_bytes.items.len == 8);
565
566 const binary_writer = binary_bytes.writer(gpa);
564 try bw.writeAll(&std.wasm.magic ++ &std.wasm.version);
567565
568566 // Type section.
569567 for (f.function_imports.values()) |id| {
......@@ -573,22 +571,18 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
573571 try f.func_types.put(gpa, function.typeIndex(wasm), {});
574572 }
575573 if (f.func_types.entries.len != 0) {
576 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
574 const header_offset = try reserveVecSectionHeader(bw);
577575 for (f.func_types.keys()) |func_type_index| {
578576 const func_type = func_type_index.ptr(wasm);
579 try leb.writeUleb128(binary_writer, std.wasm.function_type);
577 try bw.writeLeb128(std.wasm.function_type);
580578 const params = func_type.params.slice(wasm);
581 try leb.writeUleb128(binary_writer, @as(u32, @intCast(params.len)));
582 for (params) |param_ty| {
583 try leb.writeUleb128(binary_writer, @intFromEnum(param_ty));
584 }
579 try bw.writeLeb128(params.len);
580 for (params) |param_ty| try bw.writeLeb128(@intFromEnum(param_ty));
585581 const returns = func_type.returns.slice(wasm);
586 try leb.writeUleb128(binary_writer, @as(u32, @intCast(returns.len)));
587 for (returns) |ret_ty| {
588 try leb.writeUleb128(binary_writer, @intFromEnum(ret_ty));
589 }
582 try bw.writeLeb128(returns.len);
583 for (returns) |ret_ty| try bw.writeLeb128(@intFromEnum(ret_ty));
590584 }
591 replaceVecSectionHeader(binary_bytes, header_offset, .type, @intCast(f.func_types.entries.len));
585 replaceVecSectionHeader(&aw, header_offset, .type, @intCast(f.func_types.entries.len));
592586 section_index += 1;
593587 }
594588
......@@ -601,42 +595,42 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
601595 // Import section
602596 {
603597 var total_imports: usize = 0;
604 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
598 const header_offset = try reserveVecSectionHeader(bw);
605599
606600 for (f.function_imports.values()) |id| {
607601 const module_name = id.moduleName(wasm).slice(wasm).?;
608 try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len)));
609 try binary_writer.writeAll(module_name);
602 try bw.writeLeb128(module_name.len);
603 try bw.writeAll(module_name);
610604
611605 const name = id.importName(wasm).slice(wasm);
612 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
613 try binary_writer.writeAll(name);
606 try bw.writeLeb128(name.len);
607 try bw.writeAll(name);
614608
615 try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.function));
609 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.function));
616610 const type_index: FuncTypeIndex = .fromTypeIndex(id.functionType(wasm), f);
617 try leb.writeUleb128(binary_writer, @intFromEnum(type_index));
611 try bw.writeLeb128(@intFromEnum(type_index));
618612 }
619613 total_imports += f.function_imports.entries.len;
620614
621615 for (wasm.table_imports.values()) |id| {
622616 const table_import = id.value(wasm);
623617 const module_name = table_import.module_name.slice(wasm);
624 try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len)));
625 try binary_writer.writeAll(module_name);
618 try bw.writeLeb128(module_name.len);
619 try bw.writeAll(module_name);
626620
627621 const name = table_import.name.slice(wasm);
628 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
629 try binary_writer.writeAll(name);
622 try bw.writeLeb128(name.len);
623 try bw.writeAll(name);
630624
631 try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.table));
632 try leb.writeUleb128(binary_writer, @intFromEnum(@as(std.wasm.RefType, table_import.flags.ref_type.to())));
633 try emitLimits(gpa, binary_bytes, table_import.limits());
625 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.table));
626 try bw.writeLeb128(@intFromEnum(@as(std.wasm.RefType, table_import.flags.ref_type.to())));
627 try emitLimits(bw, table_import.limits());
634628 }
635629 total_imports += wasm.table_imports.entries.len;
636630
637631 if (import_memory) {
638632 const name = if (is_obj) wasm.preloaded_strings.__linear_memory else wasm.preloaded_strings.memory;
639 try emitMemoryImport(wasm, binary_bytes, name, &.{
633 try emitMemoryImport(wasm, bw, name, &.{
640634 // TODO the import_memory option needs to specify from which module
641635 .module_name = wasm.object_host_name.unwrap().?,
642636 .limits_min = wasm.memories.limits.min,
......@@ -650,215 +644,209 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
650644
651645 for (f.global_imports.values()) |id| {
652646 const module_name = id.moduleName(wasm).slice(wasm).?;
653 try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len)));
654 try binary_writer.writeAll(module_name);
647 try bw.writeLeb128(module_name.len);
648 try bw.writeAll(module_name);
655649
656650 const name = id.importName(wasm).slice(wasm);
657 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
658 try binary_writer.writeAll(name);
651 try bw.writeLeb128(name.len);
652 try bw.writeAll(name);
659653
660 try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.global));
654 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.global));
661655 const global_type = id.globalType(wasm);
662 try leb.writeUleb128(binary_writer, @intFromEnum(@as(std.wasm.Valtype, global_type.valtype)));
663 try binary_writer.writeByte(@intFromBool(global_type.mutable));
656 try bw.writeLeb128(@intFromEnum(global_type.valtype));
657 try bw.writeByte(@intFromBool(global_type.mutable));
664658 }
665659 total_imports += f.global_imports.entries.len;
666660
667661 if (total_imports > 0) {
668 replaceVecSectionHeader(binary_bytes, header_offset, .import, @intCast(total_imports));
662 replaceVecSectionHeader(&aw, header_offset, .import, @intCast(total_imports));
669663 section_index += 1;
670664 } else {
671 binary_bytes.shrinkRetainingCapacity(header_offset);
665 aw.shrinkRetainingCapacity(header_offset);
672666 }
673667 }
674668
675669 // Function section
676670 if (wasm.functions.count() != 0) {
677 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
671 const header_offset = try reserveVecSectionHeader(bw);
678672 for (wasm.functions.keys()) |function| {
679673 const index: FuncTypeIndex = .fromTypeIndex(function.typeIndex(wasm), f);
680 try leb.writeUleb128(binary_writer, @intFromEnum(index));
674 try bw.writeLeb128(@intFromEnum(index));
681675 }
682676
683 replaceVecSectionHeader(binary_bytes, header_offset, .function, @intCast(wasm.functions.count()));
677 replaceVecSectionHeader(&aw, header_offset, .function, @intCast(wasm.functions.count()));
684678 section_index += 1;
685679 }
686680
687681 // Table section
688682 if (wasm.tables.entries.len > 0) {
689 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
683 const header_offset = try reserveVecSectionHeader(bw);
690684
691685 for (wasm.tables.keys()) |table| {
692 try leb.writeUleb128(binary_writer, @intFromEnum(@as(std.wasm.RefType, table.refType(wasm))));
693 try emitLimits(gpa, binary_bytes, table.limits(wasm));
686 try bw.writeLeb128(@intFromEnum(table.refType(wasm)));
687 try emitLimits(bw, table.limits(wasm));
694688 }
695689
696 replaceVecSectionHeader(binary_bytes, header_offset, .table, @intCast(wasm.tables.entries.len));
690 replaceVecSectionHeader(&aw, header_offset, .table, @intCast(wasm.tables.entries.len));
697691 section_index += 1;
698692 }
699693
700694 // Memory section. wasm currently only supports 1 linear memory segment.
701695 if (!import_memory) {
702 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
703 try emitLimits(gpa, binary_bytes, wasm.memories.limits);
704 replaceVecSectionHeader(binary_bytes, header_offset, .memory, 1);
696 const header_offset = try reserveVecSectionHeader(bw);
697 try emitLimits(bw, wasm.memories.limits);
698 replaceVecSectionHeader(&aw, header_offset, .memory, 1);
705699 section_index += 1;
706700 }
707701
708702 // Global section.
709703 const globals_len: u32 = @intCast(wasm.globals.entries.len);
710704 if (globals_len > 0) {
711 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
705 const header_offset = try reserveVecSectionHeader(bw);
712706
713707 for (wasm.globals.keys()) |global_resolution| {
714708 switch (global_resolution.unpack(wasm)) {
715709 .unresolved => unreachable,
716 .__heap_base => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.heap_base),
717 .__heap_end => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.heap_end),
718 .__stack_pointer => try appendGlobal(gpa, binary_bytes, 1, virtual_addrs.stack_pointer),
719 .__tls_align => try appendGlobal(gpa, binary_bytes, 0, @intCast(virtual_addrs.tls_align.toByteUnits().?)),
720 .__tls_base => try appendGlobal(gpa, binary_bytes, 1, virtual_addrs.tls_base.?),
721 .__tls_size => try appendGlobal(gpa, binary_bytes, 0, virtual_addrs.tls_size.?),
710 .__heap_base => try appendGlobal(bw, false, virtual_addrs.heap_base),
711 .__heap_end => try appendGlobal(bw, false, virtual_addrs.heap_end),
712 .__stack_pointer => try appendGlobal(bw, true, virtual_addrs.stack_pointer),
713 .__tls_align => try appendGlobal(bw, false, @intCast(virtual_addrs.tls_align.toByteUnits().?)),
714 .__tls_base => try appendGlobal(bw, true, virtual_addrs.tls_base.?),
715 .__tls_size => try appendGlobal(bw, false, virtual_addrs.tls_size.?),
722716 .object_global => |i| {
723717 const global = i.ptr(wasm);
724 try binary_bytes.appendSlice(gpa, &.{
718 try bw.writeAll(&.{
725719 @intFromEnum(@as(std.wasm.Valtype, global.flags.global_type.valtype.to())),
726720 @intFromBool(global.flags.global_type.mutable),
727721 });
728 try emitExpr(wasm, binary_bytes, global.expr);
722 try emitExpr(wasm, bw, global.expr);
729723 },
730724 .nav_exe => unreachable, // Zig source code currently cannot represent this.
731725 .nav_obj => unreachable, // Zig source code currently cannot represent this.
732726 }
733727 }
734728
735 replaceVecSectionHeader(binary_bytes, header_offset, .global, globals_len);
729 replaceVecSectionHeader(&aw, header_offset, .global, globals_len);
736730 section_index += 1;
737731 }
738732
739733 // Export section
740734 {
741 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
735 const header_offset = try reserveVecSectionHeader(bw);
742736 var exports_len: usize = 0;
743737
744738 for (wasm.function_exports.keys(), wasm.function_exports.values()) |exp_name, function_index| {
745739 const name = exp_name.slice(wasm);
746 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
747 try binary_bytes.appendSlice(gpa, name);
748 try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.function));
740 try bw.writeLeb128(name.len);
741 try bw.writeAll(name);
742 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.function));
749743 const func_index = Wasm.OutputFunctionIndex.fromFunctionIndex(wasm, function_index);
750 try leb.writeUleb128(binary_writer, @intFromEnum(func_index));
744 try bw.writeLeb128(@intFromEnum(func_index));
751745 }
752746 exports_len += wasm.function_exports.entries.len;
753747
754748 if (wasm.export_table and f.indirect_function_table.entries.len > 0) {
755749 const name = "__indirect_function_table";
756750 const index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?);
757 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
758 try binary_bytes.appendSlice(gpa, name);
759 try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.table));
760 try leb.writeUleb128(binary_writer, index);
751 try bw.writeLeb128(name.len);
752 try bw.writeAll(name);
753 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.table));
754 try bw.writeLeb128(index);
761755 exports_len += 1;
762756 }
763757
764758 if (export_memory) {
765759 const name = "memory";
766 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
767 try binary_bytes.appendSlice(gpa, name);
768 try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.memory));
769 try leb.writeUleb128(binary_writer, @as(u32, 0));
760 try bw.writeLeb128(name.len);
761 try bw.writeAll(name);
762 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.memory));
763 try bw.writeUleb128(0);
770764 exports_len += 1;
771765 }
772766
773767 for (wasm.global_exports.items) |exp| {
774768 const name = exp.name.slice(wasm);
775 try leb.writeUleb128(binary_writer, @as(u32, @intCast(name.len)));
776 try binary_bytes.appendSlice(gpa, name);
777 try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.global));
778 try leb.writeUleb128(binary_writer, @intFromEnum(exp.global_index));
769 try bw.writeLeb128(name.len);
770 try bw.writeAll(name);
771 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.global));
772 try bw.writeLeb128(@intFromEnum(exp.global_index));
779773 }
780774 exports_len += wasm.global_exports.items.len;
781775
782776 if (exports_len > 0) {
783 replaceVecSectionHeader(binary_bytes, header_offset, .@"export", @intCast(exports_len));
777 replaceVecSectionHeader(&aw, header_offset, .@"export", @intCast(exports_len));
784778 section_index += 1;
785779 } else {
786 binary_bytes.shrinkRetainingCapacity(header_offset);
780 aw.shrinkRetainingCapacity(header_offset);
787781 }
788782 }
789783
790784 // start section
791785 if (wasm.functions.getIndex(.__wasm_init_memory)) |func_index| {
792 try emitStartSection(gpa, binary_bytes, .fromFunctionIndex(wasm, @enumFromInt(func_index)));
786 try emitStartSection(&aw, .fromFunctionIndex(wasm, @enumFromInt(func_index)));
793787 } else if (Wasm.OutputFunctionIndex.fromResolution(wasm, wasm.entry_resolution)) |func_index| {
794 try emitStartSection(gpa, binary_bytes, func_index);
788 try emitStartSection(&aw, func_index);
795789 }
796790
797791 // element section
798792 if (f.indirect_function_table.entries.len > 0) {
799 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
793 const header_offset = try reserveVecSectionHeader(bw);
800794
801795 // indirect function table elements
802796 const table_index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?);
803797 // passive with implicit 0-index table or set table index manually
804798 const flags: u32 = if (table_index == 0) 0x0 else 0x02;
805 try leb.writeUleb128(binary_writer, flags);
806 if (flags == 0x02) {
807 try leb.writeUleb128(binary_writer, table_index);
808 }
799 try bw.writeLeb128(flags);
800 if (flags == 0x02) try bw.writeLeb128(table_index);
809801 // We start at index 1, so unresolved function pointers are invalid
810 try emitInit(binary_writer, .{ .i32_const = 1 });
811 if (flags == 0x02) {
812 try leb.writeUleb128(binary_writer, @as(u8, 0)); // represents funcref
813 }
814 try leb.writeUleb128(binary_writer, @as(u32, @intCast(f.indirect_function_table.entries.len)));
815 for (f.indirect_function_table.keys()) |func_index| {
816 try leb.writeUleb128(binary_writer, @intFromEnum(func_index));
817 }
802 try emitInit(bw, .{ .i32_const = 1 });
803 if (flags == 0x02) try bw.writeUleb128(0); // represents funcref
804 try bw.writeLeb128(f.indirect_function_table.entries.len);
805 for (f.indirect_function_table.keys()) |func_index| try bw.writeLeb128(@intFromEnum(func_index));
818806
819 replaceVecSectionHeader(binary_bytes, header_offset, .element, 1);
807 replaceVecSectionHeader(&aw, header_offset, .element, 1);
820808 section_index += 1;
821809 }
822810
823811 // When the shared-memory option is enabled, we *must* emit the 'data count' section.
824812 if (f.data_segment_groups.items.len > 0) {
825 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
826 replaceVecSectionHeader(binary_bytes, header_offset, .data_count, @intCast(f.data_segment_groups.items.len));
813 const header_offset = try reserveVecSectionHeader(bw);
814 replaceVecSectionHeader(&aw, header_offset, .data_count, @intCast(f.data_segment_groups.items.len));
827815 }
828816
829817 // Code section.
830818 if (wasm.functions.count() != 0) {
831 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
819 const header_offset = try reserveVecSectionHeader(bw);
832820
833821 for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) {
834822 .unresolved => unreachable,
835823 .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"),
836824 .__wasm_call_ctors => {
837 const code_start = try reserveSize(gpa, binary_bytes);
838 defer replaceSize(binary_bytes, code_start);
839 try emitCallCtorsFunction(wasm, binary_bytes);
825 const code_start = try reserveSizeHeader(bw);
826 defer replaceSizeHeader(&aw, code_start);
827 try emitCallCtorsFunction(wasm, bw);
840828 },
841829 .__wasm_init_memory => {
842 const code_start = try reserveSize(gpa, binary_bytes);
843 defer replaceSize(binary_bytes, code_start);
844 try emitInitMemoryFunction(wasm, binary_bytes, &virtual_addrs);
830 const code_start = try reserveSizeHeader(bw);
831 defer replaceSizeHeader(&aw, code_start);
832 try emitInitMemoryFunction(wasm, bw, &virtual_addrs);
845833 },
846834 .__wasm_init_tls => {
847 const code_start = try reserveSize(gpa, binary_bytes);
848 defer replaceSize(binary_bytes, code_start);
849 try emitInitTlsFunction(wasm, binary_bytes);
835 const code_start = try reserveSizeHeader(bw);
836 defer replaceSizeHeader(&aw, code_start);
837 try emitInitTlsFunction(wasm, bw);
850838 },
851839 .object_function => |i| {
852840 const ptr = i.ptr(wasm);
853841 const code = ptr.code.slice(wasm);
854 try leb.writeUleb128(binary_writer, code.len);
855 const code_start = binary_bytes.items.len;
856 try binary_bytes.appendSlice(gpa, code);
857 if (!is_obj) applyRelocs(binary_bytes.items[code_start..], ptr.offset, ptr.relocations(wasm), wasm);
842 try bw.writeLeb128(code.len);
843 const code_start = bw.count;
844 try bw.writeAll(code);
845 if (!is_obj) applyRelocs(aw.getWritten()[code_start..], ptr.offset, ptr.relocations(wasm), wasm);
858846 },
859847 .zcu_func => |i| {
860 const code_start = try reserveSize(gpa, binary_bytes);
861 defer replaceSize(binary_bytes, code_start);
848 const code_start = try reserveSizeHeader(bw);
849 defer replaceSizeHeader(&aw, code_start);
862850
863851 log.debug("lowering function code for '{s}'", .{resolution.name(wasm).?});
864852
......@@ -867,7 +855,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
867855 const ip_index = i.key(wasm).*;
868856 switch (ip.indexToKey(ip_index)) {
869857 .enum_type => {
870 try emitTagNameFunction(wasm, binary_bytes, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index);
858 try emitTagNameFunction(wasm, bw, f.data_segments.get(.__zig_tag_name_table).?, i.value(wasm).tag_name.table_index, ip_index);
871859 },
872860 else => {
873861 const func = i.value(wasm).function;
......@@ -882,13 +870,13 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
882870 .func_tys = undefined,
883871 .error_name_table_ref_count = undefined,
884872 };
885 try mir.lower(wasm, binary_bytes);
873 try mir.lower(wasm, bw);
886874 },
887875 }
888876 },
889877 };
890878
891 replaceVecSectionHeader(binary_bytes, header_offset, .code, @intCast(wasm.functions.entries.len));
879 replaceVecSectionHeader(&aw, header_offset, .code, @intCast(wasm.functions.entries.len));
892880 code_section_index = section_index;
893881 section_index += 1;
894882 }
......@@ -924,7 +912,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
924912
925913 // Data section.
926914 if (f.data_segment_groups.items.len != 0) {
927 const header_offset = try reserveVecSectionHeader(gpa, binary_bytes);
915 const header_offset = try reserveVecSectionHeader(bw);
928916
929917 var group_index: u32 = 0;
930918 var segment_offset: u32 = 0;
......@@ -932,7 +920,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
932920 var group_end_addr = f.data_segment_groups.items[group_index].end_addr;
933921 for (segment_ids, segment_vaddrs) |segment_id, segment_vaddr| {
934922 if (segment_vaddr >= group_end_addr) {
935 try binary_bytes.appendNTimes(gpa, 0, group_end_addr - group_start_addr - segment_offset);
923 try bw.splatByteAll(0, group_end_addr - group_start_addr - segment_offset);
936924 group_index += 1;
937925 if (group_index >= f.data_segment_groups.items.len) {
938926 // All remaining segments are zero.
......@@ -946,12 +934,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
946934 const group_size = group_end_addr - group_start_addr;
947935 log.debug("emit data section group, {d} bytes", .{group_size});
948936 const flags: Object.DataSegmentFlags = if (segment_id.isPassive(wasm)) .passive else .active;
949 try leb.writeUleb128(binary_writer, @intFromEnum(flags));
937 try bw.writeLeb128(@intFromEnum(flags));
950938 // Passive segments are initialized at runtime.
951 if (flags != .passive) {
952 try emitInit(binary_writer, .{ .i32_const = @as(i32, @bitCast(group_start_addr)) });
953 }
954 try leb.writeUleb128(binary_writer, group_size);
939 if (flags != .passive) try emitInit(bw, .{ .i32_const = @as(i32, @bitCast(group_start_addr)) });
940 try bw.writeLeb128(group_size);
955941 }
956942 if (segment_id.isEmpty(wasm)) {
957943 // It counted for virtual memory but it does not go into the binary.
......@@ -960,62 +946,62 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
960946
961947 // Padding for alignment.
962948 const needed_offset = segment_vaddr - group_start_addr;
963 try binary_bytes.appendNTimes(gpa, 0, needed_offset - segment_offset);
949 try bw.splatByteAll(0, needed_offset - segment_offset);
964950 segment_offset = needed_offset;
965951
966 const code_start = binary_bytes.items.len;
952 const code_start = bw.count;
967953 append: {
968954 const code = switch (segment_id.unpack(wasm)) {
969955 .__heap_base => {
970 mem.writeInt(u32, try binary_bytes.addManyAsArray(gpa, 4), virtual_addrs.heap_base, .little);
956 try bw.writeInt(u32, virtual_addrs.heap_base, .little);
971957 break :append;
972958 },
973959 .__heap_end => {
974 mem.writeInt(u32, try binary_bytes.addManyAsArray(gpa, 4), virtual_addrs.heap_end, .little);
960 try bw.writeInt(u32, virtual_addrs.heap_end, .little);
975961 break :append;
976962 },
977963 .__zig_error_names => {
978 try binary_bytes.appendSlice(gpa, wasm.error_name_bytes.items);
964 try bw.writeAll(wasm.error_name_bytes.items);
979965 break :append;
980966 },
981967 .__zig_error_name_table => {
982968 if (is_obj) @panic("TODO error name table reloc");
983969 const base = f.data_segments.get(.__zig_error_names).?;
984970 if (!is64) {
985 try emitTagNameTable(gpa, binary_bytes, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u32);
971 try emitTagNameTable(bw, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u32);
986972 } else {
987 try emitTagNameTable(gpa, binary_bytes, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u64);
973 try emitTagNameTable(bw, wasm.error_name_offs.items, wasm.error_name_bytes.items, base, u64);
988974 }
989975 break :append;
990976 },
991977 .__zig_tag_names => {
992 try binary_bytes.appendSlice(gpa, wasm.tag_name_bytes.items);
978 try bw.writeAll(wasm.tag_name_bytes.items);
993979 break :append;
994980 },
995981 .__zig_tag_name_table => {
996982 if (is_obj) @panic("TODO tag name table reloc");
997983 const base = f.data_segments.get(.__zig_tag_names).?;
998984 if (!is64) {
999 try emitTagNameTable(gpa, binary_bytes, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u32);
985 try emitTagNameTable(bw, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u32);
1000986 } else {
1001 try emitTagNameTable(gpa, binary_bytes, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u64);
987 try emitTagNameTable(bw, wasm.tag_name_offs.items, wasm.tag_name_bytes.items, base, u64);
1002988 }
1003989 break :append;
1004990 },
1005991 .object => |i| {
1006992 const ptr = i.ptr(wasm);
1007 try binary_bytes.appendSlice(gpa, ptr.payload.slice(wasm));
1008 if (!is_obj) applyRelocs(binary_bytes.items[code_start..], ptr.offset, ptr.relocations(wasm), wasm);
993 try bw.writeAll(ptr.payload.slice(wasm));
994 if (!is_obj) applyRelocs(aw.getWritten()[code_start..], ptr.offset, ptr.relocations(wasm), wasm);
1009995 break :append;
1010996 },
1011997 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code,
1012998 };
1013 try binary_bytes.appendSlice(gpa, code.slice(wasm));
999 try bw.writeAll(code.slice(wasm));
10141000 }
1015 segment_offset += @intCast(binary_bytes.items.len - code_start);
1001 segment_offset += @intCast(bw.count - code_start);
10161002 }
10171003
1018 replaceVecSectionHeader(binary_bytes, header_offset, .data, @intCast(f.data_segment_groups.items.len));
1004 replaceVecSectionHeader(&aw, header_offset, .data, @intCast(f.data_segment_groups.items.len));
10191005 data_section_index = section_index;
10201006 section_index += 1;
10211007 }
......@@ -1023,7 +1009,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
10231009 if (is_obj) {
10241010 @panic("TODO emit link section for object file and emit modified relocations");
10251011 } else if (comp.config.debug_format != .strip) {
1026 try emitNameSection(wasm, f.data_segment_groups.items, binary_bytes);
1012 try emitNameSection(wasm, &aw, f.data_segment_groups.items);
10271013 }
10281014
10291015 if (comp.config.debug_format != .strip) {
......@@ -1033,17 +1019,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
10331019 .none => {},
10341020 .fast => {
10351021 var id: [16]u8 = undefined;
1036 std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
1022 std.crypto.hash.sha3.TurboShake128(null).hash(bw.getWritten(), &id, .{});
10371023 var uuid: [36]u8 = undefined;
10381024 _ = try std.fmt.bufPrint(&uuid, "{x}-{x}-{x}-{x}-{x}", .{
10391025 id[0..4], id[4..6], id[6..8], id[8..10], id[10..],
10401026 });
1041 try emitBuildIdSection(gpa, binary_bytes, &uuid);
1027 try emitBuildIdSection(&aw, &uuid);
10421028 },
10431029 .hexstring => |hs| {
10441030 var buffer: [32 * 2]u8 = undefined;
10451031 const str = std.fmt.bufPrint(&buffer, "{x}", .{hs.toSlice()}) catch unreachable;
1046 try emitBuildIdSection(gpa, binary_bytes, str);
1032 try emitBuildIdSection(&aw, str);
10471033 },
10481034 else => |mode| {
10491035 var err = try diags.addErrorWithNotes(0);
......@@ -1054,14 +1040,15 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
10541040 var debug_bytes = std.ArrayList(u8).init(gpa);
10551041 defer debug_bytes.deinit();
10561042
1057 try emitProducerSection(gpa, binary_bytes);
1058 try emitFeaturesSection(gpa, binary_bytes, target);
1043 try emitProducerSection(&aw);
1044 try emitFeaturesSection(&aw, target);
10591045 }
10601046
10611047 // Finally, write the entire binary into the file.
10621048 const file = wasm.base.file.?;
1063 try file.pwriteAll(binary_bytes.items, 0);
1064 try file.setEndPos(binary_bytes.items.len);
1049 const contents = aw.getWritten();
1050 try file.setEndPos(contents.len);
1051 try file.pwriteAll(contents, 0);
10651052}
10661053
10671054const VirtualAddrs = struct {
......@@ -1076,170 +1063,155 @@ const VirtualAddrs = struct {
10761063
10771064fn emitNameSection(
10781065 wasm: *Wasm,
1066 aw: *std.io.AllocatingWriter,
10791067 data_segment_groups: []const DataSegmentGroup,
1080 binary_bytes: *std.ArrayListUnmanaged(u8),
1081) !void {
1068) anyerror!void {
10821069 const f = &wasm.flush_buffer;
1083 const comp = wasm.base.comp;
1084 const gpa = comp.gpa;
1070 const bw = &aw.buffered_writer;
1071 const header_offset = try reserveSectionHeader(bw);
1072 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
10851073
1086 const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1087 defer writeCustomSectionHeader(binary_bytes, header_offset);
1088
1089 const name_name = "name";
1090 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, name_name.len));
1091 try binary_bytes.appendSlice(gpa, name_name);
1074 const section_name = "name";
1075 try bw.writeLeb128(section_name.len);
1076 try bw.writeAll(section_name);
10921077
10931078 {
1094 const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1095 defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.function));
1096
1097 const total_functions: u32 = @intCast(f.function_imports.entries.len + wasm.functions.entries.len);
1098 try leb.writeUleb128(binary_bytes.writer(gpa), total_functions);
1079 const sub_header_offset = try reserveSectionHeader(bw);
1080 defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.function));
10991081
1082 try bw.writeLeb128(f.function_imports.entries.len + wasm.functions.entries.len);
11001083 for (f.function_imports.keys(), 0..) |name_index, function_index| {
11011084 const name = name_index.slice(wasm);
1102 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(function_index)));
1103 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
1104 try binary_bytes.appendSlice(gpa, name);
1085 try bw.writeLeb128(function_index);
1086 try bw.writeLeb128(name.len);
1087 try bw.writeAll(name);
11051088 }
11061089 for (wasm.functions.keys(), f.function_imports.entries.len..) |resolution, function_index| {
11071090 const name = resolution.name(wasm).?;
1108 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(function_index)));
1109 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
1110 try binary_bytes.appendSlice(gpa, name);
1091 try bw.writeLeb128(function_index);
1092 try bw.writeLeb128(name.len);
1093 try bw.writeAll(name);
11111094 }
11121095 }
11131096
11141097 {
1115 const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1116 defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.global));
1117
1118 const total_globals: u32 = @intCast(f.global_imports.entries.len + wasm.globals.entries.len);
1119 try leb.writeUleb128(binary_bytes.writer(gpa), total_globals);
1098 const sub_header_offset = try reserveSectionHeader(bw);
1099 defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.global));
11201100
1101 try bw.writeLeb128(f.global_imports.entries.len + wasm.globals.entries.len);
11211102 for (f.global_imports.keys(), 0..) |name_index, global_index| {
11221103 const name = name_index.slice(wasm);
1123 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(global_index)));
1124 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
1125 try binary_bytes.appendSlice(gpa, name);
1104 try bw.writeLeb128(global_index);
1105 try bw.writeLeb128(name.len);
1106 try bw.writeAll(name);
11261107 }
11271108 for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| {
11281109 const name = resolution.name(wasm).?;
1129 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(global_index)));
1130 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
1131 try binary_bytes.appendSlice(gpa, name);
1110 try bw.writeLeb128(global_index);
1111 try bw.writeLeb128(name.len);
1112 try bw.writeAll(name);
11321113 }
11331114 }
11341115
11351116 {
1136 const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1137 defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.data_segment));
1117 const sub_header_offset = try reserveSectionHeader(bw);
1118 defer replaceSectionHeader(aw, sub_header_offset, @intFromEnum(std.wasm.NameSubsection.data_segment));
11381119
1139 const total_data_segments: u32 = @intCast(data_segment_groups.len);
1140 try leb.writeUleb128(binary_bytes.writer(gpa), total_data_segments);
1141
1142 for (data_segment_groups, 0..) |group, i| {
1120 try bw.writeLeb128(data_segment_groups.len);
1121 for (data_segment_groups, 0..) |group, group_index| {
11431122 const name, _ = splitSegmentName(group.first_segment.name(wasm));
1144 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(i)));
1145 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
1146 try binary_bytes.appendSlice(gpa, name);
1123 try bw.writeLeb128(group_index);
1124 try bw.writeLeb128(name.len);
1125 try bw.writeAll(name);
11471126 }
11481127 }
11491128}
11501129
1151fn emitFeaturesSection(
1152 gpa: Allocator,
1153 binary_bytes: *std.ArrayListUnmanaged(u8),
1154 target: *const std.Target,
1155) Allocator.Error!void {
1130fn emitFeaturesSection(aw: *std.io.AllocatingWriter, target: *const std.Target) anyerror!void {
11561131 const feature_count = target.cpu.features.count();
11571132 if (feature_count == 0) return;
11581133
1159 const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1160 defer writeCustomSectionHeader(binary_bytes, header_offset);
1161
1162 const writer = binary_bytes.writer(gpa);
1163 const target_features = "target_features";
1164 try leb.writeUleb128(writer, @as(u32, @intCast(target_features.len)));
1165 try writer.writeAll(target_features);
1134 const bw = &aw.buffered_writer;
1135 const header_offset = try reserveSectionHeader(bw);
1136 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
11661137
1167 try leb.writeUleb128(writer, @as(u32, @intCast(feature_count)));
1138 const section_name = "target_features";
1139 try bw.writeLeb128(section_name.len);
1140 try bw.writeAll(section_name);
11681141
1142 try bw.writeLeb128(feature_count);
11691143 var safety_count = feature_count;
11701144 for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| {
11711145 if (!target.cpu.has(.wasm, @as(std.Target.wasm.Feature, @enumFromInt(i)))) continue;
11721146 safety_count -= 1;
11731147
1174 try leb.writeUleb128(writer, @as(u32, '+'));
1148 try bw.writeUleb128('+');
11751149 // Depends on llvm_name for the hyphenated version that matches wasm tooling conventions.
11761150 const name = feature.llvm_name.?;
1177 try leb.writeUleb128(writer, @as(u32, @intCast(name.len)));
1178 try writer.writeAll(name);
1151 try bw.writeLeb128(name.len);
1152 try bw.writeAll(name);
11791153 }
11801154 assert(safety_count == 0);
11811155}
11821156
1183fn emitBuildIdSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8), build_id: []const u8) !void {
1184 const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1185 defer writeCustomSectionHeader(binary_bytes, header_offset);
1157fn emitBuildIdSection(aw: *std.io.AllocatingWriter, build_id: []const u8) !void {
1158 const bw = &aw.buffered_writer;
1159 const header_offset = try reserveSectionHeader(bw);
1160 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
11861161
1187 const writer = binary_bytes.writer(gpa);
1188 const hdr_build_id = "build_id";
1189 try leb.writeUleb128(writer, @as(u32, @intCast(hdr_build_id.len)));
1190 try writer.writeAll(hdr_build_id);
1162 const section_name = "build_id";
1163 try bw.writeLeb128(section_name.len);
1164 try bw.writeAll(section_name);
11911165
1192 try leb.writeUleb128(writer, @as(u32, 1));
1193 try leb.writeUleb128(writer, @as(u32, @intCast(build_id.len)));
1194 try writer.writeAll(build_id);
1166 try bw.writeUleb128(1);
1167 try bw.writeLeb128(build_id.len);
1168 try bw.writeAll(build_id);
11951169}
11961170
1197fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8)) !void {
1198 const header_offset = try reserveCustomSectionHeader(gpa, binary_bytes);
1199 defer writeCustomSectionHeader(binary_bytes, header_offset);
1200
1201 const writer = binary_bytes.writer(gpa);
1202 const producers = "producers";
1203 try leb.writeUleb128(writer, @as(u32, @intCast(producers.len)));
1204 try writer.writeAll(producers);
1171fn emitProducerSection(aw: *std.io.AllocatingWriter) !void {
1172 const bw = &aw.buffered_writer;
1173 const header_offset = try reserveSectionHeader(bw);
1174 defer replaceSectionHeader(aw, header_offset, @intFromEnum(std.wasm.Section.custom));
12051175
1206 try leb.writeUleb128(writer, @as(u32, 2)); // 2 fields: Language + processed-by
1176 const section_name = "producers";
1177 try bw.writeLeb128(section_name.len);
1178 try bw.writeAll(section_name);
12071179
1208 // language field
1180 try bw.writeUleb128(2); // 2 fields: language + processed-by
12091181 {
1210 const language = "language";
1211 try leb.writeUleb128(writer, @as(u32, @intCast(language.len)));
1212 try writer.writeAll(language);
1182 const field_name = "language";
1183 try bw.writeLeb128(field_name.len);
1184 try bw.writeAll(field_name);
12131185
12141186 // field_value_count (TODO: Parse object files for producer sections to detect their language)
1215 try leb.writeUleb128(writer, @as(u32, 1));
1187 try bw.writeUleb128(1);
12161188
12171189 // versioned name
12181190 {
1219 try leb.writeUleb128(writer, @as(u32, 3)); // len of "Zig"
1220 try writer.writeAll("Zig");
1191 const field_value = "Zig";
1192 try bw.writeLeb128(field_value.len);
1193 try bw.writeAll(field_value);
12211194
1222 try leb.writeUleb128(writer, @as(u32, @intCast(build_options.version.len)));
1223 try writer.writeAll(build_options.version);
1195 try bw.writeLeb128(build_options.version.len);
1196 try bw.writeAll(build_options.version);
12241197 }
12251198 }
1226
1227 // processed-by field
12281199 {
1229 const processed_by = "processed-by";
1230 try leb.writeUleb128(writer, @as(u32, @intCast(processed_by.len)));
1231 try writer.writeAll(processed_by);
1200 const field_name = "processed-by";
1201 try bw.writeLeb128(field_name.len);
1202 try bw.writeAll(field_name);
12321203
12331204 // field_value_count (TODO: Parse object files for producer sections to detect other used tools)
1234 try leb.writeUleb128(writer, @as(u32, 1));
1205 try bw.writeUleb128(1);
12351206
12361207 // versioned name
12371208 {
1238 try leb.writeUleb128(writer, @as(u32, 3)); // len of "Zig"
1239 try writer.writeAll("Zig");
1209 const field_value = "Zig";
1210 try bw.writeLeb128(field_value.len);
1211 try bw.writeAll(field_value);
12401212
1241 try leb.writeUleb128(writer, @as(u32, @intCast(build_options.version.len)));
1242 try writer.writeAll(build_options.version);
1213 try bw.writeLeb128(build_options.version.len);
1214 try bw.writeAll(build_options.version);
12431215 }
12441216 }
12451217}
......@@ -1277,170 +1249,133 @@ fn wantSegmentMerge(
12771249}
12781250
12791251/// section id + fixed leb contents size + fixed leb vector length
1280const section_header_reserve_size = 1 + 5 + 5;
1281const section_header_size = 5 + 1;
1252const vec_section_header_size = section_header_size + size_header_size;
12821253
1283fn reserveVecSectionHeader(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!u32 {
1284 try bytes.appendNTimes(gpa, 0, section_header_reserve_size);
1285 return @intCast(bytes.items.len - section_header_reserve_size);
1254fn reserveVecSectionHeader(bw: *std.io.BufferedWriter) anyerror!u32 {
1255 const offset = bw.count;
1256 _ = try bw.writableSlice(vec_section_header_size);
1257 bw.advance(vec_section_header_size);
1258 return @intCast(offset);
12861259}
12871260
12881261fn replaceVecSectionHeader(
1289 bytes: *std.ArrayListUnmanaged(u8),
1262 aw: *std.io.AllocatingWriter,
12901263 offset: u32,
12911264 section: std.wasm.Section,
12921265 n_items: u32,
12931266) void {
1294 const size: u32 = @intCast(bytes.items.len - offset - section_header_reserve_size + uleb128size(n_items));
1295 var buf: [section_header_reserve_size]u8 = undefined;
1296 var fbw = std.io.fixedBufferStream(&buf);
1297 const w = fbw.writer();
1298 w.writeByte(@intFromEnum(section)) catch unreachable;
1299 leb.writeUleb128(w, size) catch unreachable;
1300 leb.writeUleb128(w, n_items) catch unreachable;
1301 bytes.replaceRangeAssumeCapacity(offset, section_header_reserve_size, fbw.getWritten());
1267 const header = aw.getWritten()[offset..][0..vec_section_header_size];
1268 header[0] = @intFromEnum(section);
1269 std.leb.writeUnsignedFixed(5, header[1..6], @intCast(aw.buffered_writer.count - offset - section_header_size));
1270 std.leb.writeUnsignedFixed(5, header[6..], n_items);
13021271}
13031272
1304fn reserveCustomSectionHeader(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!u32 {
1305 try bytes.appendNTimes(gpa, 0, section_header_size);
1306 return @intCast(bytes.items.len - section_header_size);
1307}
1273const section_header_size = 1 + size_header_size;
13081274
1309fn writeCustomSectionHeader(bytes: *std.ArrayListUnmanaged(u8), offset: u32) void {
1310 return replaceHeader(bytes, offset, 0); // 0 = 'custom' section
1275fn reserveSectionHeader(bw: *std.io.BufferedWriter) anyerror!u32 {
1276 const offset = bw.count;
1277 _ = try bw.writableSlice(section_header_size);
1278 bw.advance(section_header_size);
1279 return @intCast(offset);
13111280}
13121281
1313fn replaceHeader(bytes: *std.ArrayListUnmanaged(u8), offset: u32, tag: u8) void {
1314 const size: u32 = @intCast(bytes.items.len - offset - section_header_size);
1315 var buf: [section_header_size]u8 = undefined;
1316 var fbw = std.io.fixedBufferStream(&buf);
1317 const w = fbw.writer();
1318 w.writeByte(tag) catch unreachable;
1319 leb.writeUleb128(w, size) catch unreachable;
1320 bytes.replaceRangeAssumeCapacity(offset, section_header_size, fbw.getWritten());
1282fn replaceSectionHeader(aw: *std.io.AllocatingWriter, offset: u32, section: u8) void {
1283 const header = aw.getWritten()[offset..][0..section_header_size];
1284 header[0] = section;
1285 std.leb.writeUnsignedFixed(5, header[1..6], @intCast(aw.buffered_writer.count - offset - section_header_size));
13211286}
13221287
1323const max_size_encoding = 5;
1288const size_header_size = 5;
13241289
1325fn reserveSize(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!u32 {
1326 try bytes.appendNTimes(gpa, 0, max_size_encoding);
1327 return @intCast(bytes.items.len - max_size_encoding);
1290fn reserveSizeHeader(bw: *std.io.BufferedWriter) anyerror!u32 {
1291 const offset = bw.count;
1292 _ = try bw.writableSlice(size_header_size);
1293 bw.advance(size_header_size);
1294 return @intCast(offset);
13281295}
13291296
1330fn replaceSize(bytes: *std.ArrayListUnmanaged(u8), offset: u32) void {
1331 const size: u32 = @intCast(bytes.items.len - offset - max_size_encoding);
1332 var buf: [max_size_encoding]u8 = undefined;
1333 var fbw = std.io.fixedBufferStream(&buf);
1334 leb.writeUleb128(fbw.writer(), size) catch unreachable;
1335 bytes.replaceRangeAssumeCapacity(offset, max_size_encoding, fbw.getWritten());
1297fn replaceSizeHeader(aw: *std.io.AllocatingWriter, offset: u32) void {
1298 const header = aw.getWritten()[offset..][0..size_header_size];
1299 std.leb.writeUnsignedFixed(5, header[0..5], @intCast(aw.buffered_writer.count - offset - size_header_size));
13361300}
13371301
1338fn emitLimits(
1339 gpa: Allocator,
1340 binary_bytes: *std.ArrayListUnmanaged(u8),
1341 limits: std.wasm.Limits,
1342) Allocator.Error!void {
1343 try binary_bytes.append(gpa, @bitCast(limits.flags));
1344 try leb.writeUleb128(binary_bytes.writer(gpa), limits.min);
1345 if (limits.flags.has_max) try leb.writeUleb128(binary_bytes.writer(gpa), limits.max);
1302fn emitLimits(bw: *std.io.BufferedWriter, limits: std.wasm.Limits) anyerror!void {
1303 try bw.writeByte(@bitCast(limits.flags));
1304 try bw.writeLeb128(limits.min);
1305 if (limits.flags.has_max) try bw.writeLeb128(limits.max);
13461306}
13471307
13481308fn emitMemoryImport(
13491309 wasm: *Wasm,
1350 binary_bytes: *std.ArrayListUnmanaged(u8),
1310 bw: *std.io.BufferedWriter,
13511311 name_index: String,
13521312 memory_import: *const Wasm.MemoryImport,
1353) Allocator.Error!void {
1354 const gpa = wasm.base.comp.gpa;
1313) anyerror!void {
13551314 const module_name = memory_import.module_name.slice(wasm);
1356 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(module_name.len)));
1357 try binary_bytes.appendSlice(gpa, module_name);
1315 try bw.writeLeb128(module_name.len);
1316 try bw.writeAll(module_name);
13581317
13591318 const name = name_index.slice(wasm);
1360 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
1361 try binary_bytes.appendSlice(gpa, name);
1319 try bw.writeLeb128(name.len);
1320 try bw.writeAll(name);
13621321
1363 try binary_bytes.append(gpa, @intFromEnum(std.wasm.ExternalKind.memory));
1364 try emitLimits(gpa, binary_bytes, memory_import.limits());
1322 try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.memory));
1323 try emitLimits(bw, memory_import.limits());
13651324}
13661325
1367pub fn emitInit(writer: anytype, init_expr: std.wasm.InitExpression) !void {
1326pub fn emitInit(bw: *std.io.BufferedWriter, init_expr: std.wasm.InitExpression) anyerror!void {
13681327 switch (init_expr) {
1369 .i32_const => |val| {
1370 try writer.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1371 try leb.writeIleb128(writer, val);
1372 },
1373 .i64_const => |val| {
1374 try writer.writeByte(@intFromEnum(std.wasm.Opcode.i64_const));
1375 try leb.writeIleb128(writer, val);
1376 },
1377 .f32_const => |val| {
1378 try writer.writeByte(@intFromEnum(std.wasm.Opcode.f32_const));
1379 try writer.writeInt(u32, @bitCast(val), .little);
1380 },
1381 .f64_const => |val| {
1382 try writer.writeByte(@intFromEnum(std.wasm.Opcode.f64_const));
1383 try writer.writeInt(u64, @bitCast(val), .little);
1384 },
1385 .global_get => |val| {
1386 try writer.writeByte(@intFromEnum(std.wasm.Opcode.global_get));
1387 try leb.writeUleb128(writer, val);
1328 inline else => |val, tag| {
1329 try bw.writeByte(@intFromEnum(@field(std.wasm.Opcode, @tagName(tag))));
1330 switch (@typeInfo(@TypeOf(val))) {
1331 .int => try bw.writeLeb128(val),
1332 .float => |float| try bw.writeInt(
1333 @Type(.{ .int = .{ .signedness = .unsigned, .bits = float.bits } }),
1334 @bitCast(val),
1335 .little,
1336 ),
1337 else => comptime unreachable,
1338 }
13881339 },
13891340 }
1390 try writer.writeByte(@intFromEnum(std.wasm.Opcode.end));
1341 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
13911342}
13921343
1393pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), expr: Wasm.Expr) Allocator.Error!void {
1394 const gpa = wasm.base.comp.gpa;
1344pub fn emitExpr(wasm: *const Wasm, bw: *std.io.BufferedWriter, expr: Wasm.Expr) anyerror!void {
13951345 const slice = expr.slice(wasm);
1396 try binary_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); // +1 to include end opcode
1346 try bw.writeAll(slice[0 .. slice.len + 1]); // +1 to include end opcode
13971347}
13981348
1399fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void {
1400 const gpa = wasm.base.comp.gpa;
1401 const writer = binary_bytes.writer(gpa);
1402 try leb.writeUleb128(writer, @intFromEnum(Wasm.SubsectionType.segment_info));
1403 const segment_offset = binary_bytes.items.len;
1349fn emitSegmentInfo(wasm: *Wasm, aw: *std.io.BufferedWriter) anyerror!void {
1350 const bw = &aw.buffered_writer;
1351 const header_offset = try reserveSectionHeader(bw);
1352 defer replaceSectionHeader(aw, header_offset, @intFromEnum(Wasm.SubsectionType.segment_info));
14041353
1405 try leb.writeUleb128(writer, @as(u32, @intCast(wasm.segment_info.count())));
1354 try bw.writeLeb128(wasm.segment_info.count());
14061355 for (wasm.segment_info.values()) |segment_info| {
14071356 log.debug("Emit segment: {s} align({d}) flags({b})", .{
14081357 segment_info.name,
14091358 segment_info.alignment,
14101359 segment_info.flags,
14111360 });
1412 try leb.writeUleb128(writer, @as(u32, @intCast(segment_info.name.len)));
1413 try writer.writeAll(segment_info.name);
1414 try leb.writeUleb128(writer, segment_info.alignment.toLog2Units());
1415 try leb.writeUleb128(writer, segment_info.flags);
1361 try bw.writeLeb128(segment_info.name.len);
1362 try bw.writeAll(segment_info.name);
1363 try bw.writeLeb128(segment_info.alignment.toLog2Units());
1364 try bw.writeLeb128(segment_info.flags);
14161365 }
1417
1418 var buf: [5]u8 = undefined;
1419 leb.writeUnsignedFixed(5, &buf, @as(u32, @intCast(binary_bytes.items.len - segment_offset)));
1420 try binary_bytes.insertSlice(segment_offset, &buf);
1421}
1422
1423fn uleb128size(x: u32) u32 {
1424 var value = x;
1425 var size: u32 = 0;
1426 while (value != 0) : (size += 1) value >>= 7;
1427 return size;
14281366}
14291367
14301368fn emitTagNameTable(
1431 gpa: Allocator,
1432 code: *std.ArrayListUnmanaged(u8),
1369 bw: *std.io.BufferedWriter,
14331370 tag_name_offs: []const u32,
14341371 tag_name_bytes: []const u8,
14351372 base: u32,
14361373 comptime Int: type,
1437) error{OutOfMemory}!void {
1438 const ptr_size_bytes = @divExact(@bitSizeOf(Int), 8);
1439 try code.ensureUnusedCapacity(gpa, ptr_size_bytes * 2 * tag_name_offs.len);
1374) anyerror!void {
14401375 for (tag_name_offs) |off| {
14411376 const name_len: u32 = @intCast(mem.indexOfScalar(u8, tag_name_bytes[off..], 0).?);
1442 mem.writeInt(Int, code.addManyAsArrayAssumeCapacity(ptr_size_bytes), base + off, .little);
1443 mem.writeInt(Int, code.addManyAsArrayAssumeCapacity(ptr_size_bytes), name_len, .little);
1377 try bw.writeInt(Int, base + off, .little);
1378 try bw.writeInt(Int, name_len, .little);
14441379 }
14451380}
14461381
......@@ -1525,11 +1460,11 @@ fn reloc_u64_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
15251460}
15261461
15271462fn reloc_sleb_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
1528 leb.writeSignedFixed(5, code[0..5], i.toAbi());
1463 std.leb.writeSignedFixed(5, code[0..5], i.toAbi());
15291464}
15301465
15311466fn reloc_sleb64_table_index(code: []u8, i: IndirectFunctionTableIndex) void {
1532 leb.writeSignedFixed(11, code[0..11], i.toAbi());
1467 std.leb.writeSignedFixed(11, code[0..11], i.toAbi());
15331468}
15341469
15351470fn reloc_u32_function(code: []u8, function: Wasm.OutputFunctionIndex) void {
......@@ -1537,7 +1472,7 @@ fn reloc_u32_function(code: []u8, function: Wasm.OutputFunctionIndex) void {
15371472}
15381473
15391474fn reloc_leb_function(code: []u8, function: Wasm.OutputFunctionIndex) void {
1540 leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(function));
1475 std.leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(function));
15411476}
15421477
15431478fn reloc_u32_global(code: []u8, global: Wasm.GlobalIndex) void {
......@@ -1545,7 +1480,7 @@ fn reloc_u32_global(code: []u8, global: Wasm.GlobalIndex) void {
15451480}
15461481
15471482fn reloc_leb_global(code: []u8, global: Wasm.GlobalIndex) void {
1548 leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(global));
1483 std.leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(global));
15491484}
15501485
15511486const RelocAddr = struct {
......@@ -1581,35 +1516,31 @@ fn reloc_u64_addr(code: []u8, ra: RelocAddr) void {
15811516}
15821517
15831518fn reloc_leb_addr(code: []u8, ra: RelocAddr) void {
1584 leb.writeUnsignedFixed(5, code[0..5], ra.addr);
1519 std.leb.writeUnsignedFixed(5, code[0..5], ra.addr);
15851520}
15861521
15871522fn reloc_leb64_addr(code: []u8, ra: RelocAddr) void {
1588 leb.writeUnsignedFixed(11, code[0..11], ra.addr);
1523 std.leb.writeUnsignedFixed(11, code[0..11], ra.addr);
15891524}
15901525
15911526fn reloc_sleb_addr(code: []u8, ra: RelocAddr) void {
1592 leb.writeSignedFixed(5, code[0..5], ra.addr);
1527 std.leb.writeSignedFixed(5, code[0..5], ra.addr);
15931528}
15941529
15951530fn reloc_sleb64_addr(code: []u8, ra: RelocAddr) void {
1596 leb.writeSignedFixed(11, code[0..11], ra.addr);
1531 std.leb.writeSignedFixed(11, code[0..11], ra.addr);
15971532}
15981533
15991534fn reloc_leb_table(code: []u8, table: Wasm.TableIndex) void {
1600 leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(table));
1535 std.leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(table));
16011536}
16021537
16031538fn reloc_leb_type(code: []u8, index: FuncTypeIndex) void {
1604 leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index));
1539 std.leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index));
16051540}
16061541
1607fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!void {
1608 const gpa = wasm.base.comp.gpa;
1609
1610 try binary_bytes.ensureUnusedCapacity(gpa, 5 + 1);
1611 appendReservedUleb32(binary_bytes, 0); // no locals
1612
1542fn emitCallCtorsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) anyerror!void {
1543 try bw.writeUleb128(0); // no locals
16131544 for (wasm.object_init_funcs.items) |init_func| {
16141545 const func = init_func.function_index.ptr(wasm);
16151546 if (!func.object_index.ptr(wasm).is_included) continue;
......@@ -1617,25 +1548,18 @@ fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanage
16171548 const n_returns = ty.returns.slice(wasm).len;
16181549
16191550 // Call function by its function index
1620 try binary_bytes.ensureUnusedCapacity(gpa, 1 + 5 + n_returns + 1);
16211551 const call_index: Wasm.OutputFunctionIndex = .fromObjectFunction(wasm, init_func.function_index);
1622 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call));
1623 appendReservedUleb32(binary_bytes, @intFromEnum(call_index));
1552 try bw.writeByte(@intFromEnum(std.wasm.Opcode.call));
1553 try bw.writeLeb128(@intFromEnum(call_index));
16241554
16251555 // drop all returned values from the stack as __wasm_call_ctors has no return value
1626 binary_bytes.appendNTimesAssumeCapacity(@intFromEnum(std.wasm.Opcode.drop), n_returns);
1556 try bw.splatByteAll(@intFromEnum(std.wasm.Opcode.drop), n_returns);
16271557 }
1628
1629 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); // end function body
1558 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end function body
16301559}
16311560
1632fn emitInitMemoryFunction(
1633 wasm: *const Wasm,
1634 binary_bytes: *std.ArrayListUnmanaged(u8),
1635 virtual_addrs: *const VirtualAddrs,
1636) Allocator.Error!void {
1561fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual_addrs: *const VirtualAddrs) anyerror!void {
16371562 const comp = wasm.base.comp;
1638 const gpa = comp.gpa;
16391563 const shared_memory = comp.config.shared_memory;
16401564
16411565 // Passive segments are used to avoid memory being reinitialized on each
......@@ -1645,39 +1569,40 @@ fn emitInitMemoryFunction(
16451569 // function.
16461570 assert(wasm.any_passive_inits);
16471571
1648 try binary_bytes.ensureUnusedCapacity(gpa, 5 + 1);
1649 appendReservedUleb32(binary_bytes, 0); // no locals
1572 try bw.writeUleb128(0); // no locals
16501573
16511574 if (virtual_addrs.init_memory_flag) |flag_address| {
16521575 assert(shared_memory);
1653 try binary_bytes.ensureUnusedCapacity(gpa, 2 * 3 + 6 * 3 + 1 + 6 * 3 + 1 + 5 * 4 + 1 + 1);
16541576 // destination blocks
16551577 // based on values we jump to corresponding label
1656 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block)); // $drop
1657 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty));
1658
1659 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block)); // $wait
1660 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty));
1661
1662 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block)); // $init
1663 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty));
1578 try bw.writeAll(&.{
1579 @intFromEnum(std.wasm.Opcode.block), // $drop
1580 @intFromEnum(std.wasm.BlockType.empty),
1581 @intFromEnum(std.wasm.Opcode.block), // $wait
1582 @intFromEnum(std.wasm.BlockType.empty),
1583 @intFromEnum(std.wasm.Opcode.block), // $init
1584 @intFromEnum(std.wasm.BlockType.empty),
1585 });
16641586
16651587 // atomically check
1666 appendReservedI32Const(binary_bytes, flag_address);
1667 appendReservedI32Const(binary_bytes, 0);
1668 appendReservedI32Const(binary_bytes, 1);
1669 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1670 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_rmw_cmpxchg));
1671 appendReservedUleb32(binary_bytes, 2); // alignment
1672 appendReservedUleb32(binary_bytes, 0); // offset
1588 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1589 try bw.writeLeb128(@as(i32, @bitCast(flag_address)));
1590 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1591 try bw.writeSleb128(0);
1592 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1593 try bw.writeSleb128(1);
1594 try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1595 try bw.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_rmw_cmpxchg));
1596 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1597 try bw.writeUleb128(0); // offset
16731598
16741599 // based on the value from the atomic check, jump to the label.
1675 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_table));
1676 appendReservedUleb32(binary_bytes, 2); // length of the table (we have 3 blocks but because of the mandatory default the length is 2).
1677 appendReservedUleb32(binary_bytes, 0); // $init
1678 appendReservedUleb32(binary_bytes, 1); // $wait
1679 appendReservedUleb32(binary_bytes, 2); // $drop
1680 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1600 try bw.writeByte(@intFromEnum(std.wasm.Opcode.br_table));
1601 try bw.writeUleb128(3 - 1); // length of the table (we have 3 blocks but because of the mandatory default the length is 2).
1602 try bw.writeUleb128(0); // $init
1603 try bw.writeUleb128(1); // $wait
1604 try bw.writeUleb128(2); // $drop
1605 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
16811606 }
16821607
16831608 const segment_groups = wasm.flush_buffer.data_segment_groups.items;
......@@ -1690,74 +1615,82 @@ fn emitInitMemoryFunction(
16901615 const start_addr: u32 = @intCast(segment.alignment(wasm).forward(prev_end));
16911616 const segment_size: u32 = group.end_addr - start_addr;
16921617
1693 try binary_bytes.ensureUnusedCapacity(gpa, 6 + 6 + 1 + 5 + 6 + 6 + 1 + 6 * 2 + 1 + 1);
1694
16951618 // For passive BSS segments we can simply issue a memory.fill(0). For
16961619 // non-BSS segments we do a memory.init. Both instructions take as
16971620 // their first argument the destination address.
1698 appendReservedI32Const(binary_bytes, start_addr);
1621 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1622 try bw.writeLeb128(@as(i32, @bitCast(start_addr)));
16991623
17001624 if (shared_memory and segment.isTls(wasm)) {
17011625 // When we initialize the TLS segment we also set the `__tls_base`
17021626 // global. This allows the runtime to use this static copy of the
17031627 // TLS data for the first/main thread.
1704 appendReservedI32Const(binary_bytes, start_addr);
1705 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_set));
1706 appendReservedUleb32(binary_bytes, virtual_addrs.tls_base.?);
1628 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1629 try bw.writeLeb128(@as(i32, @bitCast(start_addr)));
1630 try bw.writeByte(@intFromEnum(std.wasm.Opcode.global_set));
1631 try bw.writeLeb128(virtual_addrs.tls_base.?);
17071632 }
17081633
1709 appendReservedI32Const(binary_bytes, 0);
1710 appendReservedI32Const(binary_bytes, segment_size);
1711 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.misc_prefix));
1634 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1635 try bw.writeSleb128(0);
1636 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1637 try bw.writeLeb128(@as(i32, @bitCast(segment_size)));
1638 try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix));
17121639 if (segment.isBss(wasm)) {
17131640 // fill bss segment with zeroes
1714 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.MiscOpcode.memory_fill));
1641 try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_fill));
17151642 } else {
17161643 // initialize the segment
1717 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.MiscOpcode.memory_init));
1718 appendReservedUleb32(binary_bytes, @intCast(segment_index));
1644 try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_init));
1645 try bw.writeLeb128(segment_index);
17191646 }
1720 binary_bytes.appendAssumeCapacity(0); // memory index immediate
1647 try bw.writeByte(0); // memory index immediate
17211648 }
17221649
17231650 if (virtual_addrs.init_memory_flag) |flag_address| {
17241651 assert(shared_memory);
1725 try binary_bytes.ensureUnusedCapacity(gpa, 6 + 6 + 1 + 3 * 5 + 6 + 1 + 5 + 1 + 3 * 5 + 1 + 1 + 5 + 1 + 6 * 2 + 1 + 5 + 1 + 3 * 5 + 1 + 1 + 1);
1652
17261653 // we set the init memory flag to value '2'
1727 appendReservedI32Const(binary_bytes, flag_address);
1728 appendReservedI32Const(binary_bytes, 2);
1729 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1730 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_store));
1731 appendReservedUleb32(binary_bytes, @as(u32, 2)); // alignment
1732 appendReservedUleb32(binary_bytes, @as(u32, 0)); // offset
1654 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1655 try bw.writeLeb128(@as(i32, @bitCast(flag_address)));
1656 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1657 try bw.writeSleb128(2);
1658 try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1659 try bw.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.i32_atomic_store));
1660 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1661 try bw.writeUleb128(0); // offset
17331662
17341663 // notify any waiters for segment initialization completion
1735 appendReservedI32Const(binary_bytes, flag_address);
1736 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1737 leb.writeIleb128(binary_bytes.fixedWriter(), @as(i32, -1)) catch unreachable; // number of waiters
1738 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1739 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_notify));
1740 appendReservedUleb32(binary_bytes, @as(u32, 2)); // alignment
1741 appendReservedUleb32(binary_bytes, @as(u32, 0)); // offset
1742 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.drop));
1664 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1665 try bw.writeLeb128(@as(i32, @bitCast(flag_address)));
1666 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1667 try bw.writeSleb128(-1); // number of waiters
1668
1669 try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1670 try bw.writeLeb128(@intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_notify));
1671 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1672 try bw.writeUleb128(0); // offset
1673 try bw.writeByte(@intFromEnum(std.wasm.Opcode.drop));
17431674
17441675 // branch and drop segments
1745 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br));
1746 appendReservedUleb32(binary_bytes, @as(u32, 1));
1676 try bw.writeByte(@intFromEnum(std.wasm.Opcode.br));
1677 try bw.writeUleb128(1);
17471678
17481679 // wait for thread to initialize memory segments
1749 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); // end $wait
1750 appendReservedI32Const(binary_bytes, flag_address);
1751 appendReservedI32Const(binary_bytes, 1); // expected flag value
1752 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
1753 leb.writeIleb128(binary_bytes.fixedWriter(), @as(i64, -1)) catch unreachable; // timeout
1754 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1755 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_wait32));
1756 appendReservedUleb32(binary_bytes, @as(u32, 2)); // alignment
1757 appendReservedUleb32(binary_bytes, @as(u32, 0)); // offset
1758 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.drop));
1759
1760 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); // end $drop
1680 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end $wait
1681 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1682 try bw.writeLeb128(@as(i32, @bitCast(flag_address)));
1683 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1684 try bw.writeSleb128(1); // expected flag value
1685 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_const));
1686 try bw.writeSleb128(-1); // timeout
1687 try bw.writeByte(@intFromEnum(std.wasm.Opcode.atomics_prefix));
1688 try bw.writeByte(@intFromEnum(std.wasm.AtomicsOpcode.memory_atomic_wait32));
1689 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1690 try bw.writeUleb128(0); // offset
1691 try bw.writeByte(@intFromEnum(std.wasm.Opcode.drop));
1692
1693 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); // end $drop
17611694 }
17621695
17631696 for (segment_groups, 0..) |group, segment_index| {
......@@ -1768,26 +1701,20 @@ fn emitInitMemoryFunction(
17681701 // during the initialization of each thread (__wasm_init_tls).
17691702 if (shared_memory and segment.isTls(wasm)) continue;
17701703
1771 try binary_bytes.ensureUnusedCapacity(gpa, 1 + 5 + 5 + 1);
1772
1773 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.misc_prefix));
1774 appendReservedUleb32(binary_bytes, @intFromEnum(std.wasm.MiscOpcode.data_drop));
1775 appendReservedUleb32(binary_bytes, @intCast(segment_index));
1704 try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix));
1705 try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.data_drop));
1706 try bw.writeLeb128(segment_index);
17761707 }
17771708
17781709 // End of the function body
1779 binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1710 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
17801711}
17811712
1782fn emitInitTlsFunction(wasm: *const Wasm, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!void {
1713fn emitInitTlsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) anyerror!void {
17831714 const comp = wasm.base.comp;
1784 const gpa = comp.gpa;
1785
17861715 assert(comp.config.shared_memory);
17871716
1788 try bytes.ensureUnusedCapacity(gpa, 5 * 10 + 8);
1789
1790 appendReservedUleb32(bytes, 0); // no locals
1717 try bw.writeUleb128(0); // no locals
17911718
17921719 // If there's a TLS segment, initialize it during runtime using the bulk-memory feature
17931720 // TLS segment is always the first one due to how we sort the data segments.
......@@ -1796,36 +1723,35 @@ fn emitInitTlsFunction(wasm: *const Wasm, bytes: *std.ArrayListUnmanaged(u8)) Al
17961723 const start_addr = wasm.flush_buffer.data_segments.values()[0];
17971724 const end_addr = wasm.flush_buffer.data_segment_groups.items[0].end_addr;
17981725 const group_size = end_addr - start_addr;
1799 const data_segment_index = 0;
1726 const data_segment_index: u32 = 0;
18001727
18011728 const param_local: u32 = 0;
18021729
1803 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
1804 appendReservedUleb32(bytes, param_local);
1730 try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get));
1731 try bw.writeLeb128(param_local);
18051732
18061733 const tls_base_global_index: Wasm.GlobalIndex = @enumFromInt(wasm.globals.getIndex(.__tls_base).?);
1807 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.global_set));
1808 appendReservedUleb32(bytes, @intFromEnum(tls_base_global_index));
1734 try bw.writeByte(@intFromEnum(std.wasm.Opcode.global_set));
1735 try bw.writeLeb128(@intFromEnum(tls_base_global_index));
18091736
18101737 // load stack values for the bulk-memory operation
18111738 {
1812 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
1813 appendReservedUleb32(bytes, param_local);
1739 try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get));
1740 try bw.writeLeb128(param_local);
18141741
1815 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1816 appendReservedUleb32(bytes, 0); //segment offset
1742 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1743 try bw.writeSleb128(0); // segment offset
18171744
1818 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1819 appendReservedUleb32(bytes, group_size); //segment offset
1745 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1746 try bw.writeLeb128(@as(i32, @bitCast(group_size))); // segment offset
18201747 }
18211748
18221749 // perform the bulk-memory operation to initialize the data segment
1823 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.misc_prefix));
1824 appendReservedUleb32(bytes, @intFromEnum(std.wasm.MiscOpcode.memory_init));
1750 try bw.writeByte(@intFromEnum(std.wasm.Opcode.misc_prefix));
1751 try bw.writeLeb128(@intFromEnum(std.wasm.MiscOpcode.memory_init));
18251752 // segment immediate
1826 appendReservedUleb32(bytes, data_segment_index);
1827 // memory index immediate (always 0)
1828 appendReservedUleb32(bytes, 0);
1753 try bw.writeLeb128(data_segment_index);
1754 try bw.writeByte(0); // memory index immediate
18291755 }
18301756
18311757 // If we have to perform any TLS relocations, call the corresponding function
......@@ -1833,56 +1759,59 @@ fn emitInitTlsFunction(wasm: *const Wasm, bytes: *std.ArrayListUnmanaged(u8)) Al
18331759 // generated by the linker.
18341760 if (wasm.functions.getIndex(.__wasm_apply_global_tls_relocs)) |function_index| {
18351761 const output_function_index: Wasm.OutputFunctionIndex = .fromFunctionIndex(wasm, @enumFromInt(function_index));
1836 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call));
1837 appendReservedUleb32(bytes, @intFromEnum(output_function_index));
1762 try bw.writeByte(@intFromEnum(std.wasm.Opcode.call));
1763 try bw.writeLeb128(@intFromEnum(output_function_index));
18381764 }
18391765
1840 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1766 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
18411767}
18421768
1843fn emitStartSection(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8), i: Wasm.OutputFunctionIndex) !void {
1844 const header_offset = try reserveVecSectionHeader(gpa, bytes);
1845 replaceVecSectionHeader(bytes, header_offset, .start, @intFromEnum(i));
1769fn emitStartSection(aw: *std.io.AllocatingWriter, i: Wasm.OutputFunctionIndex) !void {
1770 const header_offset = try reserveVecSectionHeader(&aw.buffered_writer);
1771 defer replaceVecSectionHeader(aw, header_offset, .start, @intFromEnum(i));
18461772}
18471773
18481774fn emitTagNameFunction(
18491775 wasm: *Wasm,
1850 code: *std.ArrayListUnmanaged(u8),
1776 bw: *std.io.BufferedWriter,
18511777 table_base_addr: u32,
18521778 table_index: u32,
18531779 enum_type_ip: InternPool.Index,
18541780) !void {
18551781 const comp = wasm.base.comp;
1856 const gpa = comp.gpa;
18571782 const diags = &comp.link_diags;
18581783 const zcu = comp.zcu.?;
18591784 const ip = &zcu.intern_pool;
18601785 const enum_type = ip.loadEnumType(enum_type_ip);
18611786 const tag_values = enum_type.values.get(ip);
18621787
1863 try code.ensureUnusedCapacity(gpa, 7 * 5 + 6 + 1 * 6);
1864 appendReservedUleb32(code, 0); // no locals
1788 try bw.writeUleb128(0); // no locals
18651789
1866 const slice_abi_size = 8;
1867 const encoded_alignment = @ctz(@as(u32, 4));
1790 const slice_abi_size: u32 = 8;
18681791 if (tag_values.len == 0) {
18691792 // Then it's auto-numbered and therefore a direct table lookup.
1870 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
1871 appendReservedUleb32(code, 0);
1793 try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get));
1794 try bw.writeUleb128(0);
18721795
1873 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
1874 appendReservedUleb32(code, 1);
1796 try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get));
1797 try bw.writeUleb128(1);
18751798
1876 appendReservedI32Const(code, slice_abi_size);
1877 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_mul));
1799 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1800 if (std.math.isPowerOfTwo(slice_abi_size)) {
1801 try bw.writeLeb128(@as(i32, @bitCast(@as(u32, std.math.log2_int(u32, slice_abi_size)))));
1802 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_shl));
1803 } else {
1804 try bw.writeLeb128(@as(i32, @bitCast(slice_abi_size)));
1805 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_mul));
1806 }
18781807
1879 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_load));
1880 appendReservedUleb32(code, encoded_alignment);
1881 appendReservedUleb32(code, table_base_addr + table_index * 8);
1808 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_load));
1809 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1810 try bw.writeLeb128(table_base_addr + slice_abi_size * table_index);
18821811
1883 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_store));
1884 appendReservedUleb32(code, encoded_alignment);
1885 appendReservedUleb32(code, 0);
1812 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_store));
1813 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1814 try bw.writeUleb128(0);
18861815 } else {
18871816 const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu);
18881817 const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {
......@@ -1891,94 +1820,80 @@ fn emitTagNameFunction(
18911820 else => return diags.fail("wasm linker does not yet implement @tagName for sparse enums with more than 64 bit integer tag types", .{}),
18921821 };
18931822
1894 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
1895 appendReservedUleb32(code, 0);
1823 try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get));
1824 try bw.writeUleb128(0);
18961825
18971826 // Outer block that computes table offset.
1898 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block));
1899 code.appendAssumeCapacity(@intFromEnum(outer_block_type));
1827 try bw.writeByte(@intFromEnum(std.wasm.Opcode.block));
1828 try bw.writeByte(@intFromEnum(outer_block_type));
19001829
19011830 for (tag_values, 0..) |tag_value, tag_index| {
19021831 // block for this if case
1903 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.block));
1904 code.appendAssumeCapacity(@intFromEnum(std.wasm.BlockType.empty));
1832 try bw.writeByte(@intFromEnum(std.wasm.Opcode.block));
1833 try bw.writeByte(@intFromEnum(std.wasm.BlockType.empty));
19051834
19061835 // Tag value whose name should be returned.
1907 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.local_get));
1908 appendReservedUleb32(code, 1);
1836 try bw.writeByte(@intFromEnum(std.wasm.Opcode.local_get));
1837 try bw.writeUleb128(1);
19091838
19101839 const val: Zcu.Value = .fromInterned(tag_value);
19111840 switch (outer_block_type) {
19121841 .i32 => {
1913 const x: u32 = switch (int_info.signedness) {
1914 .signed => @bitCast(@as(i32, @intCast(val.toSignedInt(zcu)))),
1915 .unsigned => @intCast(val.toUnsignedInt(zcu)),
1916 };
1917 appendReservedI32Const(code, x);
1918 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_ne));
1842 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1843 try bw.writeLeb128(@as(i32, switch (int_info.signedness) {
1844 .signed => @intCast(val.toSignedInt(zcu)),
1845 .unsigned => @bitCast(@as(u32, @intCast(val.toUnsignedInt(zcu)))),
1846 }));
1847 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_ne));
19191848 },
19201849 .i64 => {
1921 const x: u64 = switch (int_info.signedness) {
1922 .signed => @bitCast(val.toSignedInt(zcu)),
1923 .unsigned => val.toUnsignedInt(zcu),
1924 };
1925 appendReservedI64Const(code, x);
1926 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_ne));
1850 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_const));
1851 try bw.writeLeb128(@as(i64, switch (int_info.signedness) {
1852 .signed => val.toSignedInt(zcu),
1853 .unsigned => @bitCast(val.toUnsignedInt(zcu)),
1854 }));
1855 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_ne));
19271856 },
19281857 else => unreachable,
19291858 }
19301859
19311860 // if they're not equal, break out of current branch
1932 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br_if));
1933 appendReservedUleb32(code, 0);
1861 try bw.writeByte(@intFromEnum(std.wasm.Opcode.br_if));
1862 try bw.writeUleb128(0);
19341863
19351864 // Put the table offset of the result on the stack.
1936 appendReservedI32Const(code, @intCast(tag_index * slice_abi_size));
1865 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const));
1866 try bw.writeLeb128(@as(i32, @bitCast(@as(u32, @intCast(slice_abi_size * tag_index)))));
19371867
19381868 // break outside blocks
1939 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.br));
1940 appendReservedUleb32(code, 1);
1869 try bw.writeByte(@intFromEnum(std.wasm.Opcode.br));
1870 try bw.writeUleb128(1);
19411871
19421872 // end the block for this case
1943 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1873 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
19441874 }
1945 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.@"unreachable"));
1946 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1875 try bw.writeByte(@intFromEnum(std.wasm.Opcode.@"unreachable"));
1876 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
19471877
1948 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_load));
1949 appendReservedUleb32(code, encoded_alignment);
1950 appendReservedUleb32(code, table_base_addr + table_index * 8);
1878 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_load));
1879 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1880 try bw.writeLeb128(table_base_addr + slice_abi_size * table_index);
19511881
1952 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_store));
1953 appendReservedUleb32(code, encoded_alignment);
1954 appendReservedUleb32(code, 0);
1882 try bw.writeByte(@intFromEnum(std.wasm.Opcode.i64_store));
1883 try bw.writeLeb128(comptime Alignment.@"4".toLog2Units());
1884 try bw.writeUleb128(0);
19551885 }
19561886
19571887 // End of the function body
1958 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1959}
1960
1961/// Writes an unsigned 32-bit integer as a LEB128-encoded 'i32.const' value.
1962fn appendReservedI32Const(bytes: *std.ArrayListUnmanaged(u8), val: u32) void {
1963 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1964 leb.writeIleb128(bytes.fixedWriter(), @as(i32, @bitCast(val))) catch unreachable;
1965}
1966
1967/// Writes an unsigned 64-bit integer as a LEB128-encoded 'i64.const' value.
1968fn appendReservedI64Const(bytes: *std.ArrayListUnmanaged(u8), val: u64) void {
1969 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
1970 leb.writeIleb128(bytes.fixedWriter(), @as(i64, @bitCast(val))) catch unreachable;
1971}
1972
1973fn appendReservedUleb32(bytes: *std.ArrayListUnmanaged(u8), val: u32) void {
1974 leb.writeUleb128(bytes.fixedWriter(), val) catch unreachable;
1888 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
19751889}
19761890
1977fn appendGlobal(gpa: Allocator, bytes: *std.ArrayListUnmanaged(u8), mutable: u8, val: u32) Allocator.Error!void {
1978 try bytes.ensureUnusedCapacity(gpa, 9);
1979 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Valtype.i32));
1980 bytes.appendAssumeCapacity(mutable);
1981 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const));
1982 appendReservedUleb32(bytes, val);
1983 bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end));
1891fn appendGlobal(bw: *std.io.BufferedWriter, mutable: bool, val: u32) anyerror!void {
1892 try bw.writeAll(&.{
1893 @intFromEnum(std.wasm.Valtype.i32),
1894 @intFromBool(mutable),
1895 @intFromEnum(std.wasm.Opcode.i32_const),
1896 });
1897 try bw.writeLeb128(val);
1898 try bw.writeByte(@intFromEnum(std.wasm.Opcode.end));
19841899}
src/link/Wasm/Object.zig+263-323
......@@ -252,7 +252,7 @@ pub const ScratchSpace = struct {
252252
253253pub fn parse(
254254 wasm: *Wasm,
255 bytes: []const u8,
255 br: *std.io.BufferedReader,
256256 path: Path,
257257 archive_member_name: ?[]const u8,
258258 host_name: Wasm.OptionalString,
......@@ -264,13 +264,9 @@ pub fn parse(
264264 const gpa = comp.gpa;
265265 const diags = &comp.link_diags;
266266
267 var pos: usize = 0;
267 if (!std.mem.eql(u8, try br.takeArray(std.wasm.magic.len), &std.wasm.magic)) return error.BadObjectMagic;
268268
269 if (!std.mem.eql(u8, bytes[0..std.wasm.magic.len], &std.wasm.magic)) return error.BadObjectMagic;
270 pos += std.wasm.magic.len;
271
272 const version = std.mem.readInt(u32, bytes[pos..][0..4], .little);
273 pos += 4;
269 const version = try br.takeInt(u32, .little);
274270
275271 const data_segment_start: u32 = @intCast(wasm.object_data_segments.items.len);
276272 const custom_segment_start: u32 = @intCast(wasm.object_custom_segments.entries.len);
......@@ -298,200 +294,187 @@ pub fn parse(
298294 var code_section_index: ?Wasm.ObjectSectionIndex = null;
299295 var global_section_index: ?Wasm.ObjectSectionIndex = null;
300296 var data_section_index: ?Wasm.ObjectSectionIndex = null;
301 while (pos < bytes.len) : (wasm.object_total_sections += 1) {
297 while (br.takeEnum(std.wasm.Section, .little)) |section_tag| : (wasm.object_total_sections += 1) {
302298 const section_index: Wasm.ObjectSectionIndex = @enumFromInt(wasm.object_total_sections);
303299
304 const section_tag: std.wasm.Section = @enumFromInt(bytes[pos]);
305 pos += 1;
306
307 const len, pos = readLeb(u32, bytes, pos);
308 const section_end = pos + len;
300 const len = try br.takeLeb128(u32);
301 const section_end = br.seek + len;
309302 switch (section_tag) {
310303 .custom => {
311 const section_name, pos = readBytes(bytes, pos);
304 const section_name = try br.take(try br.takeLeb128(u32));
312305 if (std.mem.eql(u8, section_name, "linking")) {
313306 saw_linking_section = true;
314 const section_version, pos = readLeb(u32, bytes, pos);
307 const section_version = try br.takeLeb128(u32);
315308 log.debug("link meta data version: {d}", .{section_version});
316309 if (section_version != 2) return error.UnsupportedVersion;
317 while (pos < section_end) {
318 const sub_type, pos = readLeb(u8, bytes, pos);
319 log.debug("found subsection: {s}", .{@tagName(@as(SubsectionType, @enumFromInt(sub_type)))});
320 const payload_len, pos = readLeb(u32, bytes, pos);
310 while (br.seek < section_end) {
311 const sub_type = try br.takeEnum(SubsectionType, .little);
312 log.debug("found subsection: {s}", .{@tagName(sub_type)});
313 const payload_len = try br.takeLeb128(u32);
321314 if (payload_len == 0) break;
322315
323 const count, pos = readLeb(u32, bytes, pos);
324
325 switch (@as(SubsectionType, @enumFromInt(sub_type))) {
326 .segment_info => {
327 for (try ss.segment_info.addManyAsSlice(gpa, count)) |*segment| {
328 const name, pos = readBytes(bytes, pos);
329 const alignment, pos = readLeb(u32, bytes, pos);
330 const flags_u32, pos = readLeb(u32, bytes, pos);
331 const flags: SegmentInfo.Flags = @bitCast(flags_u32);
332 const tls = flags.tls or
333 // Supports legacy object files that specified
334 // being TLS by the name instead of the TLS flag.
335 std.mem.startsWith(u8, name, ".tdata") or
336 std.mem.startsWith(u8, name, ".tbss");
337 has_tls = has_tls or tls;
338 segment.* = .{
339 .name = try wasm.internString(name),
340 .flags = .{
341 .strings = flags.strings,
342 .tls = tls,
343 .alignment = @enumFromInt(alignment),
344 .retain = flags.retain,
345 },
346 };
347 }
316 const count = try br.takeLeb128(u32);
317 switch (sub_type) {
318 .segment_info => for (try ss.segment_info.addManyAsSlice(gpa, count)) |*segment| {
319 const name = try br.take(try br.takeLeb128(u32));
320 const alignment: Alignment = .fromLog2Units(try br.takeLeb128(u32));
321 const flags: SegmentInfo.Flags = @bitCast(try br.takeLeb128(u32));
322 const tls = flags.tls or
323 // Supports legacy object files that specified
324 // being TLS by the name instead of the TLS flag.
325 std.mem.startsWith(u8, name, ".tdata") or
326 std.mem.startsWith(u8, name, ".tbss");
327 has_tls = has_tls or tls;
328 segment.* = .{
329 .name = try wasm.internString(name),
330 .flags = .{
331 .strings = flags.strings,
332 .tls = tls,
333 .alignment = alignment,
334 .retain = flags.retain,
335 },
336 };
348337 },
349 .init_funcs => {
350 for (try wasm.object_init_funcs.addManyAsSlice(gpa, count)) |*func| {
351 const priority, pos = readLeb(u32, bytes, pos);
352 const symbol_index, pos = readLeb(u32, bytes, pos);
353 if (symbol_index > ss.symbol_table.items.len)
354 return diags.failParse(path, "init_funcs before symbol table", .{});
355 const sym = &ss.symbol_table.items[symbol_index];
356 if (sym.pointee != .function) {
357 return diags.failParse(path, "init_func symbol '{s}' not a function", .{
358 sym.name.slice(wasm).?,
359 });
360 } else if (sym.flags.undefined) {
361 return diags.failParse(path, "init_func symbol '{s}' is an import", .{
362 sym.name.slice(wasm).?,
363 });
364 }
365 func.* = .{
366 .priority = priority,
367 .function_index = sym.pointee.function,
368 };
338 .init_funcs => for (try wasm.object_init_funcs.addManyAsSlice(gpa, count)) |*func| {
339 const priority = try br.takeLeb128(u32);
340 const symbol_index = try br.takeLeb128(u32);
341 if (symbol_index > ss.symbol_table.items.len)
342 return diags.failParse(path, "init_funcs before symbol table", .{});
343 const sym = &ss.symbol_table.items[symbol_index];
344 if (sym.pointee != .function) {
345 return diags.failParse(path, "init_func symbol '{s}' not a function", .{
346 sym.name.slice(wasm).?,
347 });
348 } else if (sym.flags.undefined) {
349 return diags.failParse(path, "init_func symbol '{s}' is an import", .{
350 sym.name.slice(wasm).?,
351 });
369352 }
353 func.* = .{
354 .priority = priority,
355 .function_index = sym.pointee.function,
356 };
370357 },
371 .comdat_info => {
372 for (try wasm.object_comdats.addManyAsSlice(gpa, count)) |*comdat| {
373 const name, pos = readBytes(bytes, pos);
374 const flags, pos = readLeb(u32, bytes, pos);
375 if (flags != 0) return error.UnexpectedComdatFlags;
376 const symbol_count, pos = readLeb(u32, bytes, pos);
377 const start_off: u32 = @intCast(wasm.object_comdat_symbols.len);
378 try wasm.object_comdat_symbols.ensureUnusedCapacity(gpa, symbol_count);
379 for (0..symbol_count) |_| {
380 const kind, pos = readEnum(Wasm.Comdat.Symbol.Type, bytes, pos);
381 const index, pos = readLeb(u32, bytes, pos);
382 if (true) @panic("TODO rebase index depending on kind");
383 wasm.object_comdat_symbols.appendAssumeCapacity(.{
384 .kind = kind,
385 .index = index,
386 });
387 }
388 comdat.* = .{
389 .name = try wasm.internString(name),
390 .flags = flags,
391 .symbols = .{
392 .off = start_off,
393 .len = @intCast(wasm.object_comdat_symbols.len - start_off),
394 },
395 };
358 .comdat_info => for (try wasm.object_comdats.addManyAsSlice(gpa, count)) |*comdat| {
359 const name = try br.take(try br.takeLeb128(u32));
360 const flags = try br.takeLeb128(u32);
361 if (flags != 0) return error.UnexpectedComdatFlags;
362 const symbol_count = try br.takeLeb128(u32);
363 const start_off: u32 = @intCast(wasm.object_comdat_symbols.len);
364 try wasm.object_comdat_symbols.ensureUnusedCapacity(gpa, symbol_count);
365 for (0..symbol_count) |_| {
366 const kind = try br.takeEnum(Wasm.Comdat.Symbol.Type, .little);
367 const index = try br.takeLeb128(u32);
368 if (true) @panic("TODO rebase index depending on kind");
369 wasm.object_comdat_symbols.appendAssumeCapacity(.{
370 .kind = kind,
371 .index = index,
372 });
396373 }
374 comdat.* = .{
375 .name = try wasm.internString(name),
376 .flags = flags,
377 .symbols = .{
378 .off = start_off,
379 .len = @intCast(wasm.object_comdat_symbols.len - start_off),
380 },
381 };
397382 },
398 .symbol_table => {
399 for (try ss.symbol_table.addManyAsSlice(gpa, count)) |*symbol| {
400 const tag, pos = readEnum(Symbol.Tag, bytes, pos);
401 const flags, pos = readLeb(u32, bytes, pos);
402 symbol.* = .{
403 .flags = @bitCast(flags),
404 .name = .none,
405 .pointee = undefined,
406 };
407 symbol.flags.initZigSpecific(must_link, gc_sections);
408
409 switch (tag) {
410 .data => {
411 const name, pos = readBytes(bytes, pos);
412 const interned_name = try wasm.internString(name);
413 symbol.name = interned_name.toOptional();
414 if (symbol.flags.undefined) {
415 symbol.pointee = .data_import;
383 .symbol_table => for (try ss.symbol_table.addManyAsSlice(gpa, count)) |*symbol| {
384 const tag = try br.takeEnum(Symbol.Tag, .little);
385 const flags: Wasm.SymbolFlags = @bitCast(try br.takeLeb128(u32));
386 symbol.* = .{
387 .flags = flags,
388 .name = .none,
389 .pointee = undefined,
390 };
391 symbol.flags.initZigSpecific(must_link, gc_sections);
392
393 switch (tag) {
394 .data => {
395 const name = try br.take(try br.takeLeb128(u32));
396 const interned_name = try wasm.internString(name);
397 symbol.name = interned_name.toOptional();
398 if (symbol.flags.undefined) {
399 symbol.pointee = .data_import;
400 } else {
401 const segment_index = try br.takeLeb128(u32);
402 const segment_offset = try br.takeLeb128(u32);
403 const size = try br.takeLeb128(u32);
404 try wasm.object_datas.append(gpa, .{
405 .segment = @enumFromInt(data_segment_start + segment_index),
406 .offset = segment_offset,
407 .size = size,
408 .name = interned_name,
409 .flags = symbol.flags,
410 });
411 symbol.pointee = .{
412 .data = @enumFromInt(wasm.object_datas.items.len - 1),
413 };
414 }
415 },
416 .section => {
417 const local_section = try br.takeLeb128(u32);
418 const section: Wasm.ObjectSectionIndex = @enumFromInt(local_section_index_base + local_section);
419 symbol.pointee = .{ .section = section };
420 },
421
422 .function => {
423 const local_index = try br.takeLeb128(u32);
424 if (symbol.flags.undefined) {
425 const function_import: ScratchSpace.FuncImportIndex = @enumFromInt(local_index);
426 symbol.pointee = .{ .function_import = function_import };
427 if (symbol.flags.explicit_name) {
428 const name = try br.take(try br.takeLeb128(u32));
429 symbol.name = (try wasm.internString(name)).toOptional();
416430 } else {
417 const segment_index, pos = readLeb(u32, bytes, pos);
418 const segment_offset, pos = readLeb(u32, bytes, pos);
419 const size, pos = readLeb(u32, bytes, pos);
420 try wasm.object_datas.append(gpa, .{
421 .segment = @enumFromInt(data_segment_start + segment_index),
422 .offset = segment_offset,
423 .size = size,
424 .name = interned_name,
425 .flags = symbol.flags,
426 });
427 symbol.pointee = .{
428 .data = @enumFromInt(wasm.object_datas.items.len - 1),
429 };
431 symbol.name = function_import.ptr(ss).name.toOptional();
430432 }
431 },
432 .section => {
433 const local_section, pos = readLeb(u32, bytes, pos);
434 const section: Wasm.ObjectSectionIndex = @enumFromInt(local_section_index_base + local_section);
435 symbol.pointee = .{ .section = section };
436 },
437
438 .function => {
439 const local_index, pos = readLeb(u32, bytes, pos);
440 if (symbol.flags.undefined) {
441 const function_import: ScratchSpace.FuncImportIndex = @enumFromInt(local_index);
442 symbol.pointee = .{ .function_import = function_import };
443 if (symbol.flags.explicit_name) {
444 const name, pos = readBytes(bytes, pos);
445 symbol.name = (try wasm.internString(name)).toOptional();
446 } else {
447 symbol.name = function_import.ptr(ss).name.toOptional();
448 }
449 } else {
450 symbol.pointee = .{ .function = @enumFromInt(functions_start + (local_index - ss.func_imports.items.len)) };
451 const name, pos = readBytes(bytes, pos);
433 } else {
434 symbol.pointee = .{ .function = @enumFromInt(functions_start + (local_index - ss.func_imports.items.len)) };
435 const name = try br.take(try br.takeLeb128(u32));
436 symbol.name = (try wasm.internString(name)).toOptional();
437 }
438 },
439 .global => {
440 const local_index = try br.takeLeb128(u32);
441 if (symbol.flags.undefined) {
442 const global_import: ScratchSpace.GlobalImportIndex = @enumFromInt(local_index);
443 symbol.pointee = .{ .global_import = global_import };
444 if (symbol.flags.explicit_name) {
445 const name = try br.take(try br.takeLeb128(u32));
452446 symbol.name = (try wasm.internString(name)).toOptional();
453 }
454 },
455 .global => {
456 const local_index, pos = readLeb(u32, bytes, pos);
457 if (symbol.flags.undefined) {
458 const global_import: ScratchSpace.GlobalImportIndex = @enumFromInt(local_index);
459 symbol.pointee = .{ .global_import = global_import };
460 if (symbol.flags.explicit_name) {
461 const name, pos = readBytes(bytes, pos);
462 symbol.name = (try wasm.internString(name)).toOptional();
463 } else {
464 symbol.name = global_import.ptr(ss).name.toOptional();
465 }
466447 } else {
467 symbol.pointee = .{ .global = @enumFromInt(globals_start + (local_index - ss.global_imports.items.len)) };
468 const name, pos = readBytes(bytes, pos);
469 symbol.name = (try wasm.internString(name)).toOptional();
448 symbol.name = global_import.ptr(ss).name.toOptional();
470449 }
471 },
472 .table => {
473 const local_index, pos = readLeb(u32, bytes, pos);
474 if (symbol.flags.undefined) {
475 table_import_symbol_count += 1;
476 const table_import: ScratchSpace.TableImportIndex = @enumFromInt(local_index);
477 symbol.pointee = .{ .table_import = table_import };
478 if (symbol.flags.explicit_name) {
479 const name, pos = readBytes(bytes, pos);
480 symbol.name = (try wasm.internString(name)).toOptional();
481 } else {
482 symbol.name = table_import.ptr(ss).name.toOptional();
483 }
484 } else {
485 symbol.pointee = .{ .table = @enumFromInt(tables_start + (local_index - ss.table_imports.items.len)) };
486 const name, pos = readBytes(bytes, pos);
450 } else {
451 symbol.pointee = .{ .global = @enumFromInt(globals_start + (local_index - ss.global_imports.items.len)) };
452 const name = try br.take(try br.takeLeb128(u32));
453 symbol.name = (try wasm.internString(name)).toOptional();
454 }
455 },
456 .table => {
457 const local_index = try br.takeLeb128(u32);
458 if (symbol.flags.undefined) {
459 table_import_symbol_count += 1;
460 const table_import: ScratchSpace.TableImportIndex = @enumFromInt(local_index);
461 symbol.pointee = .{ .table_import = table_import };
462 if (symbol.flags.explicit_name) {
463 const name = try br.take(try br.takeLeb128(u32));
487464 symbol.name = (try wasm.internString(name)).toOptional();
465 } else {
466 symbol.name = table_import.ptr(ss).name.toOptional();
488467 }
489 },
490 else => {
491 log.debug("unrecognized symbol type tag: {x}", .{@intFromEnum(tag)});
492 return error.UnrecognizedSymbolType;
493 },
494 }
468 } else {
469 symbol.pointee = .{ .table = @enumFromInt(tables_start + (local_index - ss.table_imports.items.len)) };
470 const name = try br.take(try br.takeLeb128(u32));
471 symbol.name = (try wasm.internString(name)).toOptional();
472 }
473 },
474 else => {
475 log.debug("unrecognized symbol type tag: {x}", .{@intFromEnum(tag)});
476 return error.UnrecognizedSymbolType;
477 },
495478 }
496479 },
497480 }
......@@ -504,8 +487,8 @@ pub fn parse(
504487 // which section they apply to, and must be sequenced in
505488 // the module after that section."
506489 // "Relocation sections can only target code, data and custom sections."
507 const local_section, pos = readLeb(u32, bytes, pos);
508 const count, pos = readLeb(u32, bytes, pos);
490 const local_section = try br.takeLeb128(u32);
491 const count = try br.takeLeb128(u32);
509492 const section: Wasm.ObjectSectionIndex = @enumFromInt(local_section_index_base + local_section);
510493
511494 log.debug("found {d} relocations for section={d}", .{ count, section });
......@@ -513,10 +496,9 @@ pub fn parse(
513496 var prev_offset: u32 = 0;
514497 try wasm.object_relocations.ensureUnusedCapacity(gpa, count);
515498 for (0..count) |_| {
516 const tag: RelocationType = @enumFromInt(bytes[pos]);
517 pos += 1;
518 const offset, pos = readLeb(u32, bytes, pos);
519 const index, pos = readLeb(u32, bytes, pos);
499 const tag = try br.takeEnum(RelocationType, .little);
500 const offset = try br.takeLeb128(u32);
501 const index = try br.takeLeb128(u32);
520502
521503 if (offset < prev_offset)
522504 return diags.failParse(path, "relocation entries not sorted by offset", .{});
......@@ -537,7 +519,7 @@ pub fn parse(
537519 .memory_addr_locrel_i32,
538520 .memory_addr_tls_sleb64,
539521 => {
540 const addend: i32, pos = readLeb(i32, bytes, pos);
522 const addend = try br.takeLeb128(i32);
541523 wasm.object_relocations.appendAssumeCapacity(switch (sym.pointee) {
542524 .data => |data| .{
543525 .tag = .fromType(tag),
......@@ -555,7 +537,7 @@ pub fn parse(
555537 });
556538 },
557539 .function_offset_i32, .function_offset_i64 => {
558 const addend: i32, pos = readLeb(i32, bytes, pos);
540 const addend = try br.takeLeb128(i32);
559541 wasm.object_relocations.appendAssumeCapacity(switch (sym.pointee) {
560542 .function => .{
561543 .tag = .fromType(tag),
......@@ -573,7 +555,7 @@ pub fn parse(
573555 });
574556 },
575557 .section_offset_i32 => {
576 const addend: i32, pos = readLeb(i32, bytes, pos);
558 const addend = try br.takeLeb128(i32);
577559 wasm.object_relocations.appendAssumeCapacity(.{
578560 .tag = .section_offset_i32,
579561 .offset = offset,
......@@ -658,10 +640,9 @@ pub fn parse(
658640 .len = count,
659641 });
660642 } else if (std.mem.eql(u8, section_name, "target_features")) {
661 opt_features, pos = try parseFeatures(wasm, bytes, pos, path);
643 opt_features = try parseFeatures(wasm, br, path);
662644 } else if (std.mem.startsWith(u8, section_name, ".debug")) {
663 const debug_content = bytes[pos..section_end];
664 pos = section_end;
645 const debug_content = try br.take(len);
665646
666647 const data_off: u32 = @intCast(wasm.string_bytes.items.len);
667648 try wasm.string_bytes.appendSlice(gpa, debug_content);
......@@ -669,23 +650,20 @@ pub fn parse(
669650 try wasm.object_custom_segments.put(gpa, section_index, .{
670651 .payload = .{
671652 .off = @enumFromInt(data_off),
672 .len = @intCast(debug_content.len),
653 .len = @intCast(len),
673654 },
674655 .flags = .{},
675656 .section_name = try wasm.internString(section_name),
676657 });
677 } else {
678 pos = section_end;
679 }
658 } else br.seek = section_end;
680659 },
681660 .type => {
682 const func_types_len, pos = readLeb(u32, bytes, pos);
661 const func_types_len = try br.takeLeb128(u32);
683662 for (try ss.func_types.addManyAsSlice(gpa, func_types_len)) |*func_type| {
684 if (bytes[pos] != std.wasm.function_type) return error.ExpectedFuncType;
685 pos += 1;
663 if (try br.takeByte() != std.wasm.function_type) return error.ExpectedFuncType;
686664
687 const params, pos = readBytes(bytes, pos);
688 const returns, pos = readBytes(bytes, pos);
665 const params = try br.take(try br.takeLeb128(u32));
666 const returns = try br.take(try br.takeLeb128(u32));
689667 func_type.* = try wasm.addFuncType(.{
690668 .params = .fromString(try wasm.internString(params)),
691669 .returns = .fromString(try wasm.internString(returns)),
......@@ -693,16 +671,16 @@ pub fn parse(
693671 }
694672 },
695673 .import => {
696 const imports_len, pos = readLeb(u32, bytes, pos);
674 const imports_len = try br.takeLeb128(u32);
697675 for (0..imports_len) |_| {
698 const module_name, pos = readBytes(bytes, pos);
699 const name, pos = readBytes(bytes, pos);
700 const kind, pos = readEnum(std.wasm.ExternalKind, bytes, pos);
676 const module_name = try br.take(try br.takeLeb128(u32));
677 const name = try br.take(try br.takeLeb128(u32));
678 const kind = try br.takeEnum(std.wasm.ExternalKind, .little);
701679 const interned_module_name = try wasm.internString(module_name);
702680 const interned_name = try wasm.internString(name);
703681 switch (kind) {
704682 .function => {
705 const function, pos = readLeb(u32, bytes, pos);
683 const function = try br.takeLeb128(u32);
706684 try ss.func_imports.append(gpa, .{
707685 .module_name = interned_module_name,
708686 .name = interned_name,
......@@ -710,7 +688,7 @@ pub fn parse(
710688 });
711689 },
712690 .memory => {
713 const limits, pos = readLimits(bytes, pos);
691 const limits = try readLimits(br);
714692 const gop = try wasm.object_memory_imports.getOrPut(gpa, interned_name);
715693 if (gop.found_existing) {
716694 if (gop.value_ptr.module_name != interned_module_name) {
......@@ -736,9 +714,12 @@ pub fn parse(
736714 }
737715 },
738716 .global => {
739 const valtype, pos = readEnum(std.wasm.Valtype, bytes, pos);
740 const mutable = bytes[pos] == 0x01;
741 pos += 1;
717 const valtype = try br.takeEnum(std.wasm.Valtype, .little);
718 const mutable = switch (try br.takeByte()) {
719 0 => false,
720 1 => true,
721 else => return error.InvalidMutability,
722 };
742723 try ss.global_imports.append(gpa, .{
743724 .name = interned_name,
744725 .valtype = valtype,
......@@ -747,8 +728,8 @@ pub fn parse(
747728 });
748729 },
749730 .table => {
750 const ref_type, pos = readEnum(std.wasm.RefType, bytes, pos);
751 const limits, pos = readLimits(bytes, pos);
731 const ref_type = try br.takeEnum(std.wasm.RefType, .little);
732 const limits = try readLimits(br);
752733 try ss.table_imports.append(gpa, .{
753734 .name = interned_name,
754735 .module_name = interned_module_name,
......@@ -763,17 +744,16 @@ pub fn parse(
763744 }
764745 },
765746 .function => {
766 const functions_len, pos = readLeb(u32, bytes, pos);
747 const functions_len = try br.takeLeb128(u32);
767748 for (try ss.func_type_indexes.addManyAsSlice(gpa, functions_len)) |*func_type_index| {
768 const i, pos = readLeb(u32, bytes, pos);
769 func_type_index.* = @enumFromInt(i);
749 func_type_index.* = @enumFromInt(try br.takeLeb128(u32));
770750 }
771751 },
772752 .table => {
773 const tables_len, pos = readLeb(u32, bytes, pos);
753 const tables_len = try br.takeLeb128(u32);
774754 for (try wasm.object_tables.addManyAsSlice(gpa, tables_len)) |*table| {
775 const ref_type, pos = readEnum(std.wasm.RefType, bytes, pos);
776 const limits, pos = readLimits(bytes, pos);
755 const ref_type = try br.takeEnum(std.wasm.RefType, .little);
756 const limits = try readLimits(br);
777757 table.* = .{
778758 .name = .none,
779759 .module_name = .none,
......@@ -788,9 +768,9 @@ pub fn parse(
788768 }
789769 },
790770 .memory => {
791 const memories_len, pos = readLeb(u32, bytes, pos);
771 const memories_len = try br.takeLeb128(u32);
792772 for (try wasm.object_memories.addManyAsSlice(gpa, memories_len)) |*memory| {
793 const limits, pos = readLimits(bytes, pos);
773 const limits = try readLimits(br);
794774 memory.* = .{
795775 .name = .none,
796776 .flags = .{
......@@ -807,14 +787,17 @@ pub fn parse(
807787 return diags.failParse(path, "object has more than one global section", .{});
808788 global_section_index = section_index;
809789
810 const section_start = pos;
811 const globals_len, pos = readLeb(u32, bytes, pos);
790 const section_start = br.seek;
791 const globals_len = try br.takeLeb128(u32);
812792 for (try wasm.object_globals.addManyAsSlice(gpa, globals_len)) |*global| {
813 const valtype, pos = readEnum(std.wasm.Valtype, bytes, pos);
814 const mutable = bytes[pos] == 0x01;
815 pos += 1;
816 const init_start = pos;
817 const expr, pos = try readInit(wasm, bytes, pos);
793 const valtype = try br.takeEnum(std.wasm.Valtype, .little);
794 const mutable = switch (try br.takeByte()) {
795 0 => false,
796 1 => true,
797 else => return error.InvalidMutability,
798 };
799 const init_start = br.seek;
800 const expr = try readInit(wasm, br);
818801 global.* = .{
819802 .name = .none,
820803 .flags = .{
......@@ -826,20 +809,19 @@ pub fn parse(
826809 .expr = expr,
827810 .object_index = object_index,
828811 .offset = @intCast(init_start - section_start),
829 .size = @intCast(pos - init_start),
812 .size = @intCast(br.seek - init_start),
830813 };
831814 }
832815 },
833816 .@"export" => {
834 const exports_len, pos = readLeb(u32, bytes, pos);
817 const exports_len = try br.takeLeb128(u32);
835818 // Read into scratch space, and then later add this data as if
836819 // it were extra symbol table entries, but allow merging with
837820 // existing symbol table data if the name matches.
838821 for (try ss.exports.addManyAsSlice(gpa, exports_len)) |*exp| {
839 const name, pos = readBytes(bytes, pos);
840 const kind: std.wasm.ExternalKind = @enumFromInt(bytes[pos]);
841 pos += 1;
842 const index, pos = readLeb(u32, bytes, pos);
822 const name = try br.take(try br.takeLeb128(u32));
823 const kind = try br.takeEnum(std.wasm.ExternalKind, .little);
824 const index = try br.takeLeb128(u32);
843825 exp.* = .{
844826 .name = try wasm.internString(name),
845827 .pointee = switch (kind) {
......@@ -852,25 +834,24 @@ pub fn parse(
852834 }
853835 },
854836 .start => {
855 const index, pos = readLeb(u32, bytes, pos);
837 const index = try br.takeLeb128(u32);
856838 start_function = @enumFromInt(functions_start + index);
857839 },
858840 .element => {
859 log.warn("unimplemented: element section in {} {?s}", .{ path, archive_member_name });
860 pos = section_end;
841 log.warn("unimplemented: element section in {f} {?s}", .{ path, archive_member_name });
842 br.seek = section_end;
861843 },
862844 .code => {
863845 if (code_section_index != null)
864846 return diags.failParse(path, "object has more than one code section", .{});
865847 code_section_index = section_index;
866848
867 const start = pos;
868 const count, pos = readLeb(u32, bytes, pos);
849 const start = br.seek;
850 const count = try br.takeLeb128(u32);
869851 for (try wasm.object_functions.addManyAsSlice(gpa, count)) |*elem| {
870 const code_len, pos = readLeb(u32, bytes, pos);
871 const offset: u32 = @intCast(pos - start);
872 const payload = try wasm.addRelocatableDataPayload(bytes[pos..][0..code_len]);
873 pos += code_len;
852 const code_len = try br.takeLeb128(u32);
853 const offset: u32 = @intCast(br.seek - start);
854 const payload = try wasm.addRelocatableDataPayload(try br.take(code_len));
874855 elem.* = .{
875856 .flags = .{}, // populated from symbol table
876857 .name = .none, // populated from symbol table
......@@ -886,20 +867,19 @@ pub fn parse(
886867 return diags.failParse(path, "object has more than one data section", .{});
887868 data_section_index = section_index;
888869
889 const section_start = pos;
890 const count, pos = readLeb(u32, bytes, pos);
870 const section_start = br.seek;
871 const count = try br.takeLeb128(u32);
891872 for (try wasm.object_data_segments.addManyAsSlice(gpa, count)) |*elem| {
892 const flags, pos = readEnum(DataSegmentFlags, bytes, pos);
873 const flags: DataSegmentFlags = @enumFromInt(try br.takeLeb128(u32));
893874 if (flags == .active_memidx) {
894 const memidx, pos = readLeb(u32, bytes, pos);
875 const memidx = try br.takeLeb128(u32);
895876 if (memidx != 0) return diags.failParse(path, "data section uses mem index {d}", .{memidx});
896877 }
897 //const expr, pos = if (flags != .passive) try readInit(wasm, bytes, pos) else .{ .none, pos };
898 if (flags != .passive) pos = try skipInit(bytes, pos);
899 const data_len, pos = readLeb(u32, bytes, pos);
900 const segment_start = pos;
901 const payload = try wasm.addRelocatableDataPayload(bytes[pos..][0..data_len]);
902 pos += data_len;
878 //const expr = if (flags != .passive) try readInit(wasm, br) else .none;
879 if (flags != .passive) try skipInit(br);
880 const data_len = try br.takeLeb128(u32);
881 const segment_start = br.seek;
882 const payload = try wasm.addRelocatableDataPayload(try br.take(data_len));
903883 elem.* = .{
904884 .payload = payload,
905885 .name = .none, // Populated from segment_info
......@@ -911,10 +891,10 @@ pub fn parse(
911891 };
912892 }
913893 },
914 else => pos = section_end,
894 else => br.seek = section_end,
915895 }
916 if (pos != section_end) return error.MalformedSection;
917 }
896 if (br.seek != section_end) return error.MalformedSection;
897 } else |_| {}
918898 if (!saw_linking_section) return error.MissingLinkingSection;
919899
920900 const cpu = comp.root_mod.resolved_target.result.cpu;
......@@ -984,10 +964,10 @@ pub fn parse(
984964 if (gop.value_ptr.type != fn_ty_index) {
985965 var err = try diags.addErrorWithNotes(2);
986966 try err.addMsg("symbol '{s}' mismatching function signatures", .{name.slice(wasm)});
987 gop.value_ptr.source_location.addNote(&err, "imported as {} here", .{
967 gop.value_ptr.source_location.addNote(&err, "imported as {f} here", .{
988968 gop.value_ptr.type.fmt(wasm),
989969 });
990 source_location.addNote(&err, "imported as {} here", .{fn_ty_index.fmt(wasm)});
970 source_location.addNote(&err, "imported as {f} here", .{fn_ty_index.fmt(wasm)});
991971 continue;
992972 }
993973 if (gop.value_ptr.module_name != ptr.module_name.toOptional()) {
......@@ -1155,11 +1135,11 @@ pub fn parse(
11551135 if (gop.value_ptr.type != ptr.type_index) {
11561136 var err = try diags.addErrorWithNotes(2);
11571137 try err.addMsg("function signature mismatch: {s}", .{name.slice(wasm)});
1158 gop.value_ptr.source_location.addNote(&err, "exported as {} here", .{
1138 gop.value_ptr.source_location.addNote(&err, "exported as {f} here", .{
11591139 ptr.type_index.fmt(wasm),
11601140 });
11611141 const word = if (gop.value_ptr.resolution == .unresolved) "imported" else "exported";
1162 source_location.addNote(&err, "{s} as {} here", .{ word, gop.value_ptr.type.fmt(wasm) });
1142 source_location.addNote(&err, "{s} as {f} here", .{ word, gop.value_ptr.type.fmt(wasm) });
11631143 continue;
11641144 }
11651145 if (gop.value_ptr.resolution == .unresolved or gop.value_ptr.flags.binding == .weak) {
......@@ -1176,8 +1156,8 @@ pub fn parse(
11761156 }
11771157 var err = try diags.addErrorWithNotes(2);
11781158 try err.addMsg("symbol collision: {s}", .{name.slice(wasm)});
1179 gop.value_ptr.source_location.addNote(&err, "exported as {} here", .{ptr.type_index.fmt(wasm)});
1180 source_location.addNote(&err, "exported as {} here", .{gop.value_ptr.type.fmt(wasm)});
1159 gop.value_ptr.source_location.addNote(&err, "exported as {f} here", .{ptr.type_index.fmt(wasm)});
1160 source_location.addNote(&err, "exported as {f} here", .{gop.value_ptr.type.fmt(wasm)});
11811161 continue;
11821162 } else {
11831163 gop.value_ptr.* = .{
......@@ -1422,27 +1402,21 @@ pub fn parse(
14221402/// Based on the "features" custom section, parses it into a list of
14231403/// features that tell the linker what features were enabled and may be mandatory
14241404/// to be able to link.
1425fn parseFeatures(
1426 wasm: *Wasm,
1427 bytes: []const u8,
1428 start_pos: usize,
1429 path: Path,
1430) error{ OutOfMemory, LinkFailure }!struct { Wasm.Feature.Set, usize } {
1405fn parseFeatures(wasm: *Wasm, br: *std.io.BufferedReader, path: Path) anyerror!Wasm.Feature.Set {
14311406 const gpa = wasm.base.comp.gpa;
14321407 const diags = &wasm.base.comp.link_diags;
1433 const features_len, var pos = readLeb(u32, bytes, start_pos);
1408 const features_len = try br.takeLeb128(u32);
14341409 // This temporary allocation could be avoided by using the string_bytes buffer as a scratch space.
14351410 const feature_buffer = try gpa.alloc(Wasm.Feature, features_len);
14361411 defer gpa.free(feature_buffer);
14371412 for (feature_buffer) |*feature| {
1438 const prefix: Wasm.Feature.Prefix = switch (bytes[pos]) {
1413 const prefix: Wasm.Feature.Prefix = switch (try br.takeByte()) {
14391414 '-' => .@"-",
14401415 '+' => .@"+",
14411416 '=' => .@"=",
14421417 else => |b| return diags.failParse(path, "invalid feature prefix: 0x{x}", .{b}),
14431418 };
1444 pos += 1;
1445 const name, pos = readBytes(bytes, pos);
1419 const name = try br.take(try br.takeLeb128(u32));
14461420 const tag = std.meta.stringToEnum(Wasm.Feature.Tag, name) orelse {
14471421 return diags.failParse(path, "unrecognized wasm feature in object: {s}", .{name});
14481422 };
......@@ -1453,68 +1427,34 @@ fn parseFeatures(
14531427 }
14541428 std.mem.sortUnstable(Wasm.Feature, feature_buffer, {}, Wasm.Feature.lessThan);
14551429
1456 return .{
1457 .fromString(try wasm.internString(@ptrCast(feature_buffer))),
1458 pos,
1459 };
1430 return .fromString(try wasm.internString(@ptrCast(feature_buffer)));
14601431}
14611432
1462fn readLeb(comptime T: type, bytes: []const u8, pos: usize) struct { T, usize } {
1463 var fbr: std.io.FixedBufferStream = .{ .buffer = bytes[pos..] };
1433fn readLimits(br: *std.io.BufferedReader) anyerror!std.wasm.Limits {
1434 const flags: std.wasm.Limits.Flags = @bitCast(try br.takeByte());
1435 const min = try br.takeLeb128(u32);
1436 const max = if (flags.has_max) try br.takeLeb128(u32) else 0;
14641437 return .{
1465 switch (@typeInfo(T).int.signedness) {
1466 .signed => std.leb.readIleb128(T, fbr.reader()) catch unreachable,
1467 .unsigned => std.leb.readUleb128(T, fbr.reader()) catch unreachable,
1468 },
1469 pos + fbr.pos,
1470 };
1471}
1472
1473fn readBytes(bytes: []const u8, start_pos: usize) struct { []const u8, usize } {
1474 const len, const pos = readLeb(u32, bytes, start_pos);
1475 return .{
1476 bytes[pos..][0..len],
1477 pos + len,
1478 };
1479}
1480
1481fn readEnum(comptime T: type, bytes: []const u8, pos: usize) struct { T, usize } {
1482 const Tag = @typeInfo(T).@"enum".tag_type;
1483 const int, const new_pos = readLeb(Tag, bytes, pos);
1484 return .{ @enumFromInt(int), new_pos };
1485}
1486
1487fn readLimits(bytes: []const u8, start_pos: usize) struct { std.wasm.Limits, usize } {
1488 const flags: std.wasm.Limits.Flags = @bitCast(bytes[start_pos]);
1489 const min, const max_pos = readLeb(u32, bytes, start_pos + 1);
1490 const max, const end_pos = if (flags.has_max) readLeb(u32, bytes, max_pos) else .{ 0, max_pos };
1491 return .{ .{
14921438 .flags = flags,
14931439 .min = min,
14941440 .max = max,
1495 }, end_pos };
1441 };
14961442}
14971443
1498fn readInit(wasm: *Wasm, bytes: []const u8, pos: usize) !struct { Wasm.Expr, usize } {
1499 const end_pos = try skipInit(bytes, pos); // one after the end opcode
1500 return .{ try wasm.addExpr(bytes[pos..end_pos]), end_pos };
1444fn readInit(wasm: *Wasm, br: *std.io.BufferedReader) anyerror!Wasm.Expr {
1445 const start = br.seek;
1446 try skipInit(br); // one after the end opcode
1447 return wasm.addExpr(br.storageBuffer()[start..br.seek]);
15011448}
15021449
1503pub fn exprEndPos(bytes: []const u8, pos: usize) error{InvalidInitOpcode}!usize {
1504 const opcode = bytes[pos];
1505 return switch (@as(std.wasm.Opcode, @enumFromInt(opcode))) {
1506 .i32_const => readLeb(i32, bytes, pos + 1)[1],
1507 .i64_const => readLeb(i64, bytes, pos + 1)[1],
1508 .f32_const => pos + 5,
1509 .f64_const => pos + 9,
1510 .global_get => readLeb(u32, bytes, pos + 1)[1],
1450pub fn skipInit(br: *std.io.BufferedReader) anyerror!void {
1451 switch (try br.takeEnum(std.wasm.Opcode, .little)) {
1452 .i32_const => _ = try br.takeLeb128(i32),
1453 .i64_const => _ = try br.takeLeb128(i64),
1454 .f32_const => try br.discard(5),
1455 .f64_const => try br.discard(9),
1456 .global_get => _ = try br.takeLeb128(u32),
15111457 else => return error.InvalidInitOpcode,
1512 };
1513}
1514
1515fn skipInit(bytes: []const u8, pos: usize) !usize {
1516 const end_pos = try exprEndPos(bytes, pos);
1517 const op, const final_pos = readEnum(std.wasm.Opcode, bytes, end_pos);
1518 if (op != .end) return error.InitExprMissingEnd;
1519 return final_pos;
1458 }
1459 if (try br.takeEnum(std.wasm.Opcode, .little) != .end) return error.InitExprMissingEnd;
15201460}
src/link/aarch64.zig+3-3
......@@ -4,7 +4,7 @@ pub inline fn isArithmeticOp(inst: *const [4]u8) bool {
44}
55
66pub fn writeAddImmInst(value: u12, code: *[4]u8) void {
7 var inst = Instruction{
7 var inst: Instruction = .{
88 .add_subtract_immediate = mem.bytesToValue(@FieldType(
99 Instruction,
1010 @tagName(Instruction.add_subtract_immediate),
......@@ -33,7 +33,7 @@ pub fn calcNumberOfPages(saddr: i64, taddr: i64) error{Overflow}!i21 {
3333}
3434
3535pub fn writeAdrpInst(pages: u21, code: *[4]u8) void {
36 var inst = Instruction{
36 var inst: Instruction = .{
3737 .pc_relative_address = mem.bytesToValue(@FieldType(
3838 Instruction,
3939 @tagName(Instruction.pc_relative_address),
......@@ -45,7 +45,7 @@ pub fn writeAdrpInst(pages: u21, code: *[4]u8) void {
4545}
4646
4747pub fn writeBranchImm(disp: i28, code: *[4]u8) void {
48 var inst = Instruction{
48 var inst: Instruction = .{
4949 .unconditional_branch_immediate = mem.bytesToValue(@FieldType(
5050 Instruction,
5151 @tagName(Instruction.unconditional_branch_immediate),
src/link/riscv.zig+22-24
......@@ -1,52 +1,50 @@
1pub fn writeSetSub6(comptime op: enum { set, sub }, code: *[1]u8, addend: anytype) void {
1pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io.BufferedWriter) anyerror!void {
22 const mask: u8 = 0b11_000000;
33 const actual: i8 = @truncate(addend);
4 var value: u8 = mem.readInt(u8, code, .little);
5 switch (op) {
6 .set => value = (value & mask) | @as(u8, @bitCast(actual & ~mask)),
7 .sub => value = (value & mask) | (@as(u8, @bitCast(@as(i8, @bitCast(value)) -| actual)) & ~mask),
8 }
9 mem.writeInt(u8, code, value, .little);
4 const old_value = (try bw.writableSlice(1))[0];
5 const new_value = (old_value & mask) | (@as(u8, switch (op) {
6 .set => @bitCast(actual),
7 .sub => @bitCast(@as(i8, @bitCast(old_value)) -| actual),
8 }) & ~mask);
9 try bw.writeByte(new_value);
1010}
1111
12pub fn writeSetSubUleb(comptime op: enum { set, sub }, stream: *std.io.FixedBufferStream([]u8), addend: i64) !void {
12pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io.BufferedWriter) anyerror!void {
1313 switch (op) {
14 .set => try overwriteUleb(stream, @intCast(addend)),
14 .set => try overwriteUleb(@intCast(addend), bw),
1515 .sub => {
16 const position = try stream.getPos();
17 const value: u64 = try std.leb.readUleb128(u64, stream.reader());
18 try stream.seekTo(position);
19 try overwriteUleb(stream, value -% @as(u64, @intCast(addend)));
16 var br: std.io.BufferedReader = undefined;
17 br.initFixed(try bw.writableSlice(1));
18 const old_value = try br.takeLeb128(u64);
19 try overwriteUleb(old_value -% @as(u64, @intCast(addend)), bw);
2020 },
2121 }
2222}
2323
24fn overwriteUleb(stream: *std.io.FixedBufferStream([]u8), addend: u64) !void {
25 var value: u64 = addend;
26 const writer = stream.writer();
27
24fn overwriteUleb(new_value: u64, bw: *std.io.BufferedWriter) anyerror!void {
25 var value: u64 = new_value;
2826 while (true) {
29 const byte = stream.buffer[stream.pos];
27 const byte = (try bw.writableSlice(1))[0];
28 try bw.writeByte((byte & 0x80) | @as(u7, @truncate(value)));
3029 if (byte & 0x80 == 0) break;
31 try writer.writeByte(0x80 | @as(u8, @truncate(value & 0x7f)));
3230 value >>= 7;
3331 }
34 stream.buffer[stream.pos] = @truncate(value & 0x7f);
3532}
3633
3734pub fn writeAddend(
3835 comptime Int: type,
3936 comptime op: enum { add, sub },
40 code: *[@typeInfo(Int).int.bits / 8]u8,
4137 value: anytype,
42) void {
43 var V: Int = mem.readInt(Int, code, .little);
38 bw: *std.io.BufferedWriter,
39) anyerror!void {
40 const n = @divExact(@bitSizeOf(Int), 8);
41 var V: Int = mem.readInt(Int, (try bw.writableSlice(n))[0..n], .little);
4442 const addend: Int = @truncate(value);
4543 switch (op) {
4644 .add => V +|= addend, // TODO: I think saturating arithmetic is correct here
4745 .sub => V -|= addend,
4846 }
49 mem.writeInt(Int, code, V, .little);
47 try bw.writeInt(Int, V, .little);
5048}
5149
5250pub fn writeInstU(code: *[4]u8, value: u32) void {
src/link/table_section.zig+3-9
......@@ -39,17 +39,11 @@ pub fn TableSection(comptime Entry: type) type {
3939 return self.entries.items.len;
4040 }
4141
42 pub fn format(
43 self: Self,
44 comptime unused_format_string: []const u8,
45 options: std.fmt.FormatOptions,
46 writer: anytype,
47 ) !void {
48 _ = options;
42 pub fn format(self: Self, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void {
4943 comptime assert(unused_format_string.len == 0);
50 try writer.writeAll("TableSection:\n");
44 try bw.writeAll("TableSection:\n");
5145 for (self.entries.items, 0..) |entry, i| {
52 try writer.print(" {d} => {}\n", .{ i, entry });
46 try bw.print(" {d} => {}\n", .{ i, entry });
5347 }
5448 }
5549
src/main.zig+43-64
......@@ -66,7 +66,7 @@ pub fn wasi_cwd() std.os.wasi.fd_t {
6666const fatal = std.process.fatal;
6767
6868/// This can be global since stdout is a singleton.
69var stdout_buffer: [4096]u8 = undefined;
69var stdio_buffer: [4096]u8 = undefined;
7070
7171/// Shaming all the locations that inappropriately use an O(N) search algorithm.
7272/// Please delete this and fix the compilation errors!
......@@ -5477,7 +5477,7 @@ fn jitCmd(
54775477 defer comp.destroy();
54785478
54795479 if (options.server) {
5480 var server = std.zig.Server{
5480 var server: std.zig.Server = .{
54815481 .out = fs.File.stdout(),
54825482 .in = undefined, // won't be receiving messages
54835483 .receive_fifo = undefined, // won't be receiving messages
......@@ -5672,7 +5672,7 @@ const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true,
56725672/// Initialize the arguments from a Response File. "*.rsp"
56735673fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile {
56745674 const max_bytes = 10 * 1024 * 1024; // 10 MiB of command line arguments is a reasonable limit
5675 const cmd_line = try fs.cwd().readFileAlloc(allocator, resp_file_path, max_bytes);
5675 const cmd_line = try fs.cwd().readFileAlloc(resp_file_path, allocator, .limited(max_bytes));
56765676 errdefer allocator.free(cmd_line);
56775677
56785678 return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line);
......@@ -6061,11 +6061,7 @@ fn cmdAstCheck(
60616061
60626062 const tree = try Ast.parse(arena, source, mode);
60636063
6064 var bw: std.io.BufferedWriter = .{
6065 .unbuffered_writer = fs.File.stdout().writer(),
6066 .buffer = &stdout_buffer,
6067 };
6068
6064 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
60696065 switch (mode) {
60706066 .zig => {
60716067 const zir = try AstGen.generate(arena, tree);
......@@ -6109,7 +6105,7 @@ fn cmdAstCheck(
61096105 const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +
61106106 zir.string_bytes.len * @sizeOf(u8);
61116107 // zig fmt: off
6112 try bw.print(
6108 try stdout_bw.print(
61136109 \\# Source bytes: {Bi}
61146110 \\# Tokens: {} ({Bi})
61156111 \\# AST Nodes: {} ({Bi})
......@@ -6130,8 +6126,8 @@ fn cmdAstCheck(
61306126 // zig fmt: on
61316127 }
61326128
6133 try @import("print_zir.zig").renderAsText(arena, tree, zir, &bw);
6134 try bw.flush();
6129 try @import("print_zir.zig").renderAsText(arena, tree, zir, &stdout_bw);
6130 try stdout_bw.flush();
61356131
61366132 if (zir.hasCompileErrors()) {
61376133 process.exit(1);
......@@ -6158,8 +6154,8 @@ fn cmdAstCheck(
61586154 fatal("-t option only available in builds of zig with debug extensions", .{});
61596155 }
61606156
6161 try @import("print_zoir.zig").renderToWriter(zoir, arena, &bw);
6162 try bw.flush();
6157 try @import("print_zoir.zig").renderToWriter(zoir, arena, &stdout_bw);
6158 try stdout_bw.flush();
61636159 return cleanExit();
61646160 },
61656161 }
......@@ -6187,8 +6183,7 @@ fn cmdDetectCpu(args: []const []const u8) !void {
61876183 const arg = args[i];
61886184 if (mem.startsWith(u8, arg, "-")) {
61896185 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
6190 const stdout = fs.File.stdout().writer();
6191 try stdout.writeAll(detect_cpu_usage);
6186 try fs.File.stdout().writeAll(detect_cpu_usage);
61926187 return cleanExit();
61936188 } else if (mem.eql(u8, arg, "--llvm")) {
61946189 use_llvm = true;
......@@ -6280,13 +6275,10 @@ fn detectNativeCpuWithLLVM(
62806275}
62816276
62826277fn printCpu(cpu: std.Target.Cpu) !void {
6283 var bw: std.io.BufferedWriter = .{
6284 .unbuffered_writer = fs.File.stdout().writer(),
6285 .buffer = &stdout_buffer,
6286 };
6278 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
62876279
62886280 if (cpu.model.llvm_name) |llvm_name| {
6289 try bw.print("{s}\n", .{llvm_name});
6281 try stdout_bw.print("{s}\n", .{llvm_name});
62906282 }
62916283
62926284 const all_features = cpu.arch.allFeaturesList();
......@@ -6295,10 +6287,10 @@ fn printCpu(cpu: std.Target.Cpu) !void {
62956287 const index: std.Target.Cpu.Feature.Set.Index = @intCast(index_usize);
62966288 const is_enabled = cpu.features.isEnabled(index);
62976289 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
6298 try bw.print("{c}{s}\n", .{ plus_or_minus, llvm_name });
6290 try stdout_bw.print("{c}{s}\n", .{ plus_or_minus, llvm_name });
62996291 }
63006292
6301 try bw.flush();
6293 try stdout_bw.flush();
63026294}
63036295
63046296fn cmdDumpLlvmInts(
......@@ -6331,16 +6323,13 @@ fn cmdDumpLlvmInts(
63316323 const dl = tm.createTargetDataLayout();
63326324 const context = llvm.Context.create();
63336325
6334 var bw = io.bufferedWriter(fs.File.stdout().writer());
6335 const stdout = bw.writer();
6336
6326 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
63376327 for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| {
63386328 const int_type = context.intType(bits);
63396329 const alignment = dl.abiAlignmentOfType(int_type);
6340 try stdout.print("LLVMABIAlignmentOfType(i{d}) == {d}\n", .{ bits, alignment });
6330 try stdout_bw.print("LLVMABIAlignmentOfType(i{d}) == {d}\n", .{ bits, alignment });
63416331 }
6342
6343 try bw.flush();
6332 try stdout_bw.flush();
63446333
63456334 return cleanExit();
63466335}
......@@ -6363,11 +6352,7 @@ fn cmdDumpZir(
63636352
63646353 const zir = try Zcu.loadZirCache(arena, f);
63656354
6366 var bw: std.io.BufferedWriter = .{
6367 .unbuffered_writer = fs.File.stdout().writer(),
6368 .buffer = &stdout_buffer,
6369 };
6370
6355 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
63716356 {
63726357 const instruction_bytes = zir.instructions.len *
63736358 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include
......@@ -6377,7 +6362,7 @@ fn cmdDumpZir(
63776362 const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes +
63786363 zir.string_bytes.len * @sizeOf(u8);
63796364 // zig fmt: off
6380 try bw.print(
6365 try stdout_bw.print(
63816366 \\# Total ZIR bytes: {Bi}
63826367 \\# Instructions: {d} ({Bi})
63836368 \\# String Table Bytes: {Bi}
......@@ -6392,8 +6377,8 @@ fn cmdDumpZir(
63926377 // zig fmt: on
63936378 }
63946379
6395 try @import("print_zir.zig").renderAsText(arena, null, zir, &bw);
6396 try bw.flush();
6380 try @import("print_zir.zig").renderAsText(arena, null, zir, &stdout_bw);
6381 try stdout_bw.flush();
63976382}
63986383
63996384/// This is only enabled for debug builds.
......@@ -6451,21 +6436,18 @@ fn cmdChangelist(
64516436 var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty;
64526437 try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map);
64536438
6454 var bw: std.io.BufferedWriter = .{
6455 .unbuffered_writer = fs.File.stdout().writer(),
6456 .buffer = &stdout_buffer,
6457 };
6439 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
64586440 {
6459 try bw.print("Instruction mappings:\n", .{});
6441 try stdout_bw.print("Instruction mappings:\n", .{});
64606442 var it = inst_map.iterator();
64616443 while (it.next()) |entry| {
6462 try bw.print(" %{d} => %{d}\n", .{
6444 try stdout_bw.print(" %{d} => %{d}\n", .{
64636445 @intFromEnum(entry.key_ptr.*),
64646446 @intFromEnum(entry.value_ptr.*),
64656447 });
64666448 }
64676449 }
6468 try bw.flush();
6450 try stdout_bw.flush();
64696451}
64706452
64716453fn eatIntPrefix(arg: []const u8, base: u8) []const u8 {
......@@ -6800,8 +6782,7 @@ fn cmdFetch(
68006782 const arg = args[i];
68016783 if (mem.startsWith(u8, arg, "-")) {
68026784 if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
6803 const stdout = fs.File.stdout().writer();
6804 try stdout.writeAll(usage_fetch);
6785 try fs.File.stdout().writeAll(usage_fetch);
68056786 return cleanExit();
68066787 } else if (mem.eql(u8, arg, "--global-cache-dir")) {
68076788 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
......@@ -6914,7 +6895,9 @@ fn cmdFetch(
69146895
69156896 const name = switch (save) {
69166897 .no => {
6917 try fs.File.stdout().writer().print("{s}\n", .{package_hash_slice});
6898 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
6899 try stdout_bw.print("{s}\n", .{package_hash_slice});
6900 try stdout_bw.flush();
69186901 return cleanExit();
69196902 },
69206903 .yes, .exact => |name| name: {
......@@ -6950,7 +6933,7 @@ fn cmdFetch(
69506933 var saved_path_or_url = path_or_url;
69516934
69526935 if (fetch.latest_commit) |latest_commit| resolved: {
6953 const latest_commit_hex = try std.fmt.allocPrint(arena, "{}", .{latest_commit});
6936 const latest_commit_hex = try std.fmt.allocPrint(arena, "{f}", .{latest_commit});
69546937
69556938 var uri = try std.Uri.parse(path_or_url);
69566939
......@@ -6963,7 +6946,7 @@ fn cmdFetch(
69636946 std.log.info("resolved ref '{s}' to commit {s}", .{ target_ref, latest_commit_hex });
69646947
69656948 // include the original refspec in a query parameter, could be used to check for updates
6966 uri.query = .{ .percent_encoded = try std.fmt.allocPrint(arena, "ref={%}", .{fragment}) };
6949 uri.query = .{ .percent_encoded = try std.fmt.allocPrint(arena, "ref={f%}", .{fragment}) };
69676950 } else {
69686951 std.log.info("resolved to commit {s}", .{latest_commit_hex});
69696952 }
......@@ -6972,22 +6955,22 @@ fn cmdFetch(
69726955 uri.fragment = .{ .raw = latest_commit_hex };
69736956
69746957 switch (save) {
6975 .yes => saved_path_or_url = try std.fmt.allocPrint(arena, "{}", .{uri}),
6958 .yes => saved_path_or_url = try std.fmt.allocPrint(arena, "{f}", .{uri}),
69766959 .no, .exact => {}, // keep the original URL
69776960 }
69786961 }
69796962
69806963 const new_node_init = try std.fmt.allocPrint(arena,
69816964 \\.{{
6982 \\ .url = "{}",
6983 \\ .hash = "{}",
6965 \\ .url = "{f}",
6966 \\ .hash = "{f}",
69846967 \\ }}
69856968 , .{
69866969 std.zig.fmtEscapes(saved_path_or_url),
69876970 std.zig.fmtEscapes(package_hash_slice),
69886971 });
69896972
6990 const new_node_text = try std.fmt.allocPrint(arena, ".{p_} = {s},\n", .{
6973 const new_node_text = try std.fmt.allocPrint(arena, ".{fp_} = {s},\n", .{
69916974 std.zig.fmtId(name), new_node_init,
69926975 });
69936976
......@@ -7014,12 +6997,12 @@ fn cmdFetch(
70146997
70156998 const location_replace = try std.fmt.allocPrint(
70166999 arena,
7017 "\"{}\"",
7000 "\"{f}\"",
70187001 .{std.zig.fmtEscapes(saved_path_or_url)},
70197002 );
70207003 const hash_replace = try std.fmt.allocPrint(
70217004 arena,
7022 "\"{}\"",
7005 "\"{f}\"",
70237006 .{std.zig.fmtEscapes(package_hash_slice)},
70247007 );
70257008
......@@ -7047,15 +7030,11 @@ fn cmdFetch(
70477030 fatal("unable to create {s} file: {s}", .{ Package.Manifest.basename, err });
70487031 };
70497032 defer file.close();
7050 var buffer: [4096]u8 = undefined;
7051 var bw: std.io.BufferedWriter = .{
7052 .unbuffered_writer = file.writer(),
7053 .buffer = &buffer,
7054 };
7055 ast.render(gpa, &bw, fixups) catch |err| fatal("failed to render AST to {s}: {s}", .{
7033 var stdout_bw = fs.File.stdout().writer().buffered(&stdio_buffer);
7034 ast.render(gpa, &stdout_bw, fixups) catch |err| fatal("failed to render AST to {s}: {s}", .{
70567035 Package.Manifest.basename, err,
70577036 });
7058 bw.flush() catch |err| fatal("failed to flush {s}: {s}", .{ Package.Manifest.basename, err });
7037 stdout_bw.flush() catch |err| fatal("failed to flush {s}: {s}", .{ Package.Manifest.basename, err });
70597038 return cleanExit();
70607039}
70617040
......@@ -7208,9 +7187,9 @@ fn loadManifest(
72087187) !struct { Package.Manifest, Ast } {
72097188 const manifest_bytes = while (true) {
72107189 break options.dir.readFileAllocOptions(
7211 arena,
72127190 Package.Manifest.basename,
7213 Package.Manifest.max_bytes,
7191 arena,
7192 .limited(Package.Manifest.max_bytes),
72147193 null,
72157194 .@"1",
72167195 0,
......@@ -7287,7 +7266,7 @@ const Templates = struct {
72877266 }
72887267
72897268 const max_bytes = 10 * 1024 * 1024;
7290 const contents = templates.dir.readFileAlloc(arena, template_path, max_bytes) catch |err| {
7269 const contents = templates.dir.readFileAlloc(template_path, arena, .limited(max_bytes)) catch |err| {
72917270 fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) });
72927271 };
72937272 templates.buffer.clearRetainingCapacity();
src/print_targets.zig+4-4
......@@ -27,9 +27,9 @@ fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target)
2727 defer zig_lib_directory.handle.close();
2828
2929 const abilists_contents = zig_lib_directory.handle.readFileAlloc(
30 arena,
3130 glibc.abilists_path,
32 glibc.abilists_max_size,
31 arena,
32 .limited(glibc.abilists_max_size),
3333 ) catch |err| switch (err) {
3434 error.OutOfMemory => return error.OutOfMemory,
3535 else => fatal("unable to read " ++ glibc.abilists_path ++ ": {s}", .{@errorName(err)}),
......@@ -37,7 +37,7 @@ fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target)
3737
3838 const glibc_abi = try glibc.loadMetaData(arena, abilists_contents);
3939
40 var sz = std.zon.stringify.serializer(output, .{});
40 var sz: std.zon.stringify.Serializer = .{ .writer = output };
4141
4242 {
4343 var root_obj = try sz.beginStruct(.{});
......@@ -60,7 +60,7 @@ fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target)
6060 {
6161 var glibc_obj = try root_obj.beginTupleField("glibc", .{});
6262 for (glibc_abi.all_versions) |ver| {
63 const tmp = try std.fmt.allocPrint(arena, "{}", .{ver});
63 const tmp = try std.fmt.allocPrint(arena, "{f}", .{ver});
6464 try glibc_obj.field(tmp, .{});
6565 }
6666 try glibc_obj.end();
src/print_value.zig+113-124
......@@ -20,16 +20,10 @@ pub const FormatContext = struct {
2020 depth: u8,
2121};
2222
23pub fn formatSema(
24 ctx: FormatContext,
25 comptime fmt: []const u8,
26 options: std.fmt.Options,
27 writer: *std.io.BufferedWriter,
28) anyerror!void {
29 _ = options;
23pub fn formatSema(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
3024 const sema = ctx.opt_sema.?;
3125 comptime std.debug.assert(fmt.len == 0);
32 return print(ctx.val, writer, ctx.depth, ctx.pt, sema) catch |err| switch (err) {
26 return print(ctx.val, bw, ctx.depth, ctx.pt, sema) catch |err| switch (err) {
3327 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
3428 error.ComptimeBreak, error.ComptimeReturn => unreachable,
3529 error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `sema` more fully
......@@ -37,16 +31,10 @@ pub fn formatSema(
3731 };
3832}
3933
40pub fn format(
41 ctx: FormatContext,
42 comptime fmt: []const u8,
43 options: std.fmt.Options,
44 writer: *std.io.BufferedWriter,
45) anyerror!void {
46 _ = options;
34pub fn format(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void {
4735 std.debug.assert(ctx.opt_sema == null);
4836 comptime std.debug.assert(fmt.len == 0);
49 return print(ctx.val, writer, ctx.depth, ctx.pt, null) catch |err| switch (err) {
37 return print(ctx.val, bw, ctx.depth, ctx.pt, null) catch |err| switch (err) {
5038 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
5139 error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable,
5240 else => |e| return e,
......@@ -55,7 +43,7 @@ pub fn format(
5543
5644pub fn print(
5745 val: Value,
58 writer: *std.io.BufferedWriter,
46 bw: *std.io.BufferedWriter,
5947 level: u8,
6048 pt: Zcu.PerThread,
6149 opt_sema: ?*Sema,
......@@ -79,61 +67,62 @@ pub fn print(
7967 .func_type,
8068 .error_set_type,
8169 .inferred_error_set_type,
82 => try Type.print(val.toType(), writer, pt),
83 .undef => try writer.writeAll("undefined"),
70 => try Type.print(val.toType(), bw, pt),
71 .undef => try bw.writeAll("undefined"),
8472 .simple_value => |simple_value| switch (simple_value) {
85 .void => try writer.writeAll("{}"),
86 .empty_tuple => try writer.writeAll(".{}"),
87 else => try writer.writeAll(@tagName(simple_value)),
73 .void => try bw.writeAll("{}"),
74 .empty_tuple => try bw.writeAll(".{}"),
75 else => try bw.writeAll(@tagName(simple_value)),
8876 },
89 .variable => try writer.writeAll("(variable)"),
90 .@"extern" => |e| try writer.print("(extern '{}')", .{e.name.fmt(ip)}),
91 .func => |func| try writer.print("(function '{}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}),
77 .variable => try bw.writeAll("(variable)"),
78 .@"extern" => |e| try bw.print("(extern '{f}')", .{e.name.fmt(ip)}),
79 .func => |func| try bw.print("(function '{f}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}),
9280 .int => |int| switch (int.storage) {
93 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
81 inline .u64, .i64 => |x| try bw.print("{d}", .{x}),
82 .big_int => |x| try bw.print("{f}", .{x}),
9483 .lazy_align => |ty| if (opt_sema != null) {
9584 const a = try Type.fromInterned(ty).abiAlignmentSema(pt);
96 try writer.print("{}", .{a.toByteUnits() orelse 0});
97 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(pt)}),
85 try bw.print("{}", .{a.toByteUnits() orelse 0});
86 } else try bw.print("@alignOf({f})", .{Type.fromInterned(ty).fmt(pt)}),
9887 .lazy_size => |ty| if (opt_sema != null) {
9988 const s = try Type.fromInterned(ty).abiSizeSema(pt);
100 try writer.print("{}", .{s});
101 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(pt)}),
89 try bw.print("{}", .{s});
90 } else try bw.print("@sizeOf({f})", .{Type.fromInterned(ty).fmt(pt)}),
10291 },
103 .err => |err| try writer.print("error.{}", .{
92 .err => |err| try bw.print("error.{f}", .{
10493 err.name.fmt(ip),
10594 }),
10695 .error_union => |error_union| switch (error_union.val) {
107 .err_name => |err_name| try writer.print("error.{}", .{
96 .err_name => |err_name| try bw.print("error.{f}", .{
10897 err_name.fmt(ip),
10998 }),
110 .payload => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema),
99 .payload => |payload| try print(Value.fromInterned(payload), bw, level, pt, opt_sema),
111100 },
112 .enum_literal => |enum_literal| try writer.print(".{}", .{
101 .enum_literal => |enum_literal| try bw.print(".{f}", .{
113102 enum_literal.fmt(ip),
114103 }),
115104 .enum_tag => |enum_tag| {
116105 const enum_type = ip.loadEnumType(val.typeOf(zcu).toIntern());
117106 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
118 return writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
107 return bw.print(".{fi}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
119108 }
120109 if (level == 0) {
121 return writer.writeAll("@enumFromInt(...)");
110 return bw.writeAll("@enumFromInt(...)");
122111 }
123 try writer.writeAll("@enumFromInt(");
124 try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema);
125 try writer.writeAll(")");
112 try bw.writeAll("@enumFromInt(");
113 try print(Value.fromInterned(enum_tag.int), bw, level - 1, pt, opt_sema);
114 try bw.writeAll(")");
126115 },
127 .empty_enum_value => try writer.writeAll("(empty enum value)"),
116 .empty_enum_value => try bw.writeAll("(empty enum value)"),
128117 .float => |float| switch (float.storage) {
129 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),
118 inline else => |x| try bw.print("{d}", .{@as(f64, @floatCast(x))}),
130119 },
131120 .slice => |slice| {
132121 if (ip.isUndef(slice.ptr)) {
133122 if (slice.len == .zero_usize) {
134 return writer.writeAll("&.{}");
123 return bw.writeAll("&.{}");
135124 }
136 try print(.fromInterned(slice.ptr), writer, level - 1, pt, opt_sema);
125 try print(.fromInterned(slice.ptr), bw, level - 1, pt, opt_sema);
137126 } else {
138127 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
139128 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
......@@ -144,15 +133,15 @@ pub fn print(
144133 // TODO: eventually we want to load the slice as an array with `sema`, but that's
145134 // currently not possible without e.g. triggering compile errors.
146135 }
147 try printPtr(Value.fromInterned(slice.ptr), null, writer, level, pt, opt_sema);
136 try printPtr(Value.fromInterned(slice.ptr), null, bw, level, pt, opt_sema);
148137 }
149 try writer.writeAll("[0..");
138 try bw.writeAll("[0..");
150139 if (level == 0) {
151 try writer.writeAll("(...)");
140 try bw.writeAll("(...)");
152141 } else {
153 try print(Value.fromInterned(slice.len), writer, level - 1, pt, opt_sema);
142 try print(Value.fromInterned(slice.len), bw, level - 1, pt, opt_sema);
154143 }
155 try writer.writeAll("]");
144 try bw.writeAll("]");
156145 },
157146 .ptr => {
158147 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {
......@@ -164,29 +153,29 @@ pub fn print(
164153 // TODO: eventually we want to load the pointer with `sema`, but that's
165154 // currently not possible without e.g. triggering compile errors.
166155 }
167 try printPtr(val, .rvalue, writer, level, pt, opt_sema);
156 try printPtr(val, .rvalue, bw, level, pt, opt_sema);
168157 },
169158 .opt => |opt| switch (opt.val) {
170 .none => try writer.writeAll("null"),
171 else => |payload| try print(Value.fromInterned(payload), writer, level, pt, opt_sema),
159 .none => try bw.writeAll("null"),
160 else => |payload| try print(Value.fromInterned(payload), bw, level, pt, opt_sema),
172161 },
173 .aggregate => |aggregate| try printAggregate(val, aggregate, false, writer, level, pt, opt_sema),
162 .aggregate => |aggregate| try printAggregate(val, aggregate, false, bw, level, pt, opt_sema),
174163 .un => |un| {
175164 if (level == 0) {
176 try writer.writeAll(".{ ... }");
165 try bw.writeAll(".{ ... }");
177166 return;
178167 }
179168 if (un.tag == .none) {
180169 const backing_ty = try val.typeOf(zcu).unionBackingType(pt);
181 try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(pt)});
182 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
183 try writer.writeAll("))");
170 try bw.print("@bitCast(@as({f}, ", .{backing_ty.fmt(pt)});
171 try print(Value.fromInterned(un.val), bw, level - 1, pt, opt_sema);
172 try bw.writeAll("))");
184173 } else {
185 try writer.writeAll(".{ ");
186 try print(Value.fromInterned(un.tag), writer, level - 1, pt, opt_sema);
187 try writer.writeAll(" = ");
188 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
189 try writer.writeAll(" }");
174 try bw.writeAll(".{ ");
175 try print(Value.fromInterned(un.tag), bw, level - 1, pt, opt_sema);
176 try bw.writeAll(" = ");
177 try print(Value.fromInterned(un.val), bw, level - 1, pt, opt_sema);
178 try bw.writeAll(" }");
190179 }
191180 },
192181 .memoized_call => unreachable,
......@@ -197,33 +186,33 @@ fn printAggregate(
197186 val: Value,
198187 aggregate: InternPool.Key.Aggregate,
199188 is_ref: bool,
200 writer: *std.io.BufferedWriter,
189 bw: *std.io.BufferedWriter,
201190 level: u8,
202191 pt: Zcu.PerThread,
203192 opt_sema: ?*Sema,
204193) anyerror!void {
205194 if (level == 0) {
206 if (is_ref) try writer.writeByte('&');
207 return writer.writeAll(".{ ... }");
195 if (is_ref) try bw.writeByte('&');
196 return bw.writeAll(".{ ... }");
208197 }
209198 const zcu = pt.zcu;
210199 const ip = &zcu.intern_pool;
211200 const ty = Type.fromInterned(aggregate.ty);
212201 switch (ty.zigTypeTag(zcu)) {
213202 .@"struct" => if (!ty.isTuple(zcu)) {
214 if (is_ref) try writer.writeByte('&');
203 if (is_ref) try bw.writeByte('&');
215204 if (ty.structFieldCount(zcu) == 0) {
216 return writer.writeAll(".{}");
205 return bw.writeAll(".{}");
217206 }
218 try writer.writeAll(".{ ");
207 try bw.writeAll(".{ ");
219208 const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items);
220209 for (0..max_len) |i| {
221 if (i != 0) try writer.writeAll(", ");
210 if (i != 0) try bw.writeAll(", ");
222211 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
223 try writer.print(".{i} = ", .{field_name.fmt(ip)});
224 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
212 try bw.print(".{fi} = ", .{field_name.fmt(ip)});
213 try print(try val.fieldValue(pt, i), bw, level - 1, pt, opt_sema);
225214 }
226 try writer.writeAll(" }");
215 try bw.writeAll(" }");
227216 return;
228217 },
229218 .array => {
......@@ -232,16 +221,16 @@ fn printAggregate(
232221 const len = ty.arrayLenIncludingSentinel(zcu);
233222 if (len == 0) break :string;
234223 const slice = bytes.toSlice(if (bytes.at(len - 1, ip) == 0) len - 1 else len, ip);
235 try writer.print("\"{}\"", .{std.zig.fmtEscapes(slice)});
236 if (!is_ref) try writer.writeAll(".*");
224 try bw.print("\"{f}\"", .{std.zig.fmtEscapes(slice)});
225 if (!is_ref) try bw.writeAll(".*");
237226 return;
238227 },
239228 .elems, .repeated_elem => {},
240229 }
241230 switch (ty.arrayLen(zcu)) {
242231 0 => {
243 if (is_ref) try writer.writeByte('&');
244 return writer.writeAll(".{}");
232 if (is_ref) try bw.writeByte('&');
233 return bw.writeAll(".{}");
245234 },
246235 1 => one_byte_str: {
247236 // The repr isn't `bytes`, but we might still be able to print this as a string
......@@ -249,47 +238,47 @@ fn printAggregate(
249238 const elem_val = Value.fromInterned(aggregate.storage.values()[0]);
250239 if (elem_val.isUndef(zcu)) break :one_byte_str;
251240 const byte = elem_val.toUnsignedInt(zcu);
252 try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})});
253 if (!is_ref) try writer.writeAll(".*");
241 try bw.print("\"{f}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})});
242 if (!is_ref) try bw.writeAll(".*");
254243 return;
255244 },
256245 else => {},
257246 }
258247 },
259248 .vector => if (ty.arrayLen(zcu) == 0) {
260 if (is_ref) try writer.writeByte('&');
261 return writer.writeAll(".{}");
249 if (is_ref) try bw.writeByte('&');
250 return bw.writeAll(".{}");
262251 },
263252 else => unreachable,
264253 }
265254
266255 const len = ty.arrayLen(zcu);
267256
268 if (is_ref) try writer.writeByte('&');
269 try writer.writeAll(".{ ");
257 if (is_ref) try bw.writeByte('&');
258 try bw.writeAll(".{ ");
270259
271260 const max_len = @min(len, max_aggregate_items);
272261 for (0..max_len) |i| {
273 if (i != 0) try writer.writeAll(", ");
274 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
262 if (i != 0) try bw.writeAll(", ");
263 try print(try val.fieldValue(pt, i), bw, level - 1, pt, opt_sema);
275264 }
276265 if (len > max_aggregate_items) {
277 try writer.writeAll(", ...");
266 try bw.writeAll(", ...");
278267 }
279 return writer.writeAll(" }");
268 return bw.writeAll(" }");
280269}
281270
282271fn printPtr(
283272 ptr_val: Value,
284273 /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen.
285274 want_kind: ?PrintPtrKind,
286 writer: *std.io.BufferedWriter,
275 bw: *std.io.BufferedWriter,
287276 level: u8,
288277 pt: Zcu.PerThread,
289278 opt_sema: ?*Sema,
290279) anyerror!void {
291280 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
292 .undef => return writer.writeAll("undefined"),
281 .undef => return bw.writeAll("undefined"),
293282 .ptr => |ptr| ptr,
294283 else => unreachable,
295284 };
......@@ -301,7 +290,7 @@ fn printPtr(
301290 Value.fromInterned(ptr.base_addr.uav.val),
302291 agg,
303292 true,
304 writer,
293 bw,
305294 level,
306295 pt,
307296 opt_sema,
......@@ -317,7 +306,7 @@ fn printPtr(
317306 else
318307 try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, false, null);
319308
320 _ = try printPtrDerivation(derivation, writer, pt, want_kind, .{ .print_val = .{
309 _ = try printPtrDerivation(derivation, bw, pt, want_kind, .{ .print_val = .{
321310 .level = level,
322311 .opt_sema = opt_sema,
323312 } }, 20);
......@@ -329,7 +318,7 @@ const PrintPtrKind = enum { lvalue, rvalue };
329318/// Returns the root derivation, which may be ignored.
330319pub fn printPtrDerivation(
331320 derivation: Value.PointerDeriveStep,
332 writer: *std.io.BufferedWriter,
321 bw: *std.io.BufferedWriter,
333322 pt: Zcu.PerThread,
334323 /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen.
335324 /// If this is `.rvalue`, the result may look like `&foo`, so it's not necessarily valid to treat it as
......@@ -361,7 +350,7 @@ pub fn printPtrDerivation(
361350 => |step| continue :root step.parent.*,
362351 else => |step| break :root step,
363352 };
364 try writer.writeAll("...");
353 try bw.writeAll("...");
365354 return root_step;
366355 }
367356
......@@ -384,39 +373,39 @@ pub fn printPtrDerivation(
384373 const need_kind = want_kind orelse result_kind;
385374
386375 if (need_kind == .rvalue and result_kind == .lvalue) {
387 try writer.writeByte('&');
376 try bw.writeByte('&');
388377 }
389378
390379 // null if `derivation` is the root.
391380 const root_or_null: ?Value.PointerDeriveStep = switch (derivation) {
392381 .eu_payload_ptr => |info| root: {
393 try writer.writeByte('(');
394 const root = try printPtrDerivation(info.parent.*, writer, pt, .lvalue, root_strat, ptr_depth - 1);
395 try writer.writeAll(" catch unreachable)");
382 try bw.writeByte('(');
383 const root = try printPtrDerivation(info.parent.*, bw, pt, .lvalue, root_strat, ptr_depth - 1);
384 try bw.writeAll(" catch unreachable)");
396385 break :root root;
397386 },
398387 .opt_payload_ptr => |info| root: {
399 const root = try printPtrDerivation(info.parent.*, writer, pt, .lvalue, root_strat, ptr_depth - 1);
400 try writer.writeAll(".?");
388 const root = try printPtrDerivation(info.parent.*, bw, pt, .lvalue, root_strat, ptr_depth - 1);
389 try bw.writeAll(".?");
401390 break :root root;
402391 },
403392 .field_ptr => |field| root: {
404 const root = try printPtrDerivation(field.parent.*, writer, pt, null, root_strat, ptr_depth - 1);
393 const root = try printPtrDerivation(field.parent.*, bw, pt, null, root_strat, ptr_depth - 1);
405394 const agg_ty = (try field.parent.ptrType(pt)).childType(zcu);
406395 switch (agg_ty.zigTypeTag(zcu)) {
407396 .@"struct" => if (agg_ty.structFieldName(field.field_idx, zcu).unwrap()) |field_name| {
408 try writer.print(".{i}", .{field_name.fmt(ip)});
397 try bw.print(".{fi}", .{field_name.fmt(ip)});
409398 } else {
410 try writer.print("[{d}]", .{field.field_idx});
399 try bw.print("[{d}]", .{field.field_idx});
411400 },
412401 .@"union" => {
413402 const tag_ty = agg_ty.unionTagTypeHypothetical(zcu);
414403 const field_name = tag_ty.enumFieldName(field.field_idx, zcu);
415 try writer.print(".{i}", .{field_name.fmt(ip)});
404 try bw.print(".{fi}", .{field_name.fmt(ip)});
416405 },
417406 .pointer => switch (field.field_idx) {
418 Value.slice_ptr_index => try writer.writeAll(".ptr"),
419 Value.slice_len_index => try writer.writeAll(".len"),
407 Value.slice_ptr_index => try bw.writeAll(".ptr"),
408 Value.slice_len_index => try bw.writeAll(".len"),
420409 else => unreachable,
421410 },
422411 else => unreachable,
......@@ -424,20 +413,20 @@ pub fn printPtrDerivation(
424413 break :root root;
425414 },
426415 .elem_ptr => |elem| root: {
427 const root = try printPtrDerivation(elem.parent.*, writer, pt, null, root_strat, ptr_depth - 1);
428 try writer.print("[{d}]", .{elem.elem_idx});
416 const root = try printPtrDerivation(elem.parent.*, bw, pt, null, root_strat, ptr_depth - 1);
417 try bw.print("[{d}]", .{elem.elem_idx});
429418 break :root root;
430419 },
431420
432421 .offset_and_cast => |oac| if (oac.byte_offset == 0) root: {
433 try writer.print("@as({}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)});
434 const root = try printPtrDerivation(oac.parent.*, writer, pt, .rvalue, root_strat, ptr_depth - 1);
435 try writer.writeAll("))");
422 try bw.print("@as({f}, @ptrCast(", .{oac.new_ptr_ty.fmt(pt)});
423 const root = try printPtrDerivation(oac.parent.*, bw, pt, .rvalue, root_strat, ptr_depth - 1);
424 try bw.writeAll("))");
436425 break :root root;
437426 } else root: {
438 try writer.print("@as({}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)});
439 const root = try printPtrDerivation(oac.parent.*, writer, pt, .rvalue, root_strat, ptr_depth - 1);
440 try writer.print(") + {d}))", .{oac.byte_offset});
427 try bw.print("@as({f}, @ptrFromInt(@intFromPtr(", .{oac.new_ptr_ty.fmt(pt)});
428 const root = try printPtrDerivation(oac.parent.*, bw, pt, .rvalue, root_strat, ptr_depth - 1);
429 try bw.print(") + {d}))", .{oac.byte_offset});
441430 break :root root;
442431 },
443432
......@@ -445,33 +434,33 @@ pub fn printPtrDerivation(
445434 };
446435
447436 if (root_or_null == null) switch (root_strat) {
448 .str => |x| try writer.writeAll(x),
437 .str => |x| try bw.writeAll(x),
449438 .print_val => |x| switch (derivation) {
450 .int => |int| try writer.print("@as({}, @ptrFromInt(0x{x}))", .{ int.ptr_ty.fmt(pt), int.addr }),
451 .nav_ptr => |nav| try writer.print("{}", .{ip.getNav(nav).fqn.fmt(ip)}),
439 .int => |int| try bw.print("@as({f}, @ptrFromInt(0x{x}))", .{ int.ptr_ty.fmt(pt), int.addr }),
440 .nav_ptr => |nav| try bw.print("{f}", .{ip.getNav(nav).fqn.fmt(ip)}),
452441 .uav_ptr => |uav| {
453442 const ty = Value.fromInterned(uav.val).typeOf(zcu);
454 try writer.print("@as({}, ", .{ty.fmt(pt)});
455 try print(Value.fromInterned(uav.val), writer, x.level - 1, pt, x.opt_sema);
456 try writer.writeByte(')');
443 try bw.print("@as({f}, ", .{ty.fmt(pt)});
444 try print(Value.fromInterned(uav.val), bw, x.level - 1, pt, x.opt_sema);
445 try bw.writeByte(')');
457446 },
458447 .comptime_alloc_ptr => |info| {
459 try writer.print("@as({}, ", .{info.val.typeOf(zcu).fmt(pt)});
460 try print(info.val, writer, x.level - 1, pt, x.opt_sema);
461 try writer.writeByte(')');
448 try bw.print("@as({f}, ", .{info.val.typeOf(zcu).fmt(pt)});
449 try print(info.val, bw, x.level - 1, pt, x.opt_sema);
450 try bw.writeByte(')');
462451 },
463452 .comptime_field_ptr => |val| {
464453 const ty = val.typeOf(zcu);
465 try writer.print("@as({}, ", .{ty.fmt(pt)});
466 try print(val, writer, x.level - 1, pt, x.opt_sema);
467 try writer.writeByte(')');
454 try bw.print("@as({f}, ", .{ty.fmt(pt)});
455 try print(val, bw, x.level - 1, pt, x.opt_sema);
456 try bw.writeByte(')');
468457 },
469458 else => unreachable,
470459 },
471460 };
472461
473462 if (need_kind == .lvalue and result_kind == .rvalue) {
474 try writer.writeAll(".*");
463 try bw.writeAll(".*");
475464 }
476465
477466 return root_or_null orelse derivation;
src/print_zir.zig+18-18
......@@ -41,7 +41,7 @@ pub fn renderAsText(gpa: Allocator, tree: ?Ast, zir: Zir, bw: *std.io.BufferedWr
4141 extra_index = item.end;
4242
4343 const import_path = zir.nullTerminatedString(item.data.name);
44 try bw.print(" @import(\"{}\") ", .{
44 try bw.print(" @import(\"{f}\") ", .{
4545 std.zig.fmtEscapes(import_path),
4646 });
4747 try writer.writeSrcTokAbs(bw, item.data.token);
......@@ -783,7 +783,7 @@ const Writer = struct {
783783 ) anyerror!void {
784784 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
785785 const str = inst_data.get(self.code);
786 try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)});
786 try stream.print("\"{f}\")", .{std.zig.fmtEscapes(str)});
787787 }
788788
789789 fn writeSliceStart(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void {
......@@ -939,7 +939,7 @@ const Writer = struct {
939939 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
940940 const extra = self.code.extraData(Zir.Inst.Param, inst_data.payload_index);
941941 const body = self.code.bodySlice(extra.end, extra.data.type.body_len);
942 try stream.print("\"{}\", ", .{
942 try stream.print("\"{f}\", ", .{
943943 std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)),
944944 });
945945
......@@ -1210,7 +1210,7 @@ const Writer = struct {
12101210 try stream.writeAll(", ");
12111211 } else {
12121212 const asm_source = self.code.nullTerminatedString(extra.data.asm_source);
1213 try stream.print("\"{}\", ", .{std.zig.fmtEscapes(asm_source)});
1213 try stream.print("\"{f}\", ", .{std.zig.fmtEscapes(asm_source)});
12141214 }
12151215 try stream.writeAll(", ");
12161216
......@@ -1227,7 +1227,7 @@ const Writer = struct {
12271227
12281228 const name = self.code.nullTerminatedString(output.data.name);
12291229 const constraint = self.code.nullTerminatedString(output.data.constraint);
1230 try stream.print("output({p}, \"{}\", ", .{
1230 try stream.print("output({fp}, \"{f}\", ", .{
12311231 std.zig.fmtId(name), std.zig.fmtEscapes(constraint),
12321232 });
12331233 try self.writeFlag(stream, "->", is_type);
......@@ -1246,7 +1246,7 @@ const Writer = struct {
12461246
12471247 const name = self.code.nullTerminatedString(input.data.name);
12481248 const constraint = self.code.nullTerminatedString(input.data.constraint);
1249 try stream.print("input({p}, \"{}\", ", .{
1249 try stream.print("input({fp}, \"{f}\", ", .{
12501250 std.zig.fmtId(name), std.zig.fmtEscapes(constraint),
12511251 });
12521252 try self.writeInstRef(stream, input.data.operand);
......@@ -1262,7 +1262,7 @@ const Writer = struct {
12621262 const str_index = self.code.extra[extra_i];
12631263 extra_i += 1;
12641264 const clobber = self.code.nullTerminatedString(@enumFromInt(str_index));
1265 try stream.print("{p}", .{std.zig.fmtId(clobber)});
1265 try stream.print("{fp}", .{std.zig.fmtId(clobber)});
12661266 if (i + 1 < clobbers_len) {
12671267 try stream.writeAll(", ");
12681268 }
......@@ -1306,7 +1306,7 @@ const Writer = struct {
13061306 .field => {
13071307 const field_name = self.code.nullTerminatedString(extra.data.field_name_start);
13081308 try self.writeInstRef(stream, extra.data.obj_ptr);
1309 try stream.print(", \"{}\"", .{std.zig.fmtEscapes(field_name)});
1309 try stream.print(", \"{f}\"", .{std.zig.fmtEscapes(field_name)});
13101310 },
13111311 }
13121312 try stream.writeAll(", [");
......@@ -1526,7 +1526,7 @@ const Writer = struct {
15261526 try self.writeFlag(stream, "comptime ", field.is_comptime);
15271527 if (field.name != .empty) {
15281528 const field_name = self.code.nullTerminatedString(field.name);
1529 try stream.print("{p}: ", .{std.zig.fmtId(field_name)});
1529 try stream.print("{fp}: ", .{std.zig.fmtId(field_name)});
15301530 } else {
15311531 try stream.print("@\"{d}\": ", .{i});
15321532 }
......@@ -1689,7 +1689,7 @@ const Writer = struct {
16891689 extra_index += 1;
16901690
16911691 try stream.splatByteAll(' ', self.indent);
1692 try stream.print("{p}", .{std.zig.fmtId(field_name)});
1692 try stream.print("{fp}", .{std.zig.fmtId(field_name)});
16931693
16941694 if (has_type) {
16951695 const field_type = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
......@@ -1823,7 +1823,7 @@ const Writer = struct {
18231823 extra_index += 1;
18241824
18251825 try stream.splatByteAll(' ', self.indent);
1826 try stream.print("{p}", .{std.zig.fmtId(field_name)});
1826 try stream.print("{fp}", .{std.zig.fmtId(field_name)});
18271827
18281828 if (has_tag_value) {
18291829 const tag_value_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
......@@ -1928,7 +1928,7 @@ const Writer = struct {
19281928 const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
19291929 const name = self.code.nullTerminatedString(name_index);
19301930 try stream.splatByteAll(' ', self.indent);
1931 try stream.print("{p},\n", .{std.zig.fmtId(name)});
1931 try stream.print("{fp},\n", .{std.zig.fmtId(name)});
19321932 }
19331933
19341934 self.indent -= 2;
......@@ -2210,7 +2210,7 @@ const Writer = struct {
22102210 const extra = self.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
22112211 const name = self.code.nullTerminatedString(extra.field_name_start);
22122212 try self.writeInstRef(stream, extra.lhs);
2213 try stream.print(", \"{}\") ", .{std.zig.fmtEscapes(name)});
2213 try stream.print(", \"{f}\") ", .{std.zig.fmtEscapes(name)});
22142214 try self.writeSrcNode(stream, inst_data.src_node);
22152215 }
22162216
......@@ -2251,7 +2251,7 @@ const Writer = struct {
22512251 ) anyerror!void {
22522252 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
22532253 const str = inst_data.get(self.code);
2254 try stream.print("\"{}\") ", .{std.zig.fmtEscapes(str)});
2254 try stream.print("\"{f}\") ", .{std.zig.fmtEscapes(str)});
22552255 try self.writeSrcTok(stream, inst_data.src_tok);
22562256 }
22572257
......@@ -2259,7 +2259,7 @@ const Writer = struct {
22592259 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_op;
22602260 const str = inst_data.getStr(self.code);
22612261 try self.writeInstRef(stream, inst_data.operand);
2262 try stream.print(", \"{}\")", .{std.zig.fmtEscapes(str)});
2262 try stream.print(", \"{f}\")", .{std.zig.fmtEscapes(str)});
22632263 }
22642264
22652265 fn writeFunc(
......@@ -2700,10 +2700,10 @@ const Writer = struct {
27002700 try stream.writeAll("load ");
27012701 try self.writeInstIndex(stream, ptr_inst);
27022702 },
2703 .decl_val => |str| try stream.print("decl_val \"{}\"", .{
2703 .decl_val => |str| try stream.print("decl_val \"{f}\"", .{
27042704 std.zig.fmtEscapes(self.code.nullTerminatedString(str)),
27052705 }),
2706 .decl_ref => |str| try stream.print("decl_ref \"{}\"", .{
2706 .decl_ref => |str| try stream.print("decl_ref \"{f}\"", .{
27072707 std.zig.fmtEscapes(self.code.nullTerminatedString(str)),
27082708 }),
27092709 }
......@@ -2837,7 +2837,7 @@ const Writer = struct {
28372837 const extra = self.code.extraData(Zir.Inst.Import, inst_data.payload_index).data;
28382838 try self.writeInstRef(stream, extra.res_ty);
28392839 const import_path = self.code.nullTerminatedString(extra.path);
2840 try stream.print(", \"{}\") ", .{std.zig.fmtEscapes(import_path)});
2840 try stream.print(", \"{f}\") ", .{std.zig.fmtEscapes(import_path)});
28412841 try self.writeSrcTok(stream, inst_data.src_tok);
28422842 }
28432843};
src/print_zoir.zig+3-3
......@@ -70,8 +70,8 @@ const PrintZon = struct {
7070 },
7171 .float_literal => |x| try pz.w.print("float({d})", .{x}),
7272 .char_literal => |x| try pz.w.print("char({d})", .{x}),
73 .enum_literal => |x| try pz.w.print("enum_literal({p})", .{std.zig.fmtId(x.get(zoir))}),
74 .string_literal => |x| try pz.w.print("str(\"{}\")", .{std.zig.fmtEscapes(x)}),
73 .enum_literal => |x| try pz.w.print("enum_literal({fp})", .{std.zig.fmtId(x.get(zoir))}),
74 .string_literal => |x| try pz.w.print("str(\"{f}\")", .{std.zig.fmtEscapes(x)}),
7575 .empty_literal => try pz.w.writeAll("empty_literal(.{})"),
7676 .array_literal => |vals| {
7777 try pz.w.writeAll("array_literal({");
......@@ -90,7 +90,7 @@ const PrintZon = struct {
9090 pz.indent += 1;
9191 for (s.names, 0..s.vals.len) |name, idx| {
9292 try pz.newline();
93 try pz.w.print("[{p}] ", .{std.zig.fmtId(name.get(zoir))});
93 try pz.w.print("[{fp}] ", .{std.zig.fmtId(name.get(zoir))});
9494 try pz.renderNode(s.vals.at(@intCast(idx)));
9595 try pz.w.writeByte(',');
9696 }
src/register_manager.zig+3-3
......@@ -238,7 +238,7 @@ pub fn RegisterManager(
238238 if (i < count) return null;
239239
240240 for (regs, insts) |reg, inst| {
241 log.debug("tryAllocReg {} for inst {?}", .{ reg, inst });
241 log.debug("tryAllocReg {} for inst {?f}", .{ reg, inst });
242242 self.markRegAllocated(reg);
243243
244244 if (inst) |tracked_inst| {
......@@ -317,7 +317,7 @@ pub fn RegisterManager(
317317 tracked_index: TrackedIndex,
318318 inst: ?Air.Inst.Index,
319319 ) AllocationError!void {
320 log.debug("getReg {} for inst {?}", .{ regAtTrackedIndex(tracked_index), inst });
320 log.debug("getReg {} for inst {?f}", .{ regAtTrackedIndex(tracked_index), inst });
321321 if (!self.isRegIndexFree(tracked_index)) {
322322 // Move the instruction that was previously there to a
323323 // stack allocation.
......@@ -349,7 +349,7 @@ pub fn RegisterManager(
349349 tracked_index: TrackedIndex,
350350 inst: ?Air.Inst.Index,
351351 ) void {
352 log.debug("getRegAssumeFree {} for inst {?}", .{ regAtTrackedIndex(tracked_index), inst });
352 log.debug("getRegAssumeFree {} for inst {?f}", .{ regAtTrackedIndex(tracked_index), inst });
353353 self.markRegIndexAllocated(tracked_index);
354354
355355 assert(self.isRegIndexFree(tracked_index));
src/translate_c.zig+8-8
......@@ -357,7 +357,7 @@ fn transFileScopeAsm(c: *Context, scope: *Scope, file_scope_asm: *const clang.Fi
357357 var len: usize = undefined;
358358 const bytes_ptr = asm_string.getString_bytes_begin_size(&len);
359359
360 const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])});
360 const str = try std.fmt.allocPrint(c.arena, "\"{f}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])});
361361 const str_node = try Tag.string_literal.create(c.arena, str);
362362
363363 const asm_node = try Tag.asm_simple.create(c.arena, str_node);
......@@ -2276,7 +2276,7 @@ fn transNarrowStringLiteral(
22762276 var len: usize = undefined;
22772277 const bytes_ptr = stmt.getString_bytes_begin_size(&len);
22782278
2279 const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])});
2279 const str = try std.fmt.allocPrint(c.arena, "\"{f}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])});
22802280 const node = try Tag.string_literal.create(c.arena, str);
22812281 return maybeSuppressResult(c, result_used, node);
22822282}
......@@ -3338,7 +3338,7 @@ fn transPredefinedExpr(c: *Context, scope: *Scope, expr: *const clang.Predefined
33383338
33393339fn transCreateCharLitNode(c: *Context, narrow: bool, val: u32) TransError!Node {
33403340 return Tag.char_literal.create(c.arena, if (narrow)
3341 try std.fmt.allocPrint(c.arena, "'{'}'", .{std.zig.fmtEscapes(&.{@as(u8, @intCast(val))})})
3341 try std.fmt.allocPrint(c.arena, "'{f'}'", .{std.zig.fmtEscapes(&.{@as(u8, @intCast(val))})})
33423342 else
33433343 try std.fmt.allocPrint(c.arena, "'\\u{{{x}}}'", .{val}));
33443344}
......@@ -5832,7 +5832,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
58325832 num += c - 'A' + 10;
58335833 },
58345834 else => {
5835 i += std.fmt.formatIntBuf(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
5835 i += std.fmt.printInt(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
58365836 num = 0;
58375837 if (c == '\\')
58385838 state = .escape
......@@ -5858,7 +5858,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
58585858 };
58595859 num += c - '0';
58605860 } else {
5861 i += std.fmt.formatIntBuf(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
5861 i += std.fmt.printInt(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
58625862 num = 0;
58635863 count = 0;
58645864 if (c == '\\')
......@@ -5872,7 +5872,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
58725872 }
58735873 }
58745874 if (state == .hex or state == .octal)
5875 i += std.fmt.formatIntBuf(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
5875 i += std.fmt.printInt(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
58765876 return bytes[0..i];
58775877}
58785878
......@@ -5884,9 +5884,9 @@ fn escapeUnprintables(ctx: *Context, m: *MacroCtx) ![]const u8 {
58845884 if (std.unicode.utf8ValidateSlice(zigified)) return zigified;
58855885
58865886 const formatter = std.fmt.fmtSliceEscapeLower(zigified);
5887 const encoded_size = @as(usize, @intCast(std.fmt.count("{s}", .{formatter})));
5887 const encoded_size = std.fmt.count("{f}", .{formatter});
58885888 const output = try ctx.arena.alloc(u8, encoded_size);
5889 return std.fmt.bufPrint(output, "{s}", .{formatter}) catch |err| switch (err) {
5889 return std.fmt.bufPrint(output, "{f}", .{formatter}) catch |err| switch (err) {
58905890 error.NoSpaceLeft => unreachable,
58915891 else => |e| return e,
58925892 };