| author | |
| committer | |
| log | f3d0fc7a66fa40e86036e7c626231e7de265cd64 |
| tree | aac6243b4e4e5de1f3f941a7bf6e88d9e46ac01b |
| parent | a21e7ab64f66c83c57b2d87b71c19d50d94ed543 |
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 |
| 546 | 546 | } |
| 547 | 547 | |
| 548 | 548 | 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)}); | |
| 550 | 550 | |
| 551 | 551 | // standard macros |
| 552 | 552 | try buf.appendSlice( |
lib/compiler/build_runner.zig+5-2| ... | ... | @@ -695,7 +695,10 @@ fn runStepNames( |
| 695 | 695 | |
| 696 | 696 | if (run.summary != .none) { |
| 697 | 697 | var bw = std.debug.lockStdErr2(&stdio_buffer); |
| 698 | defer std.debug.unlockStdErr(); | |
| 698 | defer { | |
| 699 | bw.flush() catch {}; | |
| 700 | std.debug.unlockStdErr(); | |
| 701 | } | |
| 699 | 702 | |
| 700 | 703 | const total_count = success_count + failure_count + pending_count + skipped_count; |
| 701 | 704 | ttyconf.setColor(&bw, .cyan) catch {}; |
| ... | ... | @@ -710,7 +713,7 @@ fn runStepNames( |
| 710 | 713 | if (test_fail_count > 0) bw.print("; {d} failed", .{test_fail_count}) catch {}; |
| 711 | 714 | if (test_leak_count > 0) bw.print("; {d} leaked", .{test_leak_count}) catch {}; |
| 712 | 715 | |
| 713 | bw.writeAll("\n") catch {}; | |
| 716 | bw.writeByte('\n') catch {}; | |
| 714 | 717 | |
| 715 | 718 | // Print a fancy tree with build results. |
| 716 | 719 | 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 { |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | 135 | pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8 { |
| 136 | return std.fmt.allocPrint(allocator, "{}", .{p}); | |
| 136 | return std.fmt.allocPrint(allocator, "{f}", .{p}); | |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | pub 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}); | |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | pub fn format( |
lib/std/Build/Step.zig+4-4| ... | ... | @@ -469,7 +469,7 @@ pub fn evalZigProcess( |
| 469 | 469 | // This is intentionally printed for failure on the first build but not for |
| 470 | 470 | // subsequent rebuilds. |
| 471 | 471 | 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", .{ | |
| 473 | 473 | s.result_error_bundle.errorMessageCount(), |
| 474 | 474 | try allocPrintCmd(arena, null, argv), |
| 475 | 475 | }); |
| ... | ... | @@ -689,7 +689,7 @@ pub inline fn handleChildProcUnsupported( |
| 689 | 689 | ) error{ OutOfMemory, MakeFailed }!void { |
| 690 | 690 | if (!std.process.can_spawn) { |
| 691 | 691 | 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", | |
| 693 | 693 | .{try allocPrintCmd(s.owner.allocator, opt_cwd, argv)}, |
| 694 | 694 | ); |
| 695 | 695 | } |
| ... | ... | @@ -706,14 +706,14 @@ pub fn handleChildProcessTerm( |
| 706 | 706 | .Exited => |code| { |
| 707 | 707 | if (code != 0) { |
| 708 | 708 | 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", | |
| 710 | 710 | .{ code, try allocPrintCmd(arena, opt_cwd, argv) }, |
| 711 | 711 | ); |
| 712 | 712 | } |
| 713 | 713 | }, |
| 714 | 714 | .Signal, .Stopped, .Unknown => { |
| 715 | 715 | return s.fail( |
| 716 | "the following command terminated unexpectedly:\n{s}", | |
| 716 | "the following command terminated unexpectedly:\n{s}\n", | |
| 717 | 717 | .{try allocPrintCmd(arena, opt_cwd, argv)}, |
| 718 | 718 | ); |
| 719 | 719 | }, |
lib/std/Build/Step/CheckObject.zig+4-4| ... | ... | @@ -1523,11 +1523,11 @@ const MachODumper = struct { |
| 1523 | 1523 | ) !void { |
| 1524 | 1524 | const size = try br.takeLeb128(u64); |
| 1525 | 1525 | if (size > 0) { |
| 1526 | const flags = try br.takeLeb128(u64); | |
| 1526 | const flags = try br.takeLeb128(u8); | |
| 1527 | 1527 | switch (flags) { |
| 1528 | 1528 | macho.EXPORT_SYMBOL_FLAGS_REEXPORT => { |
| 1529 | 1529 | const ord = try br.takeLeb128(u64); |
| 1530 | const name = try br.takeDelimiterConclusive(0); | |
| 1530 | const name = try br.takeSentinel(0); | |
| 1531 | 1531 | try exports.append(.{ |
| 1532 | 1532 | .name = if (name.len > 0) name else prefix, |
| 1533 | 1533 | .tag = .reexport, |
| ... | ... | @@ -1568,8 +1568,8 @@ const MachODumper = struct { |
| 1568 | 1568 | |
| 1569 | 1569 | const nedges = try br.takeByte(); |
| 1570 | 1570 | 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); | |
| 1573 | 1573 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); |
| 1574 | 1574 | const seek = br.seek; |
| 1575 | 1575 | br.seek = off; |
lib/std/Target.zig+7-12| ... | ... | @@ -301,28 +301,23 @@ pub const Os = struct { |
| 301 | 301 | |
| 302 | 302 | /// This function is defined to serialize a Zig source code representation of this |
| 303 | 303 | /// 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 { | |
| 310 | 305 | const maybe_name = std.enums.tagName(WindowsVersion, ver); |
| 311 | 306 | if (comptime std.mem.eql(u8, fmt_str, "s")) { |
| 312 | 307 | if (maybe_name) |name| |
| 313 | try writer.print(".{s}", .{name}) | |
| 308 | try bw.print(".{s}", .{name}) | |
| 314 | 309 | else |
| 315 | try writer.print(".{d}", .{@intFromEnum(ver)}); | |
| 310 | try bw.print(".{d}", .{@intFromEnum(ver)}); | |
| 316 | 311 | } else if (comptime std.mem.eql(u8, fmt_str, "c")) { |
| 317 | 312 | if (maybe_name) |name| |
| 318 | try writer.print(".{s}", .{name}) | |
| 313 | try bw.print(".{s}", .{name}) | |
| 319 | 314 | else |
| 320 | try writer.print("@enumFromInt(0x{X:0>8})", .{@intFromEnum(ver)}); | |
| 315 | try bw.print("@enumFromInt(0x{X:0>8})", .{@intFromEnum(ver)}); | |
| 321 | 316 | } else if (fmt_str.len == 0) { |
| 322 | 317 | if (maybe_name) |name| |
| 323 | try writer.print("WindowsVersion.{s}", .{name}) | |
| 318 | try bw.print("WindowsVersion.{s}", .{name}) | |
| 324 | 319 | else |
| 325 | try writer.print("WindowsVersion(0x{X:0>8})", .{@intFromEnum(ver)}); | |
| 320 | try bw.print("WindowsVersion(0x{X:0>8})", .{@intFromEnum(ver)}); | |
| 326 | 321 | } else std.fmt.invalidFmtError(fmt_str, ver); |
| 327 | 322 | } |
| 328 | 323 | }; |
lib/std/Uri.zig+13-13| ... | ... | @@ -236,44 +236,44 @@ pub const WriteToStreamOptions = struct { |
| 236 | 236 | port: bool = true, |
| 237 | 237 | }; |
| 238 | 238 | |
| 239 | pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, writer: *std.io.BufferedWriter) anyerror!void { | |
| 239 | pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.BufferedWriter) anyerror!void { | |
| 240 | 240 | if (options.scheme) { |
| 241 | try writer.print("{s}:", .{uri.scheme}); | |
| 241 | try bw.print("{s}:", .{uri.scheme}); | |
| 242 | 242 | if (options.authority and uri.host != null) { |
| 243 | try writer.writeAll("//"); | |
| 243 | try bw.writeAll("//"); | |
| 244 | 244 | } |
| 245 | 245 | } |
| 246 | 246 | if (options.authority) { |
| 247 | 247 | if (options.authentication and uri.host != null) { |
| 248 | 248 | if (uri.user) |user| { |
| 249 | try writer.print("{fuser}", .{user}); | |
| 249 | try bw.print("{fuser}", .{user}); | |
| 250 | 250 | if (uri.password) |password| { |
| 251 | try writer.print(":{fpassword}", .{password}); | |
| 251 | try bw.print(":{fpassword}", .{password}); | |
| 252 | 252 | } |
| 253 | try writer.writeByte('@'); | |
| 253 | try bw.writeByte('@'); | |
| 254 | 254 | } |
| 255 | 255 | } |
| 256 | 256 | if (uri.host) |host| { |
| 257 | try writer.print("{fhost}", .{host}); | |
| 257 | try bw.print("{fhost}", .{host}); | |
| 258 | 258 | if (options.port) { |
| 259 | if (uri.port) |port| try writer.print(":{d}", .{port}); | |
| 259 | if (uri.port) |port| try bw.print(":{d}", .{port}); | |
| 260 | 260 | } |
| 261 | 261 | } |
| 262 | 262 | } |
| 263 | 263 | if (options.path) { |
| 264 | try writer.print("{fpath}", .{ | |
| 264 | try bw.print("{fpath}", .{ | |
| 265 | 265 | if (uri.path.isEmpty()) Uri.Component{ .percent_encoded = "/" } else uri.path, |
| 266 | 266 | }); |
| 267 | 267 | if (options.query) { |
| 268 | if (uri.query) |query| try writer.print("?{fquery}", .{query}); | |
| 268 | if (uri.query) |query| try bw.print("?{fquery}", .{query}); | |
| 269 | 269 | } |
| 270 | 270 | if (options.fragment) { |
| 271 | if (uri.fragment) |fragment| try writer.print("#{ffragment}", .{fragment}); | |
| 271 | if (uri.fragment) |fragment| try bw.print("#{ffragment}", .{fragment}); | |
| 272 | 272 | } |
| 273 | 273 | } |
| 274 | 274 | } |
| 275 | 275 | |
| 276 | pub fn format(uri: Uri, comptime fmt: []const u8, _: std.fmt.Options, writer: *std.io.BufferedWriter) anyerror!void { | |
| 276 | pub fn format(uri: Uri, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void { | |
| 277 | 277 | const scheme = comptime std.mem.indexOfScalar(u8, fmt, ';') != null or fmt.len == 0; |
| 278 | 278 | const authentication = comptime std.mem.indexOfScalar(u8, fmt, '@') != null or fmt.len == 0; |
| 279 | 279 | 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 |
| 288 | 288 | .path = path, |
| 289 | 289 | .query = query, |
| 290 | 290 | .fragment = fragment, |
| 291 | }, writer); | |
| 291 | }, bw); | |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | 294 | /// Parses the URI or returns an error. |
lib/std/fmt.zig+1-5| ... | ... | @@ -531,11 +531,7 @@ pub fn Formatter(comptime formatFn: anytype) type { |
| 531 | 531 | const Data = @typeInfo(@TypeOf(formatFn)).@"fn".params[0].type.?; |
| 532 | 532 | return struct { |
| 533 | 533 | 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 { | |
| 539 | 535 | try formatFn(self.data, writer, fmt); |
| 540 | 536 | } |
| 541 | 537 | }; |
lib/std/io/BufferedReader.zig+79-51| ... | ... | @@ -201,8 +201,8 @@ pub fn toss(br: *BufferedReader, n: usize) void { |
| 201 | 201 | |
| 202 | 202 | /// Equivalent to `peek` + `toss`. |
| 203 | 203 | pub 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); | |
| 206 | 206 | return result; |
| 207 | 207 | } |
| 208 | 208 | |
| ... | ... | @@ -218,7 +218,7 @@ pub fn take(br: *BufferedReader, n: usize) anyerror![]u8 { |
| 218 | 218 | /// See also: |
| 219 | 219 | /// * `take` |
| 220 | 220 | pub 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]; | |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | 224 | /// 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 { |
| 232 | 232 | /// * `discardUntilEnd` |
| 233 | 233 | /// * `discardUpTo` |
| 234 | 234 | pub 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; | |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | 238 | /// 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 { |
| 325 | 325 | @panic("TODO"); |
| 326 | 326 | } |
| 327 | 327 | |
| 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` | |
| 345 | pub 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 | ||
| 351 | pub 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 | ||
| 328 | 356 | /// Returns a slice of the next bytes of buffered data from the stream until |
| 329 | 357 | /// `delimiter` is found, advancing the seek position. |
| 330 | 358 | /// |
| ... | ... | @@ -339,36 +367,17 @@ pub fn partialRead(br: *BufferedReader, buffer: []u8) anyerror!usize { |
| 339 | 367 | /// Invalidates previously returned values from `peek`. |
| 340 | 368 | /// |
| 341 | 369 | /// See also: |
| 342 | /// * `takeDelimiterConclusive` | |
| 370 | /// * `takeSentinel` | |
| 371 | /// * `takeDelimiterExclusive` | |
| 343 | 372 | /// * `peekDelimiterInclusive` |
| 344 | 373 | pub 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); | |
| 347 | 376 | return result; |
| 348 | 377 | } |
| 349 | 378 | |
| 350 | 379 | pub 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; | |
| 372 | 381 | } |
| 373 | 382 | |
| 374 | 383 | /// 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 |
| 384 | 393 | /// Invalidates previously returned values from `peek`. |
| 385 | 394 | /// |
| 386 | 395 | /// See also: |
| 396 | /// * `takeSentinel` | |
| 387 | 397 | /// * `takeDelimiterInclusive` |
| 388 | /// * `peekDelimiterConclusive` | |
| 389 | pub fn takeDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 { | |
| 390 | const result = try peekDelimiterConclusive(br, delimiter); | |
| 398 | /// * `peekDelimiterExclusive` | |
| 399 | pub 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 | }; | |
| 391 | 405 | br.toss(result.len); |
| 392 | return result; | |
| 406 | return result[0 .. result.len - 1]; | |
| 407 | } | |
| 408 | ||
| 409 | pub 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]; | |
| 393 | 413 | } |
| 394 | 414 | |
| 395 | pub fn peekDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 { | |
| 415 | fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) anyerror!?[]u8 { | |
| 396 | 416 | const storage = &br.storage; |
| 397 | 417 | const buffer = storage.buffer[0..storage.end]; |
| 398 | 418 | const seek = br.seek; |
| 399 | 419 | if (std.mem.indexOfScalarPos(u8, buffer, seek, delimiter)) |end| { |
| 400 | 420 | @branchHint(.likely); |
| 401 | return buffer[seek..end]; | |
| 421 | return buffer[seek .. end + 1]; | |
| 402 | 422 | } |
| 403 | 423 | const remainder = buffer[seek..]; |
| 404 | 424 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| ... | ... | @@ -407,10 +427,8 @@ pub fn peekDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 |
| 407 | 427 | br.seek = 0; |
| 408 | 428 | while (i < storage.buffer.len) { |
| 409 | 429 | 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; | |
| 414 | 432 | i = storage.end; |
| 415 | 433 | } |
| 416 | 434 | return error.StreamTooLong; |
| ... | ... | @@ -436,7 +454,7 @@ pub fn streamReadDelimiter(br: *BufferedReader, bw: *std.io.BufferedWriter, deli |
| 436 | 454 | /// |
| 437 | 455 | /// Returns number of bytes streamed as well as whether the input reached the end. |
| 438 | 456 | /// The end is not signaled to the writer. |
| 439 | pub fn streamReadDelimiterConclusive( | |
| 457 | pub fn streamReadDelimiterExclusive( | |
| 440 | 458 | br: *BufferedReader, |
| 441 | 459 | bw: *std.io.BufferedWriter, |
| 442 | 460 | delimiter: u8, |
| ... | ... | @@ -468,7 +486,7 @@ pub fn streamReadDelimiterLimited( |
| 468 | 486 | /// including the delimiter. |
| 469 | 487 | /// |
| 470 | 488 | /// If end of stream is found, this function succeeds. |
| 471 | pub fn discardDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror!void { | |
| 489 | pub fn discardDelimiterExclusive(br: *BufferedReader, delimiter: u8) anyerror!void { | |
| 472 | 490 | _ = br; |
| 473 | 491 | _ = delimiter; |
| 474 | 492 | @panic("TODO"); |
| ... | ... | @@ -517,7 +535,7 @@ pub fn takeByte(br: *BufferedReader) anyerror!u8 { |
| 517 | 535 | const seek = br.seek; |
| 518 | 536 | if (seek >= buffer.len) { |
| 519 | 537 | @branchHint(.unlikely); |
| 520 | try fill(br, 1); | |
| 538 | try br.fill(1); | |
| 521 | 539 | } |
| 522 | 540 | br.seek = seek + 1; |
| 523 | 541 | return buffer[seek]; |
| ... | ... | @@ -531,20 +549,20 @@ pub fn takeByteSigned(br: *BufferedReader) anyerror!i8 { |
| 531 | 549 | /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`. |
| 532 | 550 | pub inline fn takeInt(br: *BufferedReader, comptime T: type, endian: std.builtin.Endian) anyerror!T { |
| 533 | 551 | 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); | |
| 535 | 553 | } |
| 536 | 554 | |
| 537 | 555 | /// Asserts the buffer was initialized with a capacity at least `n`. |
| 538 | 556 | pub fn takeVarInt(br: *BufferedReader, comptime Int: type, endian: std.builtin.Endian, n: usize) anyerror!Int { |
| 539 | 557 | 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); | |
| 541 | 559 | } |
| 542 | 560 | |
| 543 | 561 | /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`. |
| 544 | 562 | pub fn takeStruct(br: *BufferedReader, comptime T: type) anyerror!*align(1) T { |
| 545 | 563 | // Only extern and packed structs have defined in-memory layout. |
| 546 | 564 | comptime assert(@typeInfo(T).@"struct".layout != .auto); |
| 547 | return @ptrCast(try takeArray(br, @sizeOf(T))); | |
| 565 | return @ptrCast(try br.takeArray(@sizeOf(T))); | |
| 548 | 566 | } |
| 549 | 567 | |
| 550 | 568 | /// 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 |
| 561 | 579 | /// Asserts the buffer was initialized with a capacity at least `@sizeOf(Enum)`. |
| 562 | 580 | pub fn takeEnum(br: *BufferedReader, comptime Enum: type, endian: std.builtin.Endian) anyerror!Enum { |
| 563 | 581 | const Tag = @typeInfo(Enum).@"enum".tag_type; |
| 564 | const int = try takeInt(br, Tag, endian); | |
| 582 | const int = try br.takeInt(Tag, endian); | |
| 565 | 583 | return std.meta.intToEnum(Enum, int); |
| 566 | 584 | } |
| 567 | 585 | |
| ... | ... | @@ -588,10 +606,12 @@ fn takeMultipleOf7Leb128(br: *BufferedReader, comptime Result: type) anyerror!Re |
| 588 | 606 | const buffer: []const packed struct(u8) { bits: u7, more: bool } = @ptrCast(try br.peekAll(1)); |
| 589 | 607 | for (buffer, 1..) |byte, len| { |
| 590 | 608 | 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; | |
| 592 | 611 | remaining_bits -= 7; |
| 593 | 612 | } 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))), | |
| 595 | 615 | .unsigned => byte.bits == 0, |
| 596 | 616 | }; |
| 597 | 617 | if (byte.more) continue; |
| ... | ... | @@ -652,6 +672,14 @@ test read { |
| 652 | 672 | return error.Unimplemented; |
| 653 | 673 | } |
| 654 | 674 | |
| 675 | test takeSentinel { | |
| 676 | return error.Unimplemented; | |
| 677 | } | |
| 678 | ||
| 679 | test peekSentinel { | |
| 680 | return error.Unimplemented; | |
| 681 | } | |
| 682 | ||
| 655 | 683 | test takeDelimiterInclusive { |
| 656 | 684 | return error.Unimplemented; |
| 657 | 685 | } |
| ... | ... | @@ -660,11 +688,11 @@ test peekDelimiterInclusive { |
| 660 | 688 | return error.Unimplemented; |
| 661 | 689 | } |
| 662 | 690 | |
| 663 | test takeDelimiterConclusive { | |
| 691 | test takeDelimiterExclusive { | |
| 664 | 692 | return error.Unimplemented; |
| 665 | 693 | } |
| 666 | 694 | |
| 667 | test peekDelimiterConclusive { | |
| 695 | test peekDelimiterExclusive { | |
| 668 | 696 | return error.Unimplemented; |
| 669 | 697 | } |
| 670 | 698 | |
| ... | ... | @@ -672,7 +700,7 @@ test streamReadDelimiter { |
| 672 | 700 | return error.Unimplemented; |
| 673 | 701 | } |
| 674 | 702 | |
| 675 | test streamReadDelimiterConclusive { | |
| 703 | test streamReadDelimiterExclusive { | |
| 676 | 704 | return error.Unimplemented; |
| 677 | 705 | } |
| 678 | 706 | |
| ... | ... | @@ -680,7 +708,7 @@ test streamReadDelimiterLimited { |
| 680 | 708 | return error.Unimplemented; |
| 681 | 709 | } |
| 682 | 710 | |
| 683 | test discardDelimiterConclusive { | |
| 711 | test discardDelimiterExclusive { | |
| 684 | 712 | return error.Unimplemented; |
| 685 | 713 | } |
| 686 | 714 |
lib/std/io/BufferedWriter.zig+127-110| ... | ... | @@ -92,7 +92,7 @@ pub fn writableSlice(bw: *BufferedWriter, minimum_length: usize) anyerror![]u8 { |
| 92 | 92 | return cap_slice; |
| 93 | 93 | } |
| 94 | 94 | 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}); | |
| 96 | 96 | if (n == buffer.len) { |
| 97 | 97 | @branchHint(.likely); |
| 98 | 98 | bw.end = 0; |
| ... | ... | @@ -306,7 +306,7 @@ pub fn write(bw: *BufferedWriter, bytes: []const u8) anyerror!usize { |
| 306 | 306 | /// transferred. |
| 307 | 307 | pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) anyerror!void { |
| 308 | 308 | 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..]); | |
| 310 | 310 | } |
| 311 | 311 | |
| 312 | 312 | pub 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 { |
| 354 | 354 | /// many times as necessary. |
| 355 | 355 | pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) anyerror!void { |
| 356 | 356 | var remaining: usize = n; |
| 357 | while (remaining > 0) remaining -= try splatByte(bw, byte, remaining); | |
| 357 | while (remaining > 0) remaining -= try bw.splatByte(byte, remaining); | |
| 358 | 358 | } |
| 359 | 359 | |
| 360 | 360 | /// Writes the same byte many times, allowing short writes. |
| ... | ... | @@ -368,11 +368,11 @@ pub fn splatByte(bw: *BufferedWriter, byte: u8, n: usize) anyerror!usize { |
| 368 | 368 | /// many times as necessary. |
| 369 | 369 | pub fn splatBytesAll(bw: *BufferedWriter, bytes: []const u8, splat: usize) anyerror!void { |
| 370 | 370 | var remaining_bytes: usize = bytes.len * splat; |
| 371 | remaining_bytes -= try splatBytes(bw, bytes, splat); | |
| 371 | remaining_bytes -= try bw.splatBytes(bytes, splat); | |
| 372 | 372 | while (remaining_bytes > 0) { |
| 373 | 373 | const leftover = remaining_bytes % bytes.len; |
| 374 | 374 | 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); | |
| 376 | 376 | } |
| 377 | 377 | } |
| 378 | 378 | |
| ... | ... | @@ -519,7 +519,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp |
| 519 | 519 | const headers_and_trailers = options.headers_and_trailers; |
| 520 | 520 | const headers = headers_and_trailers[0..options.headers_len]; |
| 521 | 521 | switch (options.limit) { |
| 522 | .nothing => return writevAll(bw, headers_and_trailers), | |
| 522 | .nothing => return bw.writevAll(headers_and_trailers), | |
| 523 | 523 | .unlimited => { |
| 524 | 524 | // When reading the whole file, we cannot include the trailers in the |
| 525 | 525 | // 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 |
| 528 | 528 | var i: usize = 0; |
| 529 | 529 | var offset = options.offset; |
| 530 | 530 | 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); | |
| 532 | 532 | while (i < headers.len and n >= headers[i].len) { |
| 533 | 533 | n -= headers[i].len; |
| 534 | 534 | i += 1; |
| ... | ... | @@ -546,7 +546,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp |
| 546 | 546 | var i: usize = 0; |
| 547 | 547 | var offset = options.offset; |
| 548 | 548 | 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); | |
| 550 | 550 | while (i < headers.len and n >= headers[i].len) { |
| 551 | 551 | n -= headers[i].len; |
| 552 | 552 | i += 1; |
| ... | ... | @@ -564,7 +564,7 @@ pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOp |
| 564 | 564 | if (i >= headers_and_trailers.len) return; |
| 565 | 565 | } |
| 566 | 566 | 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..]); | |
| 568 | 568 | } |
| 569 | 569 | offset = offset.advance(n); |
| 570 | 570 | len -= n; |
| ... | ... | @@ -605,7 +605,7 @@ pub fn alignBuffer( |
| 605 | 605 | } |
| 606 | 606 | |
| 607 | 607 | pub 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); | |
| 609 | 609 | } |
| 610 | 610 | |
| 611 | 611 | pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void { |
| ... | ... | @@ -614,15 +614,15 @@ pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void { |
| 614 | 614 | .pointer => |info| { |
| 615 | 615 | try bw.writeAll(@typeName(info.child) ++ "@"); |
| 616 | 616 | if (info.size == .slice) |
| 617 | try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{}) | |
| 617 | try bw.printIntOptions(@intFromPtr(value.ptr), 16, .lower, .{}) | |
| 618 | 618 | else |
| 619 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); | |
| 619 | try bw.printIntOptions(@intFromPtr(value), 16, .lower, .{}); | |
| 620 | 620 | return; |
| 621 | 621 | }, |
| 622 | 622 | .optional => |info| { |
| 623 | 623 | if (@typeInfo(info.child) == .pointer) { |
| 624 | 624 | try bw.writeAll(@typeName(info.child) ++ "@"); |
| 625 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); | |
| 625 | try bw.printIntOptions(@intFromPtr(value), 16, .lower, .{}); | |
| 626 | 626 | return; |
| 627 | 627 | } |
| 628 | 628 | }, |
| ... | ... | @@ -648,7 +648,7 @@ pub fn printValue( |
| 648 | 648 | } else fmt; |
| 649 | 649 | |
| 650 | 650 | if (comptime std.mem.eql(u8, actual_fmt, "*")) { |
| 651 | return printAddress(bw, value); | |
| 651 | return bw.printAddress(value); | |
| 652 | 652 | } |
| 653 | 653 | |
| 654 | 654 | if (std.meta.hasMethod(T, "format")) { |
| ... | ... | @@ -661,24 +661,24 @@ pub fn printValue( |
| 661 | 661 | } |
| 662 | 662 | |
| 663 | 663 | 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), | |
| 666 | 666 | .bool => { |
| 667 | 667 | 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); | |
| 669 | 669 | }, |
| 670 | 670 | .void => { |
| 671 | 671 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 672 | return alignBufferOptions(bw, "void", options); | |
| 672 | return bw.alignBufferOptions("void", options); | |
| 673 | 673 | }, |
| 674 | 674 | .optional => { |
| 675 | 675 | if (actual_fmt.len == 0 or actual_fmt[0] != '?') |
| 676 | 676 | @compileError("cannot print optional without a specifier (i.e. {?} or {any})"); |
| 677 | 677 | const remaining_fmt = comptime stripOptionalOrErrorUnionSpec(actual_fmt); |
| 678 | 678 | if (value) |payload| { |
| 679 | return printValue(bw, remaining_fmt, options, payload, max_depth); | |
| 679 | return bw.printValue(remaining_fmt, options, payload, max_depth); | |
| 680 | 680 | } else { |
| 681 | return alignBufferOptions(bw, "null", options); | |
| 681 | return bw.alignBufferOptions("null", options); | |
| 682 | 682 | } |
| 683 | 683 | }, |
| 684 | 684 | .error_union => { |
| ... | ... | @@ -686,9 +686,9 @@ pub fn printValue( |
| 686 | 686 | @compileError("cannot format error union without a specifier (i.e. {!} or {any})"); |
| 687 | 687 | const remaining_fmt = comptime stripOptionalOrErrorUnionSpec(actual_fmt); |
| 688 | 688 | if (value) |payload| { |
| 689 | return printValue(bw, remaining_fmt, options, payload, max_depth); | |
| 689 | return bw.printValue(remaining_fmt, options, payload, max_depth); | |
| 690 | 690 | } else |err| { |
| 691 | return printValue(bw, "", options, err, max_depth); | |
| 691 | return bw.printValue("", options, err, max_depth); | |
| 692 | 692 | } |
| 693 | 693 | }, |
| 694 | 694 | .error_set => { |
| ... | ... | @@ -721,14 +721,14 @@ pub fn printValue( |
| 721 | 721 | } |
| 722 | 722 | |
| 723 | 723 | 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); | |
| 725 | 725 | try bw.writeByte(')'); |
| 726 | 726 | }, |
| 727 | 727 | .@"union" => |info| { |
| 728 | 728 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 729 | 729 | try bw.writeAll(@typeName(T)); |
| 730 | 730 | if (max_depth == 0) { |
| 731 | bw.writeAll("{ ... }"); | |
| 731 | try bw.writeAll("{ ... }"); | |
| 732 | 732 | return; |
| 733 | 733 | } |
| 734 | 734 | if (info.tag_type) |UnionTagType| { |
| ... | ... | @@ -737,13 +737,13 @@ pub fn printValue( |
| 737 | 737 | try bw.writeAll(" = "); |
| 738 | 738 | inline for (info.fields) |u_field| { |
| 739 | 739 | 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); | |
| 741 | 741 | } |
| 742 | 742 | } |
| 743 | 743 | try bw.writeAll(" }"); |
| 744 | 744 | } else { |
| 745 | 745 | try bw.writeByte('@'); |
| 746 | try bw.printIntOptions(@intFromPtr(&value), 16, .lower); | |
| 746 | try bw.printIntOptions(@intFromPtr(&value), 16, .lower, options); | |
| 747 | 747 | } |
| 748 | 748 | }, |
| 749 | 749 | .@"struct" => |info| { |
| ... | ... | @@ -761,7 +761,7 @@ pub fn printValue( |
| 761 | 761 | } else { |
| 762 | 762 | try bw.writeAll(", "); |
| 763 | 763 | } |
| 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); | |
| 765 | 765 | } |
| 766 | 766 | try bw.writeAll(" }"); |
| 767 | 767 | return; |
| ... | ... | @@ -780,19 +780,19 @@ pub fn printValue( |
| 780 | 780 | } |
| 781 | 781 | try bw.writeAll(f.name); |
| 782 | 782 | 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); | |
| 784 | 784 | } |
| 785 | 785 | try bw.writeAll(" }"); |
| 786 | 786 | }, |
| 787 | 787 | .pointer => |ptr_info| switch (ptr_info.size) { |
| 788 | 788 | .one => switch (@typeInfo(ptr_info.child)) { |
| 789 | 789 | .array, .@"enum", .@"union", .@"struct" => { |
| 790 | return printValue(bw, actual_fmt, options, value.*, max_depth); | |
| 790 | return bw.printValue(actual_fmt, options, value.*, max_depth); | |
| 791 | 791 | }, |
| 792 | 792 | else => { |
| 793 | 793 | 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); | |
| 796 | 796 | return; |
| 797 | 797 | }, |
| 798 | 798 | }, |
| ... | ... | @@ -800,10 +800,10 @@ pub fn printValue( |
| 800 | 800 | if (actual_fmt.len == 0) |
| 801 | 801 | @compileError("cannot format pointer without a specifier (i.e. {s} or {*})"); |
| 802 | 802 | 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); | |
| 804 | 804 | } |
| 805 | 805 | 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); | |
| 807 | 807 | } |
| 808 | 808 | invalidFmtError(fmt, value); |
| 809 | 809 | }, |
| ... | ... | @@ -815,19 +815,19 @@ pub fn printValue( |
| 815 | 815 | } |
| 816 | 816 | if (ptr_info.child == u8) switch (actual_fmt.len) { |
| 817 | 817 | 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), | |
| 821 | 821 | else => {}, |
| 822 | 822 | }, |
| 823 | 823 | 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); | |
| 825 | 825 | }, |
| 826 | 826 | else => {}, |
| 827 | 827 | }; |
| 828 | 828 | try bw.writeAll("{ "); |
| 829 | 829 | 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); | |
| 831 | 831 | if (i != value.len - 1) { |
| 832 | 832 | try bw.writeAll(", "); |
| 833 | 833 | } |
| ... | ... | @@ -843,16 +843,16 @@ pub fn printValue( |
| 843 | 843 | } |
| 844 | 844 | if (info.child == u8) { |
| 845 | 845 | if (actual_fmt[0] == 's') { |
| 846 | return alignBufferOptions(bw, &value, options); | |
| 846 | return bw.alignBufferOptions(&value, options); | |
| 847 | 847 | } else if (actual_fmt[0] == 'x') { |
| 848 | return printHex(bw, &value, .lower); | |
| 848 | return bw.printHex(&value, .lower); | |
| 849 | 849 | } else if (actual_fmt[0] == 'X') { |
| 850 | return printHex(bw, &value, .upper); | |
| 850 | return bw.printHex(&value, .upper); | |
| 851 | 851 | } |
| 852 | 852 | } |
| 853 | 853 | try bw.writeAll("{ "); |
| 854 | 854 | 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); | |
| 856 | 856 | if (i < value.len - 1) { |
| 857 | 857 | try bw.writeAll(", "); |
| 858 | 858 | } |
| ... | ... | @@ -866,7 +866,7 @@ pub fn printValue( |
| 866 | 866 | try bw.writeAll("{ "); |
| 867 | 867 | var i: usize = 0; |
| 868 | 868 | 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); | |
| 870 | 870 | if (i < info.len - 1) { |
| 871 | 871 | try bw.writeAll(", "); |
| 872 | 872 | } |
| ... | ... | @@ -876,16 +876,16 @@ pub fn printValue( |
| 876 | 876 | .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), |
| 877 | 877 | .type => { |
| 878 | 878 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 879 | return alignBufferOptions(bw, @typeName(value), options); | |
| 879 | return bw.alignBufferOptions(@typeName(value), options); | |
| 880 | 880 | }, |
| 881 | 881 | .enum_literal => { |
| 882 | 882 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 883 | 883 | const buffer = [_]u8{'.'} ++ @tagName(value); |
| 884 | return alignBufferOptions(bw, buffer, options); | |
| 884 | return bw.alignBufferOptions(buffer, options); | |
| 885 | 885 | }, |
| 886 | 886 | .null => { |
| 887 | 887 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 888 | return alignBufferOptions(bw, "null", options); | |
| 888 | return bw.alignBufferOptions("null", options); | |
| 889 | 889 | }, |
| 890 | 890 | else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"), |
| 891 | 891 | } |
| ... | ... | @@ -903,34 +903,34 @@ pub fn printInt( |
| 903 | 903 | } else value; |
| 904 | 904 | |
| 905 | 905 | switch (fmt.len) { |
| 906 | 0 => return printIntOptions(bw, int_value, 10, .lower, options), | |
| 906 | 0 => return bw.printIntOptions(int_value, 10, .lower, options), | |
| 907 | 907 | 1 => switch (fmt[0]) { |
| 908 | 'd' => return printIntOptions(bw, int_value, 10, .lower, options), | |
| 908 | 'd' => return bw.printIntOptions(int_value, 10, .lower, options), | |
| 909 | 909 | 'c' => { |
| 910 | 910 | 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); | |
| 912 | 912 | } else { |
| 913 | 913 | @compileError("cannot print integer that is larger than 8 bits as an ASCII character"); |
| 914 | 914 | } |
| 915 | 915 | }, |
| 916 | 916 | 'u' => { |
| 917 | 917 | 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); | |
| 919 | 919 | } else { |
| 920 | 920 | @compileError("cannot print integer that is larger than 21 bits as an UTF-8 sequence"); |
| 921 | 921 | } |
| 922 | 922 | }, |
| 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), | |
| 929 | 929 | else => invalidFmtError(fmt, value), |
| 930 | 930 | }, |
| 931 | 931 | 2 => { |
| 932 | 932 | if (fmt[0] == 'B' and fmt[1] == 'i') { |
| 933 | return printByteSize(bw, int_value, .binary, options); | |
| 933 | return bw.printByteSize(int_value, .binary, options); | |
| 934 | 934 | } else { |
| 935 | 935 | invalidFmtError(fmt, value); |
| 936 | 936 | } |
| ... | ... | @@ -941,17 +941,17 @@ pub fn printInt( |
| 941 | 941 | } |
| 942 | 942 | |
| 943 | 943 | pub 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); | |
| 945 | 945 | } |
| 946 | 946 | |
| 947 | 947 | pub 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); | |
| 949 | 949 | } |
| 950 | 950 | |
| 951 | 951 | pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) anyerror!void { |
| 952 | 952 | var buf: [4]u8 = undefined; |
| 953 | 953 | const len = try std.unicode.utf8Encode(c, &buf); |
| 954 | return alignBufferOptions(bw, buf[0..len], options); | |
| 954 | return bw.alignBufferOptions(buf[0..len], options); | |
| 955 | 955 | } |
| 956 | 956 | |
| 957 | 957 | pub fn printIntOptions( |
| ... | ... | @@ -1019,7 +1019,7 @@ pub fn printIntOptions( |
| 1019 | 1019 | } |
| 1020 | 1020 | } |
| 1021 | 1021 | |
| 1022 | return alignBufferOptions(bw, buf[index..], options); | |
| 1022 | return bw.alignBufferOptions(buf[index..], options); | |
| 1023 | 1023 | } |
| 1024 | 1024 | |
| 1025 | 1025 | pub fn printFloat( |
| ... | ... | @@ -1036,19 +1036,19 @@ pub fn printFloat( |
| 1036 | 1036 | const s = std.fmt.float.render(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) { |
| 1037 | 1037 | error.BufferTooSmall => "(float)", |
| 1038 | 1038 | }; |
| 1039 | return alignBufferOptions(bw, s, options); | |
| 1039 | return bw.alignBufferOptions(s, options); | |
| 1040 | 1040 | }, |
| 1041 | 1041 | 'd' => { |
| 1042 | 1042 | const s = std.fmt.float.render(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) { |
| 1043 | 1043 | error.BufferTooSmall => "(float)", |
| 1044 | 1044 | }; |
| 1045 | return alignBufferOptions(bw, s, options); | |
| 1045 | return bw.alignBufferOptions(s, options); | |
| 1046 | 1046 | }, |
| 1047 | 1047 | 'x' => { |
| 1048 | 1048 | var sub_bw: BufferedWriter = undefined; |
| 1049 | 1049 | sub_bw.initFixed(&buf); |
| 1050 | 1050 | sub_bw.printFloatHexadecimal(value, options.precision) catch unreachable; |
| 1051 | return alignBufferOptions(bw, sub_bw.getWritten(), options); | |
| 1051 | return bw.alignBufferOptions(sub_bw.getWritten(), options); | |
| 1052 | 1052 | }, |
| 1053 | 1053 | else => invalidFmtError(fmt, value), |
| 1054 | 1054 | } |
| ... | ... | @@ -1150,7 +1150,7 @@ pub fn printFloatHexadecimal(bw: *BufferedWriter, value: anytype, opt_precision: |
| 1150 | 1150 | try bw.splatByteAll('0', precision - trimmed.len); |
| 1151 | 1151 | }; |
| 1152 | 1152 | try bw.writeAll("p"); |
| 1153 | try printIntOptions(bw, exponent - exponent_bias, 10, .lower, .{}); | |
| 1153 | try bw.printIntOptions(exponent - exponent_bias, 10, .lower, .{}); | |
| 1154 | 1154 | } |
| 1155 | 1155 | |
| 1156 | 1156 | pub const ByteSizeUnits = enum { |
| ... | ... | @@ -1169,7 +1169,7 @@ pub fn printByteSize( |
| 1169 | 1169 | comptime units: ByteSizeUnits, |
| 1170 | 1170 | options: std.fmt.Options, |
| 1171 | 1171 | ) anyerror!void { |
| 1172 | if (value == 0) return alignBufferOptions(bw, "0B", options); | |
| 1172 | if (value == 0) return bw.alignBufferOptions("0B", options); | |
| 1173 | 1173 | // The worst case in terms of space needed is 32 bytes + 3 for the suffix. |
| 1174 | 1174 | var buf: [std.fmt.float.min_buffer_size + 3]u8 = undefined; |
| 1175 | 1175 | |
| ... | ... | @@ -1213,7 +1213,7 @@ pub fn printByteSize( |
| 1213 | 1213 | }, |
| 1214 | 1214 | } |
| 1215 | 1215 | |
| 1216 | return alignBufferOptions(bw, buf[0..i], options); | |
| 1216 | return bw.alignBufferOptions(buf[0..i], options); | |
| 1217 | 1217 | } |
| 1218 | 1218 | |
| 1219 | 1219 | // 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 { |
| 1250 | 1250 | |
| 1251 | 1251 | pub fn printDurationSigned(bw: *BufferedWriter, ns: i64) anyerror!void { |
| 1252 | 1252 | if (ns < 0) try bw.writeByte('-'); |
| 1253 | return printDurationUnsigned(bw, @abs(ns)); | |
| 1253 | return bw.printDurationUnsigned(@abs(ns)); | |
| 1254 | 1254 | } |
| 1255 | 1255 | |
| 1256 | 1256 | pub fn printDurationUnsigned(bw: *BufferedWriter, ns: u64) anyerror!void { |
| ... | ... | @@ -1296,7 +1296,7 @@ pub fn printDurationUnsigned(bw: *BufferedWriter, ns: u64) anyerror!void { |
| 1296 | 1296 | } |
| 1297 | 1297 | } |
| 1298 | 1298 | |
| 1299 | try printIntOptions(bw, ns_remaining, 10, .lower, .{}); | |
| 1299 | try bw.printIntOptions(ns_remaining, 10, .lower, .{}); | |
| 1300 | 1300 | try bw.writeAll("ns"); |
| 1301 | 1301 | } |
| 1302 | 1302 | |
| ... | ... | @@ -1312,7 +1312,7 @@ pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt |
| 1312 | 1312 | .signed => sub_bw.printDurationSigned(nanoseconds) catch unreachable, |
| 1313 | 1313 | .unsigned => sub_bw.printDurationUnsigned(nanoseconds) catch unreachable, |
| 1314 | 1314 | } |
| 1315 | return alignBufferOptions(bw, sub_bw.getWritten(), options); | |
| 1315 | return bw.alignBufferOptions(sub_bw.getWritten(), options); | |
| 1316 | 1316 | } |
| 1317 | 1317 | |
| 1318 | 1318 | pub 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 |
| 1321 | 1321 | .lower => "0123456789abcdef", |
| 1322 | 1322 | }; |
| 1323 | 1323 | 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]); | |
| 1326 | 1326 | } |
| 1327 | 1327 | } |
| 1328 | 1328 | |
| ... | ... | @@ -1334,50 +1334,67 @@ pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) anyerror!void { |
| 1334 | 1334 | } |
| 1335 | 1335 | } |
| 1336 | 1336 | |
| 1337 | /// Write a single unsigned integer as unsigned LEB128 to the given writer. | |
| 1338 | pub 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. | |
| 1338 | pub 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 | } | |
| 1346 | 1348 | |
| 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. | |
| 1350 | pub 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 | }); | |
| 1357 | 1359 | } |
| 1358 | 1360 | |
| 1359 | /// Write a single signed integer as signed LEB128 to the given writer. | |
| 1360 | pub 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. | |
| 1362 | pub 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 | } | |
| 1369 | 1369 | |
| 1370 | fn 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; | |
| 1370 | 1374 | 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); | |
| 1380 | 1396 | } |
| 1397 | bw.advance(buffer.len); | |
| 1381 | 1398 | } |
| 1382 | 1399 | } |
| 1383 | 1400 |
lib/std/leb128.zig+2-2| ... | ... | @@ -55,10 +55,10 @@ test writeUnsignedFixed { |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | 57 | /// 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 | |
| 59 | 59 | /// fewer bytes to store smaller numbers. The advantage of using a fixed width is that it makes |
| 60 | 60 | /// 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 | |
| 62 | 62 | /// "relocatable", meaning that it becomes possible to later go back and patch the number to be a |
| 63 | 63 | /// different value without shifting all the following code. |
| 64 | 64 | pub 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 { |
| 2322 | 2322 | /// this function will fail to print the string, printing "(BigInt)" instead of a number. |
| 2323 | 2323 | /// This is because the rendering algorithm requires reversing a string, which requires O(N) memory. |
| 2324 | 2324 | /// 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 { | |
| 2332 | 2326 | comptime var base = 10; |
| 2333 | 2327 | comptime var case: std.fmt.Case = .lower; |
| 2334 | 2328 | |
| ... | ... | @@ -2348,19 +2342,21 @@ pub const Const = struct { |
| 2348 | 2342 | std.fmt.invalidFmtError(fmt, self); |
| 2349 | 2343 | } |
| 2350 | 2344 | |
| 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)"); | |
| 2364 | 2360 | } |
| 2365 | 2361 | |
| 2366 | 2362 | /// Converts self to a string in the requested base. |
lib/std/net.zig+2-2| ... | ... | @@ -1358,7 +1358,7 @@ fn linuxLookupNameFromHosts( |
| 1358 | 1358 | |
| 1359 | 1359 | var line_buf: [512]u8 = undefined; |
| 1360 | 1360 | var br = file.reader().buffered(&line_buf); |
| 1361 | while (br.takeDelimiterConclusive('\n')) |line| { | |
| 1361 | while (br.takeSentinel('\n')) |line| { | |
| 1362 | 1362 | var split_it = mem.splitScalar(u8, line, '#'); |
| 1363 | 1363 | const no_comment_line = split_it.first(); |
| 1364 | 1364 | |
| ... | ... | @@ -1550,7 +1550,7 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void { |
| 1550 | 1550 | |
| 1551 | 1551 | var line_buf: [512]u8 = undefined; |
| 1552 | 1552 | var br = file.reader().buffered(&line_buf); |
| 1553 | while (br.takeDelimiterConclusive('\n')) |line_with_comment| { | |
| 1553 | while (br.takeSentinel('\n')) |line_with_comment| { | |
| 1554 | 1554 | const line = line: { |
| 1555 | 1555 | var split = mem.splitScalar(u8, line_with_comment, '#'); |
| 1556 | 1556 | 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 |
| 544 | 544 | var buffer: std.ArrayListAlignedUnmanaged(u8, .@"2") = .empty; |
| 545 | 545 | defer buffer.deinit(gpa); |
| 546 | 546 | |
| 547 | try buffer.ensureUnusedCapacity(size_hint); | |
| 547 | try buffer.ensureUnusedCapacity(gpa, size_hint); | |
| 548 | 548 | |
| 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) { | |
| 550 | 550 | error.ConnectionResetByPeer => unreachable, |
| 551 | 551 | error.ConnectionTimedOut => unreachable, |
| 552 | 552 | error.NotOpenForReading => unreachable, |
| ... | ... | @@ -568,7 +568,7 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: u |
| 568 | 568 | // If the file starts with a UTF-16 little endian BOM, translate it to UTF-8 |
| 569 | 569 | if (std.mem.startsWith(u8, buffer.items, "\xff\xfe")) { |
| 570 | 570 | 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) { | |
| 572 | 572 | error.DanglingSurrogateHalf => error.UnsupportedEncoding, |
| 573 | 573 | error.ExpectedSecondSurrogateHalf => error.UnsupportedEncoding, |
| 574 | 574 | error.UnexpectedSecondSurrogateHalf => error.UnsupportedEncoding, |
| ... | ... | @@ -576,7 +576,7 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: u |
| 576 | 576 | }; |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | return buffer.toOwnedSliceSentinel(0); | |
| 579 | return buffer.toOwnedSliceSentinel(gpa, 0); | |
| 580 | 580 | } |
| 581 | 581 | |
| 582 | 582 | pub 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 |
| 562 | 562 | |
| 563 | 563 | .invalid_byte => { |
| 564 | 564 | 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'}'", .{ | |
| 566 | 566 | switch (tok_slice[0]) { |
| 567 | 567 | '\'' => "character literal", |
| 568 | 568 | '"', '\\' => "string literal", |
lib/std/zig/AstGen.zig+7-6| ... | ... | @@ -11465,7 +11465,7 @@ fn failWithStrLitError( |
| 11465 | 11465 | astgen, |
| 11466 | 11466 | token, |
| 11467 | 11467 | @intCast(offset + err.offset()), |
| 11468 | "{}", | |
| 11468 | "{f}", | |
| 11469 | 11469 | .{err.fmt(raw_string)}, |
| 11470 | 11470 | ); |
| 11471 | 11471 | } |
| ... | ... | @@ -13898,8 +13898,9 @@ fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void { |
| 13898 | 13898 | assert(tree.errors.len > 0); |
| 13899 | 13899 | |
| 13900 | 13900 | var msg: std.io.AllocatingWriter = undefined; |
| 13901 | const msg_writer = msg.init(gpa); | |
| 13901 | msg.init(gpa); | |
| 13902 | 13902 | defer msg.deinit(); |
| 13903 | const msg_bw = &msg.buffered_writer; | |
| 13903 | 13904 | |
| 13904 | 13905 | var notes: std.ArrayListUnmanaged(u32) = .empty; |
| 13905 | 13906 | defer notes.deinit(gpa); |
| ... | ... | @@ -13933,19 +13934,19 @@ fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void { |
| 13933 | 13934 | .extra = .{ .offset = bad_off }, |
| 13934 | 13935 | }; |
| 13935 | 13936 | 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(...) | |
| 13937 | 13938 | return try astgen.appendErrorTokNotesOff(tok, bad_off, "{s}", .{msg.getWritten()}, notes.items); |
| 13938 | 13939 | } |
| 13939 | 13940 | |
| 13940 | 13941 | var cur_err = tree.errors[0]; |
| 13941 | 13942 | for (tree.errors[1..]) |err| { |
| 13942 | 13943 | 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(...) | |
| 13944 | 13945 | try notes.append(gpa, try astgen.errNoteTok(err.token, "{s}", .{msg.getWritten()})); |
| 13945 | 13946 | } else { |
| 13946 | 13947 | // Flush error |
| 13947 | 13948 | 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(...) | |
| 13949 | 13950 | try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items); |
| 13950 | 13951 | notes.clearRetainingCapacity(); |
| 13951 | 13952 | cur_err = err; |
| ... | ... | @@ -13959,7 +13960,7 @@ fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void { |
| 13959 | 13960 | |
| 13960 | 13961 | // Flush error |
| 13961 | 13962 | 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(...) | |
| 13963 | 13964 | try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.getWritten()}, notes.items); |
| 13964 | 13965 | } |
| 13965 | 13966 |
lib/std/zig/LibCInstallation.zig+1-1| ... | ... | @@ -43,7 +43,7 @@ pub fn parse( |
| 43 | 43 | } |
| 44 | 44 | } |
| 45 | 45 | |
| 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); | |
| 47 | 47 | defer allocator.free(contents); |
| 48 | 48 | |
| 49 | 49 | var it = std.mem.tokenizeScalar(u8, contents, '\n'); |
lib/std/zig/ZonGen.zig+3-2| ... | ... | @@ -778,7 +778,7 @@ fn lowerStrLitError( |
| 778 | 778 | zg, |
| 779 | 779 | token, |
| 780 | 780 | @intCast(offset + err.offset()), |
| 781 | "{}", | |
| 781 | "{f}", | |
| 782 | 782 | .{err.fmt(raw_string)}, |
| 783 | 783 | ); |
| 784 | 784 | } |
| ... | ... | @@ -885,8 +885,9 @@ fn lowerAstErrors(zg: *ZonGen) Allocator.Error!void { |
| 885 | 885 | assert(tree.errors.len > 0); |
| 886 | 886 | |
| 887 | 887 | var msg: std.io.AllocatingWriter = undefined; |
| 888 | const msg_bw = msg.init(gpa); | |
| 888 | msg.init(gpa); | |
| 889 | 889 | defer msg.deinit(); |
| 890 | const msg_bw = &msg.buffered_writer; | |
| 890 | 891 | |
| 891 | 892 | var notes: std.ArrayListUnmanaged(Zoir.CompileError.Note) = .empty; |
| 892 | 893 | defer notes.deinit(gpa); |
lib/std/zig/llvm/BitcodeReader.zig+12-12| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | allocator: std.mem.Allocator, |
| 2 | 2 | record_arena: std.heap.ArenaAllocator.State, |
| 3 | reader: std.io.AnyReader, | |
| 3 | br: *std.io.BufferedReader, | |
| 4 | 4 | keep_names: bool, |
| 5 | 5 | bit_buffer: u32, |
| 6 | 6 | bit_offset: u5, |
| ... | ... | @@ -93,14 +93,14 @@ pub const Record = struct { |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | 95 | pub const InitOptions = struct { |
| 96 | reader: std.io.AnyReader, | |
| 96 | br: *std.io.BufferedReader, | |
| 97 | 97 | keep_names: bool = false, |
| 98 | 98 | }; |
| 99 | 99 | pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader { |
| 100 | 100 | return .{ |
| 101 | 101 | .allocator = allocator, |
| 102 | 102 | .record_arena = .{}, |
| 103 | .reader = options.reader, | |
| 103 | .br = options.br, | |
| 104 | 104 | .keep_names = options.keep_names, |
| 105 | 105 | .bit_buffer = 0, |
| 106 | 106 | .bit_offset = 0, |
| ... | ... | @@ -170,9 +170,9 @@ pub fn next(bc: *BitcodeReader) !?Item { |
| 170 | 170 | } |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | pub fn skipBlock(bc: *BitcodeReader, block: Block) !void { | |
| 173 | pub fn skipBlock(bc: *BitcodeReader, block: Block) anyerror!void { | |
| 174 | 174 | 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)); | |
| 176 | 176 | try bc.endBlock(); |
| 177 | 177 | } |
| 178 | 178 | |
| ... | ... | @@ -369,21 +369,21 @@ fn align32Bits(bc: *BitcodeReader) void { |
| 369 | 369 | bc.bit_offset = 0; |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | fn read32Bits(bc: *BitcodeReader) !u32 { | |
| 372 | fn read32Bits(bc: *BitcodeReader) anyerror!u32 { | |
| 373 | 373 | assert(bc.bit_offset == 0); |
| 374 | return bc.reader.readInt(u32, .little); | |
| 374 | return bc.br.takeInt(u32, .little); | |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | fn readBytes(bc: *BitcodeReader, bytes: []u8) !void { | |
| 377 | fn readBytes(bc: *BitcodeReader, bytes: []u8) anyerror!void { | |
| 378 | 378 | assert(bc.bit_offset == 0); |
| 379 | try bc.reader.readNoEof(bytes); | |
| 379 | try bc.br.read(bytes); | |
| 380 | 380 | |
| 381 | 381 | const trailing_bytes = bytes.len % 4; |
| 382 | 382 | 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..]); | |
| 385 | 385 | 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); | |
| 387 | 387 | } |
| 388 | 388 | } |
| 389 | 389 |
lib/std/zig/llvm/Builder.zig+343-508| ... | ... | @@ -91,26 +91,21 @@ pub const String = enum(u32) { |
| 91 | 91 | string: String, |
| 92 | 92 | builder: *const Builder, |
| 93 | 93 | }; |
| 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 { | |
| 100 | 95 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_| |
| 101 | 96 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 102 | 97 | assert(data.string != .none); |
| 103 | 98 | 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)}); | |
| 105 | 100 | if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_| |
| 106 | return writer.writeAll(string_slice); | |
| 101 | return bw.writeAll(string_slice); | |
| 107 | 102 | try printEscapedString( |
| 108 | 103 | string_slice, |
| 109 | 104 | if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_| |
| 110 | 105 | .always_quote |
| 111 | 106 | else |
| 112 | 107 | .quote_unless_valid_identifier, |
| 113 | writer, | |
| 108 | bw, | |
| 114 | 109 | ); |
| 115 | 110 | } |
| 116 | 111 | pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(format) { |
| ... | ... | @@ -228,7 +223,7 @@ pub const Type = enum(u32) { |
| 228 | 223 | _, |
| 229 | 224 | |
| 230 | 225 | 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})); | |
| 232 | 227 | |
| 233 | 228 | pub const Tag = enum(u4) { |
| 234 | 229 | simple, |
| ... | ... | @@ -654,17 +649,12 @@ pub const Type = enum(u32) { |
| 654 | 649 | type: Type, |
| 655 | 650 | builder: *const Builder, |
| 656 | 651 | }; |
| 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 { | |
| 663 | 653 | assert(data.type != .none); |
| 664 | 654 | if (comptime std.mem.eql(u8, fmt_str, "m")) { |
| 665 | 655 | const item = data.builder.type_items.items[@intFromEnum(data.type)]; |
| 666 | 656 | 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))) { | |
| 668 | 658 | .void => "isVoid", |
| 669 | 659 | .half => "f16", |
| 670 | 660 | .bfloat => "bf16", |
| ... | ... | @@ -681,29 +671,29 @@ pub const Type = enum(u32) { |
| 681 | 671 | .function, .vararg_function => |kind| { |
| 682 | 672 | var extra = data.builder.typeExtraDataTrail(Type.Function, item.data); |
| 683 | 673 | 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)}); | |
| 686 | 676 | switch (kind) { |
| 687 | 677 | .function => {}, |
| 688 | .vararg_function => try writer.writeAll("vararg"), | |
| 678 | .vararg_function => try bw.writeAll("vararg"), | |
| 689 | 679 | else => unreachable, |
| 690 | 680 | } |
| 691 | try writer.writeByte('f'); | |
| 681 | try bw.writeByte('f'); | |
| 692 | 682 | }, |
| 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}), | |
| 695 | 685 | .target => { |
| 696 | 686 | var extra = data.builder.typeExtraDataTrail(Type.Target, item.data); |
| 697 | 687 | const types = extra.trail.next(extra.data.types_len, Type, data.builder); |
| 698 | 688 | 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'); | |
| 703 | 693 | }, |
| 704 | 694 | .vector, .scalable_vector => |kind| { |
| 705 | 695 | 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}", .{ | |
| 707 | 697 | switch (kind) { |
| 708 | 698 | .vector => "", |
| 709 | 699 | .scalable_vector => "nx", |
| ... | ... | @@ -719,24 +709,24 @@ pub const Type = enum(u32) { |
| 719 | 709 | .array => Type.Array, |
| 720 | 710 | else => unreachable, |
| 721 | 711 | }, 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) }); | |
| 723 | 713 | }, |
| 724 | 714 | .structure, .packed_structure => { |
| 725 | 715 | var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data); |
| 726 | 716 | 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'); | |
| 730 | 720 | }, |
| 731 | 721 | .named_structure => { |
| 732 | 722 | 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); | |
| 735 | 725 | }, |
| 736 | 726 | } |
| 737 | 727 | return; |
| 738 | 728 | } |
| 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); | |
| 740 | 730 | const item = data.builder.type_items.items[@intFromEnum(data.type)]; |
| 741 | 731 | switch (item.tag) { |
| 742 | 732 | .simple => unreachable, |
| ... | ... | @@ -744,40 +734,40 @@ pub const Type = enum(u32) { |
| 744 | 734 | var extra = data.builder.typeExtraDataTrail(Type.Function, item.data); |
| 745 | 735 | const params = extra.trail.next(extra.data.params_len, Type, data.builder); |
| 746 | 736 | 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)}); | |
| 748 | 738 | if (!comptime std.mem.eql(u8, fmt_str, "<")) { |
| 749 | try writer.writeByte('('); | |
| 739 | try bw.writeByte('('); | |
| 750 | 740 | 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)}); | |
| 753 | 743 | } |
| 754 | 744 | switch (kind) { |
| 755 | 745 | .function => {}, |
| 756 | 746 | .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("..."); | |
| 759 | 749 | }, |
| 760 | 750 | else => unreachable, |
| 761 | 751 | } |
| 762 | try writer.writeByte(')'); | |
| 752 | try bw.writeByte(')'); | |
| 763 | 753 | } |
| 764 | 754 | }, |
| 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))}), | |
| 767 | 757 | .target => { |
| 768 | 758 | var extra = data.builder.typeExtraDataTrail(Type.Target, item.data); |
| 769 | 759 | const types = extra.trail.next(extra.data.types_len, Type, data.builder); |
| 770 | 760 | 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"} | |
| 773 | 763 | , .{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(')'); | |
| 777 | 767 | }, |
| 778 | 768 | .vector, .scalable_vector => |kind| { |
| 779 | 769 | const extra = data.builder.typeExtraData(Type.Vector, item.data); |
| 780 | try writer.print("<{s}{d} x {%}>", .{ | |
| 770 | try bw.print("<{s}{d} x {f%}>", .{ | |
| 781 | 771 | switch (kind) { |
| 782 | 772 | .vector => "", |
| 783 | 773 | .scalable_vector => "vscale x ", |
| ... | ... | @@ -793,38 +783,38 @@ pub const Type = enum(u32) { |
| 793 | 783 | .array => Type.Array, |
| 794 | 784 | else => unreachable, |
| 795 | 785 | }, 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) }); | |
| 797 | 787 | }, |
| 798 | 788 | .structure, .packed_structure => |kind| { |
| 799 | 789 | var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data); |
| 800 | 790 | const fields = extra.trail.next(extra.data.fields_len, Type, data.builder); |
| 801 | 791 | switch (kind) { |
| 802 | 792 | .structure => {}, |
| 803 | .packed_structure => try writer.writeByte('<'), | |
| 793 | .packed_structure => try bw.writeByte('<'), | |
| 804 | 794 | else => unreachable, |
| 805 | 795 | } |
| 806 | try writer.writeAll("{ "); | |
| 796 | try bw.writeAll("{ "); | |
| 807 | 797 | 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)}); | |
| 810 | 800 | } |
| 811 | try writer.writeAll(" }"); | |
| 801 | try bw.writeAll(" }"); | |
| 812 | 802 | switch (kind) { |
| 813 | 803 | .structure => {}, |
| 814 | .packed_structure => try writer.writeByte('>'), | |
| 804 | .packed_structure => try bw.writeByte('>'), | |
| 815 | 805 | else => unreachable, |
| 816 | 806 | } |
| 817 | 807 | }, |
| 818 | 808 | .named_structure => { |
| 819 | 809 | 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}", .{ | |
| 821 | 811 | extra.id.fmt(data.builder), |
| 822 | 812 | }) else switch (extra.body) { |
| 823 | .none => try writer.writeAll("opaque"), | |
| 813 | .none => try bw.writeAll("opaque"), | |
| 824 | 814 | else => try format(.{ |
| 825 | 815 | .type = extra.body, |
| 826 | 816 | .builder = data.builder, |
| 827 | }, fmt_str, fmt_opts, writer), | |
| 817 | }, bw, fmt_str), | |
| 828 | 818 | } |
| 829 | 819 | }, |
| 830 | 820 | } |
| ... | ... | @@ -1139,12 +1129,7 @@ pub const Attribute = union(Kind) { |
| 1139 | 1129 | attribute_index: Index, |
| 1140 | 1130 | builder: *const Builder, |
| 1141 | 1131 | }; |
| 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 { | |
| 1148 | 1133 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"#")) |_| |
| 1149 | 1134 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 1150 | 1135 | const attribute = data.attribute_index.toAttribute(data.builder); |
| ... | ... | @@ -1219,37 +1204,37 @@ pub const Attribute = union(Kind) { |
| 1219 | 1204 | .no_sanitize_address, |
| 1220 | 1205 | .no_sanitize_hwaddress, |
| 1221 | 1206 | .sanitize_address_dyninit, |
| 1222 | => try writer.print(" {s}", .{@tagName(attribute)}), | |
| 1207 | => try bw.print(" {s}", .{@tagName(attribute)}), | |
| 1223 | 1208 | .byval, |
| 1224 | 1209 | .byref, |
| 1225 | 1210 | .preallocated, |
| 1226 | 1211 | .inalloca, |
| 1227 | 1212 | .sret, |
| 1228 | 1213 | .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}), | |
| 1231 | 1216 | .dereferenceable, |
| 1232 | 1217 | .dereferenceable_or_null, |
| 1233 | => |size| try writer.print(" {s}({d})", .{ @tagName(attribute), size }), | |
| 1218 | => |size| try bw.print(" {s}({d})", .{ @tagName(attribute), size }), | |
| 1234 | 1219 | .nofpclass => |fpclass| { |
| 1235 | 1220 | const Int = @typeInfo(FpClass).@"struct".backing_integer.?; |
| 1236 | try writer.print(" {s}(", .{@tagName(attribute)}); | |
| 1221 | try bw.print(" {s}(", .{@tagName(attribute)}); | |
| 1237 | 1222 | var any = false; |
| 1238 | 1223 | var remaining: Int = @bitCast(fpclass); |
| 1239 | 1224 | inline for (@typeInfo(FpClass).@"struct".decls) |decl| { |
| 1240 | 1225 | const pattern: Int = @bitCast(@field(FpClass, decl.name)); |
| 1241 | 1226 | if (remaining & pattern == pattern) { |
| 1242 | 1227 | if (!any) { |
| 1243 | try writer.writeByte(' '); | |
| 1228 | try bw.writeByte(' '); | |
| 1244 | 1229 | any = true; |
| 1245 | 1230 | } |
| 1246 | try writer.writeAll(decl.name); | |
| 1231 | try bw.writeAll(decl.name); | |
| 1247 | 1232 | remaining &= ~pattern; |
| 1248 | 1233 | } |
| 1249 | 1234 | } |
| 1250 | try writer.writeByte(')'); | |
| 1235 | try bw.writeByte(')'); | |
| 1251 | 1236 | }, |
| 1252 | .alignstack => |alignment| try writer.print( | |
| 1237 | .alignstack => |alignment| try bw.print( | |
| 1253 | 1238 | if (comptime std.mem.indexOfScalar(u8, fmt_str, '#') != null) |
| 1254 | 1239 | " {s}={d}" |
| 1255 | 1240 | else |
| ... | ... | @@ -1257,53 +1242,53 @@ pub const Attribute = union(Kind) { |
| 1257 | 1242 | .{ @tagName(attribute), alignment.toByteUnits() orelse return }, |
| 1258 | 1243 | ), |
| 1259 | 1244 | .allockind => |allockind| { |
| 1260 | try writer.print(" {s}(\"", .{@tagName(attribute)}); | |
| 1245 | try bw.print(" {s}(\"", .{@tagName(attribute)}); | |
| 1261 | 1246 | var any = false; |
| 1262 | 1247 | inline for (@typeInfo(AllocKind).@"struct".fields) |field| { |
| 1263 | 1248 | if (comptime std.mem.eql(u8, field.name, "_")) continue; |
| 1264 | 1249 | if (@field(allockind, field.name)) { |
| 1265 | 1250 | if (!any) { |
| 1266 | try writer.writeByte(','); | |
| 1251 | try bw.writeByte(','); | |
| 1267 | 1252 | any = true; |
| 1268 | 1253 | } |
| 1269 | try writer.writeAll(field.name); | |
| 1254 | try bw.writeAll(field.name); | |
| 1270 | 1255 | } |
| 1271 | 1256 | } |
| 1272 | try writer.writeAll("\")"); | |
| 1257 | try bw.writeAll("\")"); | |
| 1273 | 1258 | }, |
| 1274 | 1259 | .allocsize => |allocsize| { |
| 1275 | try writer.print(" {s}({d}", .{ @tagName(attribute), allocsize.elem_size }); | |
| 1260 | try bw.print(" {s}({d}", .{ @tagName(attribute), allocsize.elem_size }); | |
| 1276 | 1261 | 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(')'); | |
| 1279 | 1264 | }, |
| 1280 | 1265 | .memory => |memory| { |
| 1281 | try writer.print(" {s}(", .{@tagName(attribute)}); | |
| 1266 | try bw.print(" {s}(", .{@tagName(attribute)}); | |
| 1282 | 1267 | var any = memory.other != .none or |
| 1283 | 1268 | (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)); | |
| 1285 | 1270 | inline for (.{ "argmem", "inaccessiblemem" }) |kind| { |
| 1286 | 1271 | 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)) }); | |
| 1289 | 1274 | any = true; |
| 1290 | 1275 | } |
| 1291 | 1276 | } |
| 1292 | try writer.writeByte(')'); | |
| 1277 | try bw.writeByte(')'); | |
| 1293 | 1278 | }, |
| 1294 | 1279 | .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)}); | |
| 1297 | 1282 | }, |
| 1298 | .vscale_range => |vscale_range| try writer.print(" {s}({d},{d})", .{ | |
| 1283 | .vscale_range => |vscale_range| try bw.print(" {s}({d},{d})", .{ | |
| 1299 | 1284 | @tagName(attribute), |
| 1300 | 1285 | vscale_range.min.toByteUnits().?, |
| 1301 | 1286 | vscale_range.max.toByteUnits() orelse 0, |
| 1302 | 1287 | }), |
| 1303 | 1288 | .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)}); | |
| 1305 | 1290 | 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)}); | |
| 1307 | 1292 | }, |
| 1308 | 1293 | .none => unreachable, |
| 1309 | 1294 | } |
| ... | ... | @@ -1583,16 +1568,11 @@ pub const Attributes = enum(u32) { |
| 1583 | 1568 | attributes: Attributes, |
| 1584 | 1569 | builder: *const Builder, |
| 1585 | 1570 | }; |
| 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 { | |
| 1592 | 1572 | for (data.attributes.slice(data.builder)) |attribute_index| try Attribute.Index.format(.{ |
| 1593 | 1573 | .attribute_index = attribute_index, |
| 1594 | 1574 | .builder = data.builder, |
| 1595 | }, fmt_str, fmt_opts, writer); | |
| 1575 | }, bw, fmt_str); | |
| 1596 | 1576 | } |
| 1597 | 1577 | pub fn fmt(self: Attributes, builder: *const Builder) std.fmt.Formatter(format) { |
| 1598 | 1578 | return .{ .data = .{ .attributes = self, .builder = builder } }; |
| ... | ... | @@ -1781,22 +1761,12 @@ pub const Linkage = enum(u4) { |
| 1781 | 1761 | extern_weak = 7, |
| 1782 | 1762 | external = 0, |
| 1783 | 1763 | |
| 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)}); | |
| 1791 | 1766 | } |
| 1792 | 1767 | |
| 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)}); | |
| 1800 | 1770 | } |
| 1801 | 1771 | pub fn fmtOptional(self: ?Linkage) std.fmt.Formatter(formatOptional) { |
| 1802 | 1772 | return .{ .data = self }; |
| ... | ... | @@ -1808,13 +1778,8 @@ pub const Preemption = enum { |
| 1808 | 1778 | dso_local, |
| 1809 | 1779 | implicit_dso_local, |
| 1810 | 1780 | |
| 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)}); | |
| 1818 | 1783 | } |
| 1819 | 1784 | }; |
| 1820 | 1785 | |
| ... | ... | @@ -1833,10 +1798,10 @@ pub const Visibility = enum(u2) { |
| 1833 | 1798 | |
| 1834 | 1799 | pub fn format( |
| 1835 | 1800 | self: Visibility, |
| 1836 | comptime _: []const u8, | |
| 1837 | _: std.fmt.FormatOptions, | |
| 1801 | comptime format_string: []const u8, | |
| 1838 | 1802 | writer: anytype, |
| 1839 | 1803 | ) @TypeOf(writer).Error!void { |
| 1804 | comptime assert(format_string.len == 0); | |
| 1840 | 1805 | if (self != .default) try writer.print(" {s}", .{@tagName(self)}); |
| 1841 | 1806 | } |
| 1842 | 1807 | }; |
| ... | ... | @@ -1846,13 +1811,8 @@ pub const DllStorageClass = enum(u2) { |
| 1846 | 1811 | dllimport = 1, |
| 1847 | 1812 | dllexport = 2, |
| 1848 | 1813 | |
| 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)}); | |
| 1856 | 1816 | } |
| 1857 | 1817 | }; |
| 1858 | 1818 | |
| ... | ... | @@ -1863,15 +1823,10 @@ pub const ThreadLocal = enum(u3) { |
| 1863 | 1823 | initialexec = 3, |
| 1864 | 1824 | localexec = 4, |
| 1865 | 1825 | |
| 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 { | |
| 1872 | 1827 | 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)}); | |
| 1875 | 1830 | } |
| 1876 | 1831 | }; |
| 1877 | 1832 | |
| ... | ... | @@ -1882,13 +1837,8 @@ pub const UnnamedAddr = enum(u2) { |
| 1882 | 1837 | unnamed_addr = 1, |
| 1883 | 1838 | local_unnamed_addr = 2, |
| 1884 | 1839 | |
| 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)}); | |
| 1892 | 1842 | } |
| 1893 | 1843 | }; |
| 1894 | 1844 | |
| ... | ... | @@ -1981,13 +1931,8 @@ pub const AddrSpace = enum(u24) { |
| 1981 | 1931 | pub const funcref: AddrSpace = @enumFromInt(20); |
| 1982 | 1932 | }; |
| 1983 | 1933 | |
| 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) }); | |
| 1991 | 1936 | } |
| 1992 | 1937 | }; |
| 1993 | 1938 | |
| ... | ... | @@ -1995,15 +1940,8 @@ pub const ExternallyInitialized = enum { |
| 1995 | 1940 | default, |
| 1996 | 1941 | externally_initialized, |
| 1997 | 1942 | |
| 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)}); | |
| 2007 | 1945 | } |
| 2008 | 1946 | }; |
| 2009 | 1947 | |
| ... | ... | @@ -2026,13 +1964,8 @@ pub const Alignment = enum(u6) { |
| 2026 | 1964 | return if (self == .default) 0 else (@intFromEnum(self) + 1); |
| 2027 | 1965 | } |
| 2028 | 1966 | |
| 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 }); | |
| 2036 | 1969 | } |
| 2037 | 1970 | }; |
| 2038 | 1971 | |
| ... | ... | @@ -2105,12 +2038,7 @@ pub const CallConv = enum(u10) { |
| 2105 | 2038 | |
| 2106 | 2039 | pub const default = CallConv.ccc; |
| 2107 | 2040 | |
| 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 { | |
| 2114 | 2042 | switch (self) { |
| 2115 | 2043 | default => {}, |
| 2116 | 2044 | .fastcc, |
| ... | ... | @@ -2164,8 +2092,8 @@ pub const CallConv = enum(u10) { |
| 2164 | 2092 | .aarch64_sme_preservemost_from_x2, |
| 2165 | 2093 | .m68k_rtdcc, |
| 2166 | 2094 | .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)}), | |
| 2169 | 2097 | } |
| 2170 | 2098 | } |
| 2171 | 2099 | }; |
| ... | ... | @@ -2191,26 +2119,21 @@ pub const StrtabString = enum(u32) { |
| 2191 | 2119 | string: StrtabString, |
| 2192 | 2120 | builder: *const Builder, |
| 2193 | 2121 | }; |
| 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 { | |
| 2200 | 2123 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_| |
| 2201 | 2124 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 2202 | 2125 | assert(data.string != .none); |
| 2203 | 2126 | 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)}); | |
| 2205 | 2128 | if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_| |
| 2206 | return writer.writeAll(string_slice); | |
| 2129 | return bw.writeAll(string_slice); | |
| 2207 | 2130 | try printEscapedString( |
| 2208 | 2131 | string_slice, |
| 2209 | 2132 | if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_| |
| 2210 | 2133 | .always_quote |
| 2211 | 2134 | else |
| 2212 | 2135 | .quote_unless_valid_identifier, |
| 2213 | writer, | |
| 2136 | bw, | |
| 2214 | 2137 | ); |
| 2215 | 2138 | } |
| 2216 | 2139 | 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 |
| 2264 | 2187 | } |
| 2265 | 2188 | |
| 2266 | 2189 | pub 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); | |
| 2268 | 2191 | return self.trailingStrtabStringAssumeCapacity(); |
| 2269 | 2192 | } |
| 2270 | 2193 | |
| ... | ... | @@ -2383,13 +2306,8 @@ pub const Global = struct { |
| 2383 | 2306 | global: Index, |
| 2384 | 2307 | builder: *const Builder, |
| 2385 | 2308 | }; |
| 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}", .{ | |
| 2393 | 2311 | data.global.unwrap(data.builder).name(data.builder).fmt(data.builder), |
| 2394 | 2312 | }); |
| 2395 | 2313 | } |
| ... | ... | @@ -4834,28 +4752,23 @@ pub const Function = struct { |
| 4834 | 4752 | function: Function.Index, |
| 4835 | 4753 | builder: *Builder, |
| 4836 | 4754 | }; |
| 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 { | |
| 4843 | 4756 | if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_| |
| 4844 | 4757 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 4845 | 4758 | if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) { |
| 4846 | 4759 | if (data.instruction == .none) return; |
| 4847 | try writer.writeByte(','); | |
| 4760 | try bw.writeByte(','); | |
| 4848 | 4761 | } |
| 4849 | 4762 | if (comptime std.mem.indexOfScalar(u8, fmt_str, ' ') != null) { |
| 4850 | 4763 | if (data.instruction == .none) return; |
| 4851 | try writer.writeByte(' '); | |
| 4764 | try bw.writeByte(' '); | |
| 4852 | 4765 | } |
| 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%} ", | |
| 4855 | 4768 | .{data.instruction.typeOf(data.function, data.builder).fmt(data.builder)}, |
| 4856 | 4769 | ); |
| 4857 | 4770 | assert(data.instruction != .none); |
| 4858 | try writer.print("%{}", .{ | |
| 4771 | try bw.print("%{f}", .{ | |
| 4859 | 4772 | data.instruction.name(data.function.ptrConst(data.builder)).fmt(data.builder), |
| 4860 | 4773 | }); |
| 4861 | 4774 | } |
| ... | ... | @@ -6361,7 +6274,7 @@ pub const WipFunction = struct { |
| 6361 | 6274 | |
| 6362 | 6275 | while (true) { |
| 6363 | 6276 | 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}", .{ | |
| 6365 | 6278 | name.fmt(wip_name.builder), |
| 6366 | 6279 | sep, |
| 6367 | 6280 | gop.value_ptr.fmt(wip_name.builder), |
| ... | ... | @@ -7031,13 +6944,8 @@ pub const MemoryAccessKind = enum(u1) { |
| 7031 | 6944 | normal, |
| 7032 | 6945 | @"volatile", |
| 7033 | 6946 | |
| 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) }); | |
| 7041 | 6949 | } |
| 7042 | 6950 | }; |
| 7043 | 6951 | |
| ... | ... | @@ -7045,13 +6953,8 @@ pub const SyncScope = enum(u1) { |
| 7045 | 6953 | singlethread, |
| 7046 | 6954 | system, |
| 7047 | 6955 | |
| 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( | |
| 7055 | 6958 | \\{s}syncscope("{s}") |
| 7056 | 6959 | , .{ prefix, @tagName(self) }); |
| 7057 | 6960 | } |
| ... | ... | @@ -7066,13 +6969,8 @@ pub const AtomicOrdering = enum(u3) { |
| 7066 | 6969 | acq_rel = 5, |
| 7067 | 6970 | seq_cst = 6, |
| 7068 | 6971 | |
| 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) }); | |
| 7076 | 6974 | } |
| 7077 | 6975 | }; |
| 7078 | 6976 | |
| ... | ... | @@ -7487,26 +7385,21 @@ pub const Constant = enum(u32) { |
| 7487 | 7385 | constant: Constant, |
| 7488 | 7386 | builder: *Builder, |
| 7489 | 7387 | }; |
| 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 { | |
| 7496 | 7389 | if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_| |
| 7497 | 7390 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 7498 | 7391 | if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) { |
| 7499 | 7392 | if (data.constant == .no_init) return; |
| 7500 | try writer.writeByte(','); | |
| 7393 | try bw.writeByte(','); | |
| 7501 | 7394 | } |
| 7502 | 7395 | if (comptime std.mem.indexOfScalar(u8, fmt_str, ' ') != null) { |
| 7503 | 7396 | if (data.constant == .no_init) return; |
| 7504 | try writer.writeByte(' '); | |
| 7397 | try bw.writeByte(' '); | |
| 7505 | 7398 | } |
| 7506 | 7399 | 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)}); | |
| 7508 | 7401 | 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); | |
| 7510 | 7403 | switch (data.constant.unwrap()) { |
| 7511 | 7404 | .constant => |constant| { |
| 7512 | 7405 | const item = data.builder.constant_items.get(constant); |
| ... | ... | @@ -7545,11 +7438,11 @@ pub const Constant = enum(u32) { |
| 7545 | 7438 | const allocator = stack.get(); |
| 7546 | 7439 | const str = try bigint.toStringAlloc(allocator, 10, undefined); |
| 7547 | 7440 | defer allocator.free(str); |
| 7548 | try writer.writeAll(str); | |
| 7441 | try bw.writeAll(str); | |
| 7549 | 7442 | }, |
| 7550 | 7443 | .half, |
| 7551 | 7444 | .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) { | |
| 7553 | 7446 | .half => 'H', |
| 7554 | 7447 | .bfloat => 'R', |
| 7555 | 7448 | else => unreachable, |
| ... | ... | @@ -7580,7 +7473,7 @@ pub const Constant = enum(u32) { |
| 7580 | 7473 | ) + 1, |
| 7581 | 7474 | else => 0, |
| 7582 | 7475 | }; |
| 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){ | |
| 7584 | 7477 | .mantissa = std.math.shl( |
| 7585 | 7478 | Mantissa64, |
| 7586 | 7479 | repr.mantissa, |
| ... | ... | @@ -7602,13 +7495,13 @@ pub const Constant = enum(u32) { |
| 7602 | 7495 | }, |
| 7603 | 7496 | .double => { |
| 7604 | 7497 | 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 }); | |
| 7606 | 7499 | }, |
| 7607 | 7500 | .fp128, |
| 7608 | 7501 | .ppc_fp128, |
| 7609 | 7502 | => |tag| { |
| 7610 | 7503 | 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}", .{ | |
| 7612 | 7505 | @as(u8, switch (tag) { |
| 7613 | 7506 | .fp128 => 'L', |
| 7614 | 7507 | .ppc_fp128 => 'M', |
| ... | ... | @@ -7622,7 +7515,7 @@ pub const Constant = enum(u32) { |
| 7622 | 7515 | }, |
| 7623 | 7516 | .x86_fp80 => { |
| 7624 | 7517 | 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}", .{ | |
| 7626 | 7519 | extra.hi, extra.lo_hi, extra.lo_lo, |
| 7627 | 7520 | }); |
| 7628 | 7521 | }, |
| ... | ... | @@ -7631,7 +7524,7 @@ pub const Constant = enum(u32) { |
| 7631 | 7524 | .zeroinitializer, |
| 7632 | 7525 | .undef, |
| 7633 | 7526 | .poison, |
| 7634 | => |tag| try writer.writeAll(@tagName(tag)), | |
| 7527 | => |tag| try bw.writeAll(@tagName(tag)), | |
| 7635 | 7528 | .structure, |
| 7636 | 7529 | .packed_structure, |
| 7637 | 7530 | .array, |
| ... | ... | @@ -7640,7 +7533,7 @@ pub const Constant = enum(u32) { |
| 7640 | 7533 | var extra = data.builder.constantExtraDataTrail(Aggregate, item.data); |
| 7641 | 7534 | const len: u32 = @intCast(extra.data.type.aggregateLen(data.builder)); |
| 7642 | 7535 | const vals = extra.trail.next(len, Constant, data.builder); |
| 7643 | try writer.writeAll(switch (tag) { | |
| 7536 | try bw.writeAll(switch (tag) { | |
| 7644 | 7537 | .structure => "{ ", |
| 7645 | 7538 | .packed_structure => "<{ ", |
| 7646 | 7539 | .array => "[", |
| ... | ... | @@ -7648,10 +7541,10 @@ pub const Constant = enum(u32) { |
| 7648 | 7541 | else => unreachable, |
| 7649 | 7542 | }); |
| 7650 | 7543 | 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)}); | |
| 7653 | 7546 | } |
| 7654 | try writer.writeAll(switch (tag) { | |
| 7547 | try bw.writeAll(switch (tag) { | |
| 7655 | 7548 | .structure => " }", |
| 7656 | 7549 | .packed_structure => " }>", |
| 7657 | 7550 | .array => "]", |
| ... | ... | @@ -7662,20 +7555,20 @@ pub const Constant = enum(u32) { |
| 7662 | 7555 | .splat => { |
| 7663 | 7556 | const extra = data.builder.constantExtraData(Splat, item.data); |
| 7664 | 7557 | const len = extra.type.vectorLen(data.builder); |
| 7665 | try writer.writeByte('<'); | |
| 7558 | try bw.writeByte('<'); | |
| 7666 | 7559 | 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)}); | |
| 7669 | 7562 | } |
| 7670 | try writer.writeByte('>'); | |
| 7563 | try bw.writeByte('>'); | |
| 7671 | 7564 | }, |
| 7672 | .string => try writer.print("c{\"}", .{ | |
| 7565 | .string => try bw.print("c{f\"}", .{ | |
| 7673 | 7566 | @as(String, @enumFromInt(item.data)).fmt(data.builder), |
| 7674 | 7567 | }), |
| 7675 | 7568 | .blockaddress => |tag| { |
| 7676 | 7569 | const extra = data.builder.constantExtraData(BlockAddress, item.data); |
| 7677 | 7570 | const function = extra.function.ptrConst(data.builder); |
| 7678 | try writer.print("{s}({}, {})", .{ | |
| 7571 | try bw.print("{s}({f}, {f})", .{ | |
| 7679 | 7572 | @tagName(tag), |
| 7680 | 7573 | function.global.fmt(data.builder), |
| 7681 | 7574 | extra.block.toInst(function).fmt(extra.function, data.builder), |
| ... | ... | @@ -7685,7 +7578,7 @@ pub const Constant = enum(u32) { |
| 7685 | 7578 | .no_cfi, |
| 7686 | 7579 | => |tag| { |
| 7687 | 7580 | const function: Function.Index = @enumFromInt(item.data); |
| 7688 | try writer.print("{s} {}", .{ | |
| 7581 | try bw.print("{s} {f}", .{ | |
| 7689 | 7582 | @tagName(tag), |
| 7690 | 7583 | function.ptrConst(data.builder).global.fmt(data.builder), |
| 7691 | 7584 | }); |
| ... | ... | @@ -7697,7 +7590,7 @@ pub const Constant = enum(u32) { |
| 7697 | 7590 | .addrspacecast, |
| 7698 | 7591 | => |tag| { |
| 7699 | 7592 | const extra = data.builder.constantExtraData(Cast, item.data); |
| 7700 | try writer.print("{s} ({%} to {%})", .{ | |
| 7593 | try bw.print("{s} ({f%} to {f%})", .{ | |
| 7701 | 7594 | @tagName(tag), |
| 7702 | 7595 | extra.val.fmt(data.builder), |
| 7703 | 7596 | extra.type.fmt(data.builder), |
| ... | ... | @@ -7709,13 +7602,13 @@ pub const Constant = enum(u32) { |
| 7709 | 7602 | var extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data); |
| 7710 | 7603 | const indices = |
| 7711 | 7604 | extra.trail.next(extra.data.info.indices_len, Constant, data.builder); |
| 7712 | try writer.print("{s} ({%}, {%}", .{ | |
| 7605 | try bw.print("{s} ({f%}, {f%}", .{ | |
| 7713 | 7606 | @tagName(tag), |
| 7714 | 7607 | extra.data.type.fmt(data.builder), |
| 7715 | 7608 | extra.data.base.fmt(data.builder), |
| 7716 | 7609 | }); |
| 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(')'); | |
| 7719 | 7612 | }, |
| 7720 | 7613 | .add, |
| 7721 | 7614 | .@"add nsw", |
| ... | ... | @@ -7727,7 +7620,7 @@ pub const Constant = enum(u32) { |
| 7727 | 7620 | .xor, |
| 7728 | 7621 | => |tag| { |
| 7729 | 7622 | const extra = data.builder.constantExtraData(Binary, item.data); |
| 7730 | try writer.print("{s} ({%}, {%})", .{ | |
| 7623 | try bw.print("{s} ({f%}, {f%})", .{ | |
| 7731 | 7624 | @tagName(tag), |
| 7732 | 7625 | extra.lhs.fmt(data.builder), |
| 7733 | 7626 | extra.rhs.fmt(data.builder), |
| ... | ... | @@ -7751,7 +7644,7 @@ pub const Constant = enum(u32) { |
| 7751 | 7644 | .@"asm sideeffect alignstack inteldialect unwind", |
| 7752 | 7645 | => |tag| { |
| 7753 | 7646 | const extra = data.builder.constantExtraData(Assembly, item.data); |
| 7754 | try writer.print("{s} {\"}, {\"}", .{ | |
| 7647 | try bw.print("{s} {f\"}, {f\"}", .{ | |
| 7755 | 7648 | @tagName(tag), |
| 7756 | 7649 | extra.assembly.fmt(data.builder), |
| 7757 | 7650 | extra.constraints.fmt(data.builder), |
| ... | ... | @@ -7759,7 +7652,7 @@ pub const Constant = enum(u32) { |
| 7759 | 7652 | }, |
| 7760 | 7653 | } |
| 7761 | 7654 | }, |
| 7762 | .global => |global| try writer.print("{}", .{global.fmt(data.builder)}), | |
| 7655 | .global => |global| try bw.print("{f}", .{global.fmt(data.builder)}), | |
| 7763 | 7656 | } |
| 7764 | 7657 | } |
| 7765 | 7658 | pub fn fmt(self: Constant, builder: *Builder) std.fmt.Formatter(format) { |
| ... | ... | @@ -7819,22 +7712,17 @@ pub const Value = enum(u32) { |
| 7819 | 7712 | function: Function.Index, |
| 7820 | 7713 | builder: *Builder, |
| 7821 | 7714 | }; |
| 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 { | |
| 7828 | 7716 | switch (data.value.unwrap()) { |
| 7829 | 7717 | .instruction => |instruction| try Function.Instruction.Index.format(.{ |
| 7830 | 7718 | .instruction = instruction, |
| 7831 | 7719 | .function = data.function, |
| 7832 | 7720 | .builder = data.builder, |
| 7833 | }, fmt_str, fmt_opts, writer), | |
| 7721 | }, bw, fmt_str), | |
| 7834 | 7722 | .constant => |constant| try Constant.format(.{ |
| 7835 | 7723 | .constant = constant, |
| 7836 | 7724 | .builder = data.builder, |
| 7837 | }, fmt_str, fmt_opts, writer), | |
| 7725 | }, bw, fmt_str), | |
| 7838 | 7726 | .metadata => unreachable, |
| 7839 | 7727 | } |
| 7840 | 7728 | } |
| ... | ... | @@ -7869,13 +7757,8 @@ pub const MetadataString = enum(u32) { |
| 7869 | 7757 | metadata_string: MetadataString, |
| 7870 | 7758 | builder: *const Builder, |
| 7871 | 7759 | }; |
| 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); | |
| 7879 | 7762 | } |
| 7880 | 7763 | fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Formatter(format) { |
| 7881 | 7764 | return .{ .data = .{ .metadata_string = self, .builder = builder } }; |
| ... | ... | @@ -8039,29 +7922,24 @@ pub const Metadata = enum(u32) { |
| 8039 | 7922 | AllCallsDescribed: bool = false, |
| 8040 | 7923 | Unused: u2 = 0, |
| 8041 | 7924 | |
| 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 { | |
| 8048 | 7926 | var need_pipe = false; |
| 8049 | 7927 | inline for (@typeInfo(DIFlags).@"struct".fields) |field| { |
| 8050 | 7928 | switch (@typeInfo(field.type)) { |
| 8051 | 7929 | .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}); | |
| 8054 | 7932 | }, |
| 8055 | 7933 | .@"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))}); | |
| 8058 | 7936 | }, |
| 8059 | 7937 | .int => assert(@field(self, field.name) == 0), |
| 8060 | 7938 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ |
| 8061 | 7939 | @typeName(field.type)), |
| 8062 | 7940 | } |
| 8063 | 7941 | } |
| 8064 | if (!need_pipe) try writer.writeByte('0'); | |
| 7942 | if (!need_pipe) try bw.writeByte('0'); | |
| 8065 | 7943 | } |
| 8066 | 7944 | }; |
| 8067 | 7945 | |
| ... | ... | @@ -8101,29 +7979,24 @@ pub const Metadata = enum(u32) { |
| 8101 | 7979 | ObjCDirect: bool = false, |
| 8102 | 7980 | Unused: u20 = 0, |
| 8103 | 7981 | |
| 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 { | |
| 8110 | 7983 | var need_pipe = false; |
| 8111 | 7984 | inline for (@typeInfo(DISPFlags).@"struct".fields) |field| { |
| 8112 | 7985 | switch (@typeInfo(field.type)) { |
| 8113 | 7986 | .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}); | |
| 8116 | 7989 | }, |
| 8117 | 7990 | .@"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))}); | |
| 8120 | 7993 | }, |
| 8121 | 7994 | .int => assert(@field(self, field.name) == 0), |
| 8122 | 7995 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ |
| 8123 | 7996 | @typeName(field.type)), |
| 8124 | 7997 | } |
| 8125 | 7998 | } |
| 8126 | if (!need_pipe) try writer.writeByte('0'); | |
| 7999 | if (!need_pipe) try bw.writeByte('0'); | |
| 8127 | 8000 | } |
| 8128 | 8001 | }; |
| 8129 | 8002 | |
| ... | ... | @@ -8323,20 +8196,15 @@ pub const Metadata = enum(u32) { |
| 8323 | 8196 | }; |
| 8324 | 8197 | }; |
| 8325 | 8198 | }; |
| 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 { | |
| 8332 | 8200 | if (data.node == .none) return; |
| 8333 | 8201 | |
| 8334 | 8202 | const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S'; |
| 8335 | 8203 | const recurse_fmt_str = if (is_specialized) fmt_str[1..] else fmt_str; |
| 8336 | 8204 | |
| 8337 | if (data.formatter.need_comma) try writer.writeAll(", "); | |
| 8205 | if (data.formatter.need_comma) try bw.writeAll(", "); | |
| 8338 | 8206 | defer data.formatter.need_comma = true; |
| 8339 | try writer.writeAll(data.prefix); | |
| 8207 | try bw.writeAll(data.prefix); | |
| 8340 | 8208 | |
| 8341 | 8209 | const builder = data.formatter.builder; |
| 8342 | 8210 | switch (data.node) { |
| ... | ... | @@ -8351,48 +8219,44 @@ pub const Metadata = enum(u32) { |
| 8351 | 8219 | .expression => { |
| 8352 | 8220 | var extra = builder.metadataExtraDataTrail(Expression, item.data); |
| 8353 | 8221 | const elements = extra.trail.next(extra.data.elements_len, u32, builder); |
| 8354 | try writer.writeAll("!DIExpression("); | |
| 8222 | try bw.writeAll("!DIExpression("); | |
| 8355 | 8223 | for (elements) |element| try format(.{ |
| 8356 | 8224 | .formatter = data.formatter, |
| 8357 | 8225 | .node = .{ .u64 = element }, |
| 8358 | }, "%", fmt_opts, writer); | |
| 8359 | try writer.writeByte(')'); | |
| 8226 | }, bw, "%"); | |
| 8227 | try bw.writeByte(')'); | |
| 8360 | 8228 | }, |
| 8361 | 8229 | .constant => try Constant.format(.{ |
| 8362 | 8230 | .constant = @enumFromInt(item.data), |
| 8363 | 8231 | .builder = builder, |
| 8364 | }, recurse_fmt_str, fmt_opts, writer), | |
| 8232 | }, bw, recurse_fmt_str), | |
| 8365 | 8233 | else => unreachable, |
| 8366 | 8234 | } |
| 8367 | 8235 | }, |
| 8368 | .index => |node| try writer.print("!{d}", .{node}), | |
| 8236 | .index => |node| try bw.print("!{d}", .{node}), | |
| 8369 | 8237 | inline .local_value, .local_metadata => |node, tag| try Value.format(.{ |
| 8370 | 8238 | .value = node.value, |
| 8371 | 8239 | .function = node.function, |
| 8372 | 8240 | .builder = builder, |
| 8373 | }, switch (tag) { | |
| 8241 | }, bw, switch (tag) { | |
| 8374 | 8242 | .local_value => recurse_fmt_str, |
| 8375 | 8243 | .local_metadata => "%", |
| 8376 | 8244 | else => unreachable, |
| 8377 | }, fmt_opts, writer), | |
| 8245 | }), | |
| 8378 | 8246 | inline .local_inline, .local_index => |node, tag| { |
| 8379 | 8247 | 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)}); | |
| 8381 | 8249 | try format(.{ |
| 8382 | 8250 | .formatter = data.formatter, |
| 8383 | 8251 | .node = @unionInit(FormatData.Node, @tagName(tag)["local_".len..], node), |
| 8384 | }, "%", fmt_opts, writer); | |
| 8252 | }, bw, "%"); | |
| 8385 | 8253 | }, |
| 8386 | .string => |node| try writer.print((if (is_specialized) "" else "!") ++ "{}", .{ | |
| 8254 | .string => |node| try bw.print((if (is_specialized) "" else "!") ++ "{f}", .{ | |
| 8387 | 8255 | node.fmt(builder), |
| 8388 | 8256 | }), |
| 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), | |
| 8396 | 8260 | } |
| 8397 | 8261 | } |
| 8398 | 8262 | inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype) switch (@TypeOf(node)) { |
| ... | ... | @@ -8506,8 +8370,8 @@ pub const Metadata = enum(u32) { |
| 8506 | 8370 | DIGlobalVariableExpression, |
| 8507 | 8371 | }, |
| 8508 | 8372 | nodes: anytype, |
| 8509 | writer: anytype, | |
| 8510 | ) !void { | |
| 8373 | bw: *std.io.BufferedWriter, | |
| 8374 | ) anyerror!void { | |
| 8511 | 8375 | comptime var fmt_str: []const u8 = ""; |
| 8512 | 8376 | const names = comptime std.meta.fieldNames(@TypeOf(nodes)); |
| 8513 | 8377 | comptime var fields: [2 + names.len]std.builtin.Type.StructField = undefined; |
| ... | ... | @@ -8523,7 +8387,7 @@ pub const Metadata = enum(u32) { |
| 8523 | 8387 | } |
| 8524 | 8388 | fmt_str = fmt_str ++ "("; |
| 8525 | 8389 | inline for (fields[2..], names) |*field, name| { |
| 8526 | fmt_str = fmt_str ++ "{[" ++ name ++ "]S}"; | |
| 8390 | fmt_str = fmt_str ++ "{[" ++ name ++ "]fS}"; | |
| 8527 | 8391 | field.* = .{ |
| 8528 | 8392 | .name = name, |
| 8529 | 8393 | .type = std.fmt.Formatter(format), |
| ... | ... | @@ -8546,7 +8410,7 @@ pub const Metadata = enum(u32) { |
| 8546 | 8410 | name ++ ": ", |
| 8547 | 8411 | @field(nodes, name), |
| 8548 | 8412 | ); |
| 8549 | try writer.print(fmt_str, fmt_args); | |
| 8413 | try bw.print(fmt_str, fmt_args); | |
| 8550 | 8414 | } |
| 8551 | 8415 | }; |
| 8552 | 8416 | }; |
| ... | ... | @@ -8636,7 +8500,7 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8636 | 8500 | inline for (.{ 0, 4 }) |addr_space_index| { |
| 8637 | 8501 | const addr_space: AddrSpace = @enumFromInt(addr_space_index); |
| 8638 | 8502 | assert(self.ptrTypeAssumeCapacity(addr_space) == |
| 8639 | @field(Type, std.fmt.comptimePrint("ptr{ }", .{addr_space}))); | |
| 8503 | @field(Type, std.fmt.comptimePrint("ptr{f }", .{addr_space}))); | |
| 8640 | 8504 | } |
| 8641 | 8505 | } |
| 8642 | 8506 | |
| ... | ... | @@ -8759,16 +8623,17 @@ pub fn deinit(self: *Builder) void { |
| 8759 | 8623 | self.* = undefined; |
| 8760 | 8624 | } |
| 8761 | 8625 | |
| 8762 | pub fn setModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer { | |
| 8626 | pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter { | |
| 8763 | 8627 | self.module_asm.clearRetainingCapacity(); |
| 8764 | return self.appendModuleAsm(); | |
| 8628 | return self.appendModuleAsm(aw); | |
| 8765 | 8629 | } |
| 8766 | 8630 | |
| 8767 | pub fn appendModuleAsm(self: *Builder) std.ArrayListUnmanaged(u8).Writer { | |
| 8768 | return self.module_asm.writer(self.gpa); | |
| 8631 | pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter { | |
| 8632 | return aw.fromArrayList(self.gpa, &self.module_asm); | |
| 8769 | 8633 | } |
| 8770 | 8634 | |
| 8771 | pub fn finishModuleAsm(self: *Builder) Allocator.Error!void { | |
| 8635 | pub fn finishModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) Allocator.Error!void { | |
| 8636 | self.module_asm = aw.toArrayList(); | |
| 8772 | 8637 | if (self.module_asm.getLastOrNull()) |last| if (last != '\n') |
| 8773 | 8638 | try self.module_asm.append(self.gpa, '\n'); |
| 8774 | 8639 | } |
| ... | ... | @@ -8804,7 +8669,7 @@ pub fn fmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allo |
| 8804 | 8669 | } |
| 8805 | 8670 | |
| 8806 | 8671 | pub 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); | |
| 8808 | 8673 | return self.trailingStringAssumeCapacity(); |
| 8809 | 8674 | } |
| 8810 | 8675 | |
| ... | ... | @@ -9076,9 +8941,13 @@ pub fn getIntrinsic( |
| 9076 | 8941 | const allocator = stack.get(); |
| 9077 | 8942 | |
| 9078 | 8943 | 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 | } | |
| 9082 | 8951 | break :name try self.trailingStrtabString(); |
| 9083 | 8952 | }; |
| 9084 | 8953 | if (self.getGlobal(name)) |global| return global.ptrConst(self).kind.function; |
| ... | ... | @@ -9494,108 +9363,78 @@ pub fn asmValue( |
| 9494 | 9363 | |
| 9495 | 9364 | pub fn dump(self: *Builder) void { |
| 9496 | 9365 | const stderr: std.fs.File = .stderr(); |
| 9497 | self.print(stderr.writer().unbuffered()) catch {}; | |
| 9366 | self.printBuffered(stderr.writer()) catch {}; | |
| 9498 | 9367 | } |
| 9499 | 9368 | |
| 9500 | pub fn printToFile(self: *Builder, path: []const u8) Allocator.Error!bool { | |
| 9369 | pub fn printToFile(self: *Builder, path: []const u8) bool { | |
| 9501 | 9370 | var file = std.fs.cwd().createFile(path, .{}) catch |err| { |
| 9502 | 9371 | log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); |
| 9503 | 9372 | return false; |
| 9504 | 9373 | }; |
| 9505 | 9374 | defer file.close(); |
| 9506 | self.print(file.writer()) catch |err| { | |
| 9375 | self.printBuffered(file.writer()) catch |err| { | |
| 9507 | 9376 | log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); |
| 9508 | 9377 | return false; |
| 9509 | 9378 | }; |
| 9510 | 9379 | return true; |
| 9511 | 9380 | } |
| 9512 | 9381 | |
| 9513 | pub 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()); | |
| 9382 | pub 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); | |
| 9516 | 9386 | try bw.flush(); |
| 9517 | 9387 | } |
| 9518 | 9388 | |
| 9519 | fn 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 | } | |
| 9537 | fn writerWithErrors( | |
| 9538 | backing_writer: anytype, | |
| 9539 | comptime ExtraErrors: type, | |
| 9540 | ) WriterWithErrors(@TypeOf(backing_writer), ExtraErrors) { | |
| 9541 | return .{ .backing_writer = backing_writer }; | |
| 9542 | } | |
| 9543 | ||
| 9544 | pub 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 | ||
| 9389 | pub fn print(self: *Builder, bw: *std.io.BufferedWriter) anyerror!void { | |
| 9551 | 9390 | var need_newline = false; |
| 9552 | 9391 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; |
| 9553 | 9392 | defer metadata_formatter.map.deinit(self.gpa); |
| 9554 | 9393 | |
| 9555 | 9394 | 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( | |
| 9558 | 9397 | \\; ModuleID = '{s}' |
| 9559 | \\source_filename = {"} | |
| 9398 | \\source_filename = {f"} | |
| 9560 | 9399 | \\ |
| 9561 | 9400 | , .{ 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"} | |
| 9564 | 9403 | \\ |
| 9565 | 9404 | , .{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"} | |
| 9568 | 9407 | \\ |
| 9569 | 9408 | , .{self.target_triple.fmt(self)}); |
| 9570 | 9409 | } |
| 9571 | 9410 | |
| 9572 | 9411 | 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; | |
| 9574 | 9413 | var line_it = std.mem.tokenizeScalar(u8, self.module_asm.items, '\n'); |
| 9575 | 9414 | 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'); | |
| 9579 | 9418 | } |
| 9580 | 9419 | } |
| 9581 | 9420 | |
| 9582 | 9421 | 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} | |
| 9586 | 9425 | \\ |
| 9587 | 9426 | , .{ id.fmt(self), ty.fmt(self) }); |
| 9588 | 9427 | } |
| 9589 | 9428 | |
| 9590 | 9429 | 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; | |
| 9592 | 9431 | for (self.variables.items) |variable| { |
| 9593 | 9432 | if (variable.global.getReplacement(self) != .none) continue; |
| 9594 | 9433 | const global = variable.global.ptrConst(self); |
| 9595 | 9434 | metadata_formatter.need_comma = true; |
| 9596 | 9435 | 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} | |
| 9599 | 9438 | \\ |
| 9600 | 9439 | , .{ |
| 9601 | 9440 | variable.global.fmt(self), |
| ... | ... | @@ -9618,14 +9457,14 @@ pub fn printUnbuffered( |
| 9618 | 9457 | } |
| 9619 | 9458 | |
| 9620 | 9459 | 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; | |
| 9622 | 9461 | for (self.aliases.items) |alias| { |
| 9623 | 9462 | if (alias.global.getReplacement(self) != .none) continue; |
| 9624 | 9463 | const global = alias.global.ptrConst(self); |
| 9625 | 9464 | metadata_formatter.need_comma = true; |
| 9626 | 9465 | 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} | |
| 9629 | 9468 | \\ |
| 9630 | 9469 | , .{ |
| 9631 | 9470 | alias.global.fmt(self), |
| ... | ... | @@ -9647,17 +9486,17 @@ pub fn printUnbuffered( |
| 9647 | 9486 | |
| 9648 | 9487 | for (0.., self.functions.items) |function_i, function| { |
| 9649 | 9488 | 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; | |
| 9651 | 9490 | const function_index: Function.Index = @enumFromInt(function_i); |
| 9652 | 9491 | const global = function.global.ptrConst(self); |
| 9653 | 9492 | const params_len = global.type.functionParameters(self).len; |
| 9654 | 9493 | 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} | |
| 9657 | 9496 | \\ |
| 9658 | 9497 | , .{function_attributes.fmt(self)}); |
| 9659 | try writer.print( | |
| 9660 | \\{s}{}{}{}{}{}{"} {%} {}( | |
| 9498 | try bw.print( | |
| 9499 | \\{s}{f}{f}{f}{f}{f}{f"} {f%} {f}( | |
| 9661 | 9500 | , .{ |
| 9662 | 9501 | if (function.instructions.len > 0) "define" else "declare", |
| 9663 | 9502 | global.linkage, |
| ... | ... | @@ -9670,40 +9509,40 @@ pub fn printUnbuffered( |
| 9670 | 9509 | function.global.fmt(self), |
| 9671 | 9510 | }); |
| 9672 | 9511 | 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"} | |
| 9676 | 9515 | , .{ |
| 9677 | 9516 | global.type.functionParameters(self)[arg].fmt(self), |
| 9678 | 9517 | function.attributes.param(arg, self).fmt(self), |
| 9679 | 9518 | }); |
| 9680 | 9519 | 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)}) | |
| 9682 | 9521 | else |
| 9683 | try writer.print(" %{d}", .{arg}); | |
| 9522 | try bw.print(" %{d}", .{arg}); | |
| 9684 | 9523 | } |
| 9685 | 9524 | switch (global.type.functionKind(self)) { |
| 9686 | 9525 | .normal => {}, |
| 9687 | 9526 | .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("..."); | |
| 9690 | 9529 | }, |
| 9691 | 9530 | } |
| 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}", .{ | |
| 9694 | 9533 | (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index, |
| 9695 | 9534 | }); |
| 9696 | 9535 | { |
| 9697 | 9536 | metadata_formatter.need_comma = false; |
| 9698 | 9537 | defer metadata_formatter.need_comma = undefined; |
| 9699 | try writer.print("{ }{}", .{ | |
| 9538 | try bw.print("{f }{f}", .{ | |
| 9700 | 9539 | function.alignment, |
| 9701 | 9540 | try metadata_formatter.fmt(" !dbg ", global.dbg), |
| 9702 | 9541 | }); |
| 9703 | 9542 | } |
| 9704 | 9543 | if (function.instructions.len > 0) { |
| 9705 | 9544 | var block_incoming_len: u32 = undefined; |
| 9706 | try writer.writeAll(" {\n"); | |
| 9545 | try bw.writeAll(" {\n"); | |
| 9707 | 9546 | var maybe_dbg_index: ?u32 = null; |
| 9708 | 9547 | for (params_len..function.instructions.len) |instruction_i| { |
| 9709 | 9548 | const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i); |
| ... | ... | @@ -9801,7 +9640,7 @@ pub fn printUnbuffered( |
| 9801 | 9640 | .xor, |
| 9802 | 9641 | => |tag| { |
| 9803 | 9642 | const extra = function.extraData(Function.Instruction.Binary, instruction.data); |
| 9804 | try writer.print(" %{} = {s} {%}, {}", .{ | |
| 9643 | try bw.print(" %{f} = {s} {f%}, {f}", .{ | |
| 9805 | 9644 | instruction_index.name(&function).fmt(self), |
| 9806 | 9645 | @tagName(tag), |
| 9807 | 9646 | extra.lhs.fmt(function_index, self), |
| ... | ... | @@ -9823,7 +9662,7 @@ pub fn printUnbuffered( |
| 9823 | 9662 | .zext, |
| 9824 | 9663 | => |tag| { |
| 9825 | 9664 | const extra = function.extraData(Function.Instruction.Cast, instruction.data); |
| 9826 | try writer.print(" %{} = {s} {%} to {%}", .{ | |
| 9665 | try bw.print(" %{f} = {s} {f%} to {f%}", .{ | |
| 9827 | 9666 | instruction_index.name(&function).fmt(self), |
| 9828 | 9667 | @tagName(tag), |
| 9829 | 9668 | extra.val.fmt(function_index, self), |
| ... | ... | @@ -9834,7 +9673,7 @@ pub fn printUnbuffered( |
| 9834 | 9673 | .@"alloca inalloca", |
| 9835 | 9674 | => |tag| { |
| 9836 | 9675 | const extra = function.extraData(Function.Instruction.Alloca, instruction.data); |
| 9837 | try writer.print(" %{} = {s} {%}{,%}{, }{, }", .{ | |
| 9676 | try bw.print(" %{f} = {s} {f%}{f,%}{f, }{f, }", .{ | |
| 9838 | 9677 | instruction_index.name(&function).fmt(self), |
| 9839 | 9678 | @tagName(tag), |
| 9840 | 9679 | extra.type.fmt(self), |
| ... | ... | @@ -9850,7 +9689,7 @@ pub fn printUnbuffered( |
| 9850 | 9689 | .atomicrmw => |tag| { |
| 9851 | 9690 | const extra = |
| 9852 | 9691 | 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, }", .{ | |
| 9854 | 9693 | instruction_index.name(&function).fmt(self), |
| 9855 | 9694 | @tagName(tag), |
| 9856 | 9695 | extra.info.access_kind, |
| ... | ... | @@ -9866,19 +9705,19 @@ pub fn printUnbuffered( |
| 9866 | 9705 | block_incoming_len = instruction.data; |
| 9867 | 9706 | const name = instruction_index.name(&function); |
| 9868 | 9707 | 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)}); | |
| 9871 | 9710 | continue; |
| 9872 | 9711 | }, |
| 9873 | 9712 | .br => |tag| { |
| 9874 | 9713 | const target: Function.Block.Index = @enumFromInt(instruction.data); |
| 9875 | try writer.print(" {s} {%}", .{ | |
| 9714 | try bw.print(" {s} {f%}", .{ | |
| 9876 | 9715 | @tagName(tag), target.toInst(&function).fmt(function_index, self), |
| 9877 | 9716 | }); |
| 9878 | 9717 | }, |
| 9879 | 9718 | .br_cond => { |
| 9880 | 9719 | const extra = function.extraData(Function.Instruction.BrCond, instruction.data); |
| 9881 | try writer.print(" br {%}, {%}, {%}", .{ | |
| 9720 | try bw.print(" br {f%}, {f%}, {f%}", .{ | |
| 9882 | 9721 | extra.cond.fmt(function_index, self), |
| 9883 | 9722 | extra.then.toInst(&function).fmt(function_index, self), |
| 9884 | 9723 | extra.@"else".toInst(&function).fmt(function_index, self), |
| ... | ... | @@ -9887,8 +9726,8 @@ pub fn printUnbuffered( |
| 9887 | 9726 | defer metadata_formatter.need_comma = undefined; |
| 9888 | 9727 | switch (extra.weights) { |
| 9889 | 9728 | .none => {}, |
| 9890 | .unpredictable => try writer.writeAll("!unpredictable !{}"), | |
| 9891 | _ => try writer.print("{}", .{ | |
| 9729 | .unpredictable => try bw.writeAll("!unpredictable !{}"), | |
| 9730 | _ => try bw.print("{f}", .{ | |
| 9892 | 9731 | try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights)))), |
| 9893 | 9732 | }), |
| 9894 | 9733 | } |
| ... | ... | @@ -9905,16 +9744,16 @@ pub fn printUnbuffered( |
| 9905 | 9744 | var extra = |
| 9906 | 9745 | function.extraDataTrail(Function.Instruction.Call, instruction.data); |
| 9907 | 9746 | const args = extra.trail.next(extra.data.args_len, Value, &function); |
| 9908 | try writer.writeAll(" "); | |
| 9747 | try bw.writeAll(" "); | |
| 9909 | 9748 | const ret_ty = extra.data.ty.functionReturn(self); |
| 9910 | 9749 | switch (ret_ty) { |
| 9911 | 9750 | .void => {}, |
| 9912 | else => try writer.print("%{} = ", .{ | |
| 9751 | else => try bw.print("%{f} = ", .{ | |
| 9913 | 9752 | instruction_index.name(&function).fmt(self), |
| 9914 | 9753 | }), |
| 9915 | 9754 | .none => unreachable, |
| 9916 | 9755 | } |
| 9917 | try writer.print("{s}{}{}{} {%} {}(", .{ | |
| 9756 | try bw.print("{s}{f}{f}{f} {f%} {f}(", .{ | |
| 9918 | 9757 | @tagName(tag), |
| 9919 | 9758 | extra.data.info.call_conv, |
| 9920 | 9759 | extra.data.attributes.ret(self).fmt(self), |
| ... | ... | @@ -9926,21 +9765,21 @@ pub fn printUnbuffered( |
| 9926 | 9765 | extra.data.callee.fmt(function_index, self), |
| 9927 | 9766 | }); |
| 9928 | 9767 | for (0.., args) |arg_index, arg| { |
| 9929 | if (arg_index > 0) try writer.writeAll(", "); | |
| 9768 | if (arg_index > 0) try bw.writeAll(", "); | |
| 9930 | 9769 | metadata_formatter.need_comma = false; |
| 9931 | 9770 | defer metadata_formatter.need_comma = undefined; |
| 9932 | try writer.print("{%}{}{}", .{ | |
| 9771 | try bw.print("{f%}{f}{f}", .{ | |
| 9933 | 9772 | arg.typeOf(function_index, self).fmt(self), |
| 9934 | 9773 | extra.data.attributes.param(arg_index, self).fmt(self), |
| 9935 | 9774 | try metadata_formatter.fmtLocal(" ", arg, function_index), |
| 9936 | 9775 | }); |
| 9937 | 9776 | } |
| 9938 | try writer.writeByte(')'); | |
| 9777 | try bw.writeByte(')'); | |
| 9939 | 9778 | if (extra.data.info.has_op_bundle_cold) { |
| 9940 | try writer.writeAll(" [ \"cold\"() ]"); | |
| 9779 | try bw.writeAll(" [ \"cold\"() ]"); | |
| 9941 | 9780 | } |
| 9942 | 9781 | 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}", .{ | |
| 9944 | 9783 | (try attribute_groups.getOrPutValue( |
| 9945 | 9784 | self.gpa, |
| 9946 | 9785 | call_function_attributes, |
| ... | ... | @@ -9953,7 +9792,7 @@ pub fn printUnbuffered( |
| 9953 | 9792 | => |tag| { |
| 9954 | 9793 | const extra = |
| 9955 | 9794 | 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, }", .{ | |
| 9957 | 9796 | instruction_index.name(&function).fmt(self), |
| 9958 | 9797 | @tagName(tag), |
| 9959 | 9798 | extra.info.access_kind, |
| ... | ... | @@ -9969,7 +9808,7 @@ pub fn printUnbuffered( |
| 9969 | 9808 | .extractelement => |tag| { |
| 9970 | 9809 | const extra = |
| 9971 | 9810 | function.extraData(Function.Instruction.ExtractElement, instruction.data); |
| 9972 | try writer.print(" %{} = {s} {%}, {%}", .{ | |
| 9811 | try bw.print(" %{f} = {s} {f%}, {f%}", .{ | |
| 9973 | 9812 | instruction_index.name(&function).fmt(self), |
| 9974 | 9813 | @tagName(tag), |
| 9975 | 9814 | extra.val.fmt(function_index, self), |
| ... | ... | @@ -9982,16 +9821,16 @@ pub fn printUnbuffered( |
| 9982 | 9821 | instruction.data, |
| 9983 | 9822 | ); |
| 9984 | 9823 | const indices = extra.trail.next(extra.data.indices_len, u32, &function); |
| 9985 | try writer.print(" %{} = {s} {%}", .{ | |
| 9824 | try bw.print(" %{f} = {s} {f%}", .{ | |
| 9986 | 9825 | instruction_index.name(&function).fmt(self), |
| 9987 | 9826 | @tagName(tag), |
| 9988 | 9827 | extra.data.val.fmt(function_index, self), |
| 9989 | 9828 | }); |
| 9990 | for (indices) |index| try writer.print(", {d}", .{index}); | |
| 9829 | for (indices) |index| try bw.print(", {d}", .{index}); | |
| 9991 | 9830 | }, |
| 9992 | 9831 | .fence => |tag| { |
| 9993 | 9832 | const info: MemoryAccessInfo = @bitCast(instruction.data); |
| 9994 | try writer.print(" {s}{ }{ }", .{ | |
| 9833 | try bw.print(" {s}{f }{f }", .{ | |
| 9995 | 9834 | @tagName(tag), |
| 9996 | 9835 | info.sync_scope, |
| 9997 | 9836 | info.success_ordering, |
| ... | ... | @@ -10001,7 +9840,7 @@ pub fn printUnbuffered( |
| 10001 | 9840 | .@"fneg fast", |
| 10002 | 9841 | => |tag| { |
| 10003 | 9842 | const val: Value = @enumFromInt(instruction.data); |
| 10004 | try writer.print(" %{} = {s} {%}", .{ | |
| 9843 | try bw.print(" %{f} = {s} {f%}", .{ | |
| 10005 | 9844 | instruction_index.name(&function).fmt(self), |
| 10006 | 9845 | @tagName(tag), |
| 10007 | 9846 | val.fmt(function_index, self), |
| ... | ... | @@ -10015,13 +9854,13 @@ pub fn printUnbuffered( |
| 10015 | 9854 | instruction.data, |
| 10016 | 9855 | ); |
| 10017 | 9856 | const indices = extra.trail.next(extra.data.indices_len, Value, &function); |
| 10018 | try writer.print(" %{} = {s} {%}, {%}", .{ | |
| 9857 | try bw.print(" %{f} = {s} {f%}, {f%}", .{ | |
| 10019 | 9858 | instruction_index.name(&function).fmt(self), |
| 10020 | 9859 | @tagName(tag), |
| 10021 | 9860 | extra.data.type.fmt(self), |
| 10022 | 9861 | extra.data.base.fmt(function_index, self), |
| 10023 | 9862 | }); |
| 10024 | for (indices) |index| try writer.print(", {%}", .{ | |
| 9863 | for (indices) |index| try bw.print(", {f%}", .{ | |
| 10025 | 9864 | index.fmt(function_index, self), |
| 10026 | 9865 | }); |
| 10027 | 9866 | }, |
| ... | ... | @@ -10030,22 +9869,22 @@ pub fn printUnbuffered( |
| 10030 | 9869 | function.extraDataTrail(Function.Instruction.IndirectBr, instruction.data); |
| 10031 | 9870 | const targets = |
| 10032 | 9871 | extra.trail.next(extra.data.targets_len, Function.Block.Index, &function); |
| 10033 | try writer.print(" {s} {%}, [", .{ | |
| 9872 | try bw.print(" {s} {f%}, [", .{ | |
| 10034 | 9873 | @tagName(tag), |
| 10035 | 9874 | extra.data.addr.fmt(function_index, self), |
| 10036 | 9875 | }); |
| 10037 | 9876 | 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%}", .{ | |
| 10040 | 9879 | target.toInst(&function).fmt(function_index, self), |
| 10041 | 9880 | }); |
| 10042 | 9881 | } |
| 10043 | try writer.writeByte(']'); | |
| 9882 | try bw.writeByte(']'); | |
| 10044 | 9883 | }, |
| 10045 | 9884 | .insertelement => |tag| { |
| 10046 | 9885 | const extra = |
| 10047 | 9886 | function.extraData(Function.Instruction.InsertElement, instruction.data); |
| 10048 | try writer.print(" %{} = {s} {%}, {%}, {%}", .{ | |
| 9887 | try bw.print(" %{f} = {s} {f%}, {f%}, {f%}", .{ | |
| 10049 | 9888 | instruction_index.name(&function).fmt(self), |
| 10050 | 9889 | @tagName(tag), |
| 10051 | 9890 | extra.val.fmt(function_index, self), |
| ... | ... | @@ -10057,19 +9896,19 @@ pub fn printUnbuffered( |
| 10057 | 9896 | var extra = |
| 10058 | 9897 | function.extraDataTrail(Function.Instruction.InsertValue, instruction.data); |
| 10059 | 9898 | const indices = extra.trail.next(extra.data.indices_len, u32, &function); |
| 10060 | try writer.print(" %{} = {s} {%}, {%}", .{ | |
| 9899 | try bw.print(" %{f} = {s} {f%}, {f%}", .{ | |
| 10061 | 9900 | instruction_index.name(&function).fmt(self), |
| 10062 | 9901 | @tagName(tag), |
| 10063 | 9902 | extra.data.val.fmt(function_index, self), |
| 10064 | 9903 | extra.data.elem.fmt(function_index, self), |
| 10065 | 9904 | }); |
| 10066 | for (indices) |index| try writer.print(", {d}", .{index}); | |
| 9905 | for (indices) |index| try bw.print(", {d}", .{index}); | |
| 10067 | 9906 | }, |
| 10068 | 9907 | .load, |
| 10069 | 9908 | .@"load atomic", |
| 10070 | 9909 | => |tag| { |
| 10071 | 9910 | 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, }", .{ | |
| 10073 | 9912 | instruction_index.name(&function).fmt(self), |
| 10074 | 9913 | @tagName(tag), |
| 10075 | 9914 | extra.info.access_kind, |
| ... | ... | @@ -10087,14 +9926,14 @@ pub fn printUnbuffered( |
| 10087 | 9926 | const vals = extra.trail.next(block_incoming_len, Value, &function); |
| 10088 | 9927 | const blocks = |
| 10089 | 9928 | extra.trail.next(block_incoming_len, Function.Block.Index, &function); |
| 10090 | try writer.print(" %{} = {s} {%} ", .{ | |
| 9929 | try bw.print(" %{f} = {s} {f%} ", .{ | |
| 10091 | 9930 | instruction_index.name(&function).fmt(self), |
| 10092 | 9931 | @tagName(tag), |
| 10093 | 9932 | vals[0].typeOf(function_index, self).fmt(self), |
| 10094 | 9933 | }); |
| 10095 | 9934 | 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} ]", .{ | |
| 10098 | 9937 | incoming_val.fmt(function_index, self), |
| 10099 | 9938 | incoming_block.toInst(&function).fmt(function_index, self), |
| 10100 | 9939 | }); |
| ... | ... | @@ -10102,19 +9941,19 @@ pub fn printUnbuffered( |
| 10102 | 9941 | }, |
| 10103 | 9942 | .ret => |tag| { |
| 10104 | 9943 | const val: Value = @enumFromInt(instruction.data); |
| 10105 | try writer.print(" {s} {%}", .{ | |
| 9944 | try bw.print(" {s} {f%}", .{ | |
| 10106 | 9945 | @tagName(tag), |
| 10107 | 9946 | val.fmt(function_index, self), |
| 10108 | 9947 | }); |
| 10109 | 9948 | }, |
| 10110 | 9949 | .@"ret void", |
| 10111 | 9950 | .@"unreachable", |
| 10112 | => |tag| try writer.print(" {s}", .{@tagName(tag)}), | |
| 9951 | => |tag| try bw.print(" {s}", .{@tagName(tag)}), | |
| 10113 | 9952 | .select, |
| 10114 | 9953 | .@"select fast", |
| 10115 | 9954 | => |tag| { |
| 10116 | 9955 | const extra = function.extraData(Function.Instruction.Select, instruction.data); |
| 10117 | try writer.print(" %{} = {s} {%}, {%}, {%}", .{ | |
| 9956 | try bw.print(" %{f} = {s} {f%}, {f%}, {f%}", .{ | |
| 10118 | 9957 | instruction_index.name(&function).fmt(self), |
| 10119 | 9958 | @tagName(tag), |
| 10120 | 9959 | extra.cond.fmt(function_index, self), |
| ... | ... | @@ -10125,7 +9964,7 @@ pub fn printUnbuffered( |
| 10125 | 9964 | .shufflevector => |tag| { |
| 10126 | 9965 | const extra = |
| 10127 | 9966 | function.extraData(Function.Instruction.ShuffleVector, instruction.data); |
| 10128 | try writer.print(" %{} = {s} {%}, {%}, {%}", .{ | |
| 9967 | try bw.print(" %{f} = {s} {f%}, {f%}, {f%}", .{ | |
| 10129 | 9968 | instruction_index.name(&function).fmt(self), |
| 10130 | 9969 | @tagName(tag), |
| 10131 | 9970 | extra.lhs.fmt(function_index, self), |
| ... | ... | @@ -10137,7 +9976,7 @@ pub fn printUnbuffered( |
| 10137 | 9976 | .@"store atomic", |
| 10138 | 9977 | => |tag| { |
| 10139 | 9978 | 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, }", .{ | |
| 10141 | 9980 | @tagName(tag), |
| 10142 | 9981 | extra.info.access_kind, |
| 10143 | 9982 | extra.val.fmt(function_index, self), |
| ... | ... | @@ -10153,32 +9992,32 @@ pub fn printUnbuffered( |
| 10153 | 9992 | const vals = extra.trail.next(extra.data.cases_len, Constant, &function); |
| 10154 | 9993 | const blocks = |
| 10155 | 9994 | 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", .{ | |
| 10157 | 9996 | @tagName(tag), |
| 10158 | 9997 | extra.data.val.fmt(function_index, self), |
| 10159 | 9998 | extra.data.default.toInst(&function).fmt(function_index, self), |
| 10160 | 9999 | }); |
| 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", | |
| 10163 | 10002 | .{ |
| 10164 | 10003 | case_val.fmt(self), |
| 10165 | 10004 | case_block.toInst(&function).fmt(function_index, self), |
| 10166 | 10005 | }, |
| 10167 | 10006 | ); |
| 10168 | try writer.writeAll(" ]"); | |
| 10007 | try bw.writeAll(" ]"); | |
| 10169 | 10008 | metadata_formatter.need_comma = true; |
| 10170 | 10009 | defer metadata_formatter.need_comma = undefined; |
| 10171 | 10010 | switch (extra.data.weights) { |
| 10172 | 10011 | .none => {}, |
| 10173 | .unpredictable => try writer.writeAll("!unpredictable !{}"), | |
| 10174 | _ => try writer.print("{}", .{ | |
| 10012 | .unpredictable => try bw.writeAll("!unpredictable !{}"), | |
| 10013 | _ => try bw.print("{f}", .{ | |
| 10175 | 10014 | try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights)))), |
| 10176 | 10015 | }), |
| 10177 | 10016 | } |
| 10178 | 10017 | }, |
| 10179 | 10018 | .va_arg => |tag| { |
| 10180 | 10019 | const extra = function.extraData(Function.Instruction.VaArg, instruction.data); |
| 10181 | try writer.print(" %{} = {s} {%}, {%}", .{ | |
| 10020 | try bw.print(" %{f} = {s} {f%}, {f%}", .{ | |
| 10182 | 10021 | instruction_index.name(&function).fmt(self), |
| 10183 | 10022 | @tagName(tag), |
| 10184 | 10023 | extra.list.fmt(function_index, self), |
| ... | ... | @@ -10188,45 +10027,45 @@ pub fn printUnbuffered( |
| 10188 | 10027 | } |
| 10189 | 10028 | |
| 10190 | 10029 | if (maybe_dbg_index) |dbg_index| { |
| 10191 | try writer.print(", !dbg !{}", .{dbg_index}); | |
| 10030 | try bw.print(", !dbg !{d}", .{dbg_index}); | |
| 10192 | 10031 | } |
| 10193 | try writer.writeByte('\n'); | |
| 10032 | try bw.writeByte('\n'); | |
| 10194 | 10033 | } |
| 10195 | try writer.writeByte('}'); | |
| 10034 | try bw.writeByte('}'); | |
| 10196 | 10035 | } |
| 10197 | try writer.writeByte('\n'); | |
| 10036 | try bw.writeByte('\n'); | |
| 10198 | 10037 | } |
| 10199 | 10038 | |
| 10200 | 10039 | 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; | |
| 10202 | 10041 | 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#"} }} | |
| 10205 | 10044 | \\ |
| 10206 | 10045 | , .{ attribute_group_index, attribute_group.fmt(self) }); |
| 10207 | 10046 | } |
| 10208 | 10047 | |
| 10209 | 10048 | 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; | |
| 10211 | 10050 | for (self.metadata_named.keys(), self.metadata_named.values()) |name, data| { |
| 10212 | 10051 | const elements: []const Metadata = |
| 10213 | 10052 | @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(" = !{"); | |
| 10217 | 10056 | metadata_formatter.need_comma = false; |
| 10218 | 10057 | 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"); | |
| 10221 | 10060 | } |
| 10222 | 10061 | } |
| 10223 | 10062 | |
| 10224 | 10063 | 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; | |
| 10226 | 10065 | var metadata_index: usize = 0; |
| 10227 | 10066 | while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) { |
| 10228 | 10067 | @setEvalBranchQuota(10_000); |
| 10229 | try writer.print("!{} = ", .{metadata_index}); | |
| 10068 | try bw.print("!{d} = ", .{metadata_index}); | |
| 10230 | 10069 | metadata_formatter.need_comma = false; |
| 10231 | 10070 | defer metadata_formatter.need_comma = undefined; |
| 10232 | 10071 | |
| ... | ... | @@ -10239,7 +10078,7 @@ pub fn printUnbuffered( |
| 10239 | 10078 | .scope = location.scope, |
| 10240 | 10079 | .inlinedAt = location.inlined_at, |
| 10241 | 10080 | .isImplicitCode = false, |
| 10242 | }, writer); | |
| 10081 | }, bw); | |
| 10243 | 10082 | continue; |
| 10244 | 10083 | }, |
| 10245 | 10084 | .metadata => |metadata| self.metadata_items.get(@intFromEnum(metadata)), |
| ... | ... | @@ -10255,7 +10094,7 @@ pub fn printUnbuffered( |
| 10255 | 10094 | .checksumkind = null, |
| 10256 | 10095 | .checksum = null, |
| 10257 | 10096 | .source = null, |
| 10258 | }, writer); | |
| 10097 | }, bw); | |
| 10259 | 10098 | }, |
| 10260 | 10099 | .compile_unit, |
| 10261 | 10100 | .@"compile_unit optimized", |
| ... | ... | @@ -10286,7 +10125,7 @@ pub fn printUnbuffered( |
| 10286 | 10125 | .rangesBaseAddress = null, |
| 10287 | 10126 | .sysroot = null, |
| 10288 | 10127 | .sdk = null, |
| 10289 | }, writer); | |
| 10128 | }, bw); | |
| 10290 | 10129 | }, |
| 10291 | 10130 | .subprogram, |
| 10292 | 10131 | .@"subprogram local", |
| ... | ... | @@ -10320,7 +10159,7 @@ pub fn printUnbuffered( |
| 10320 | 10159 | .thrownTypes = null, |
| 10321 | 10160 | .annotations = null, |
| 10322 | 10161 | .targetFuncName = null, |
| 10323 | }, writer); | |
| 10162 | }, bw); | |
| 10324 | 10163 | }, |
| 10325 | 10164 | .lexical_block => { |
| 10326 | 10165 | const extra = self.metadataExtraData(Metadata.LexicalBlock, metadata_item.data); |
| ... | ... | @@ -10329,7 +10168,7 @@ pub fn printUnbuffered( |
| 10329 | 10168 | .file = extra.file, |
| 10330 | 10169 | .line = extra.line, |
| 10331 | 10170 | .column = extra.column, |
| 10332 | }, writer); | |
| 10171 | }, bw); | |
| 10333 | 10172 | }, |
| 10334 | 10173 | .location => { |
| 10335 | 10174 | const extra = self.metadataExtraData(Metadata.Location, metadata_item.data); |
| ... | ... | @@ -10339,7 +10178,7 @@ pub fn printUnbuffered( |
| 10339 | 10178 | .scope = extra.scope, |
| 10340 | 10179 | .inlinedAt = extra.inlined_at, |
| 10341 | 10180 | .isImplicitCode = false, |
| 10342 | }, writer); | |
| 10181 | }, bw); | |
| 10343 | 10182 | }, |
| 10344 | 10183 | .basic_bool_type, |
| 10345 | 10184 | .basic_unsigned_type, |
| ... | ... | @@ -10368,7 +10207,7 @@ pub fn printUnbuffered( |
| 10368 | 10207 | else => unreachable, |
| 10369 | 10208 | }), |
| 10370 | 10209 | .flags = null, |
| 10371 | }, writer); | |
| 10210 | }, bw); | |
| 10372 | 10211 | }, |
| 10373 | 10212 | .composite_struct_type, |
| 10374 | 10213 | .composite_union_type, |
| ... | ... | @@ -10413,7 +10252,7 @@ pub fn printUnbuffered( |
| 10413 | 10252 | .allocated = null, |
| 10414 | 10253 | .rank = null, |
| 10415 | 10254 | .annotations = null, |
| 10416 | }, writer); | |
| 10255 | }, bw); | |
| 10417 | 10256 | }, |
| 10418 | 10257 | .derived_pointer_type, |
| 10419 | 10258 | .derived_member_type, |
| ... | ... | @@ -10446,7 +10285,7 @@ pub fn printUnbuffered( |
| 10446 | 10285 | .extraData = null, |
| 10447 | 10286 | .dwarfAddressSpace = null, |
| 10448 | 10287 | .annotations = null, |
| 10449 | }, writer); | |
| 10288 | }, bw); | |
| 10450 | 10289 | }, |
| 10451 | 10290 | .subroutine_type => { |
| 10452 | 10291 | const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data); |
| ... | ... | @@ -10454,7 +10293,7 @@ pub fn printUnbuffered( |
| 10454 | 10293 | .flags = null, |
| 10455 | 10294 | .cc = null, |
| 10456 | 10295 | .types = extra.types_tuple, |
| 10457 | }, writer); | |
| 10296 | }, bw); | |
| 10458 | 10297 | }, |
| 10459 | 10298 | .enumerator_unsigned, |
| 10460 | 10299 | .enumerator_signed_positive, |
| ... | ... | @@ -10504,7 +10343,7 @@ pub fn printUnbuffered( |
| 10504 | 10343 | => false, |
| 10505 | 10344 | else => unreachable, |
| 10506 | 10345 | }, |
| 10507 | }, writer); | |
| 10346 | }, bw); | |
| 10508 | 10347 | }, |
| 10509 | 10348 | .subrange => { |
| 10510 | 10349 | const extra = self.metadataExtraData(Metadata.Subrange, metadata_item.data); |
| ... | ... | @@ -10513,31 +10352,31 @@ pub fn printUnbuffered( |
| 10513 | 10352 | .lowerBound = extra.lower_bound, |
| 10514 | 10353 | .upperBound = null, |
| 10515 | 10354 | .stride = null, |
| 10516 | }, writer); | |
| 10355 | }, bw); | |
| 10517 | 10356 | }, |
| 10518 | 10357 | .tuple => { |
| 10519 | 10358 | var extra = self.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data); |
| 10520 | 10359 | 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%}", .{ | |
| 10523 | 10362 | .element = try metadata_formatter.fmt("", element), |
| 10524 | 10363 | }); |
| 10525 | try writer.writeAll("}\n"); | |
| 10364 | try bw.writeAll("}\n"); | |
| 10526 | 10365 | }, |
| 10527 | 10366 | .str_tuple => { |
| 10528 | 10367 | var extra = self.metadataExtraDataTrail(Metadata.StrTuple, metadata_item.data); |
| 10529 | 10368 | const elements = extra.trail.next(extra.data.elements_len, Metadata, self); |
| 10530 | try writer.print("!{{{[str]%}", .{ | |
| 10369 | try bw.print("!{{{[str]f%}", .{ | |
| 10531 | 10370 | .str = try metadata_formatter.fmt("", extra.data.str), |
| 10532 | 10371 | }); |
| 10533 | for (elements) |element| try writer.print("{[element]%}", .{ | |
| 10372 | for (elements) |element| try bw.print("{[element]f%}", .{ | |
| 10534 | 10373 | .element = try metadata_formatter.fmt("", element), |
| 10535 | 10374 | }); |
| 10536 | try writer.writeAll("}\n"); | |
| 10375 | try bw.writeAll("}\n"); | |
| 10537 | 10376 | }, |
| 10538 | 10377 | .module_flag => { |
| 10539 | 10378 | 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", .{ | |
| 10541 | 10380 | .behavior = try metadata_formatter.fmt("", extra.behavior), |
| 10542 | 10381 | .name = try metadata_formatter.fmt("", extra.name), |
| 10543 | 10382 | .constant = try metadata_formatter.fmt("", extra.constant), |
| ... | ... | @@ -10555,7 +10394,7 @@ pub fn printUnbuffered( |
| 10555 | 10394 | .flags = null, |
| 10556 | 10395 | .@"align" = null, |
| 10557 | 10396 | .annotations = null, |
| 10558 | }, writer); | |
| 10397 | }, bw); | |
| 10559 | 10398 | }, |
| 10560 | 10399 | .parameter => { |
| 10561 | 10400 | const extra = self.metadataExtraData(Metadata.Parameter, metadata_item.data); |
| ... | ... | @@ -10569,7 +10408,7 @@ pub fn printUnbuffered( |
| 10569 | 10408 | .flags = null, |
| 10570 | 10409 | .@"align" = null, |
| 10571 | 10410 | .annotations = null, |
| 10572 | }, writer); | |
| 10411 | }, bw); | |
| 10573 | 10412 | }, |
| 10574 | 10413 | .global_var, |
| 10575 | 10414 | .@"global_var local", |
| ... | ... | @@ -10592,7 +10431,7 @@ pub fn printUnbuffered( |
| 10592 | 10431 | .templateParams = null, |
| 10593 | 10432 | .@"align" = null, |
| 10594 | 10433 | .annotations = null, |
| 10595 | }, writer); | |
| 10434 | }, bw); | |
| 10596 | 10435 | }, |
| 10597 | 10436 | .global_var_expression => { |
| 10598 | 10437 | const extra = |
| ... | ... | @@ -10600,7 +10439,7 @@ pub fn printUnbuffered( |
| 10600 | 10439 | try metadata_formatter.specialized(.@"!", .DIGlobalVariableExpression, .{ |
| 10601 | 10440 | .@"var" = extra.variable, |
| 10602 | 10441 | .expr = extra.expression, |
| 10603 | }, writer); | |
| 10442 | }, bw); | |
| 10604 | 10443 | }, |
| 10605 | 10444 | } |
| 10606 | 10445 | } |
| ... | ... | @@ -10619,22 +10458,18 @@ fn isValidIdentifier(id: []const u8) bool { |
| 10619 | 10458 | } |
| 10620 | 10459 | |
| 10621 | 10460 | const QuoteBehavior = enum { always_quote, quote_unless_valid_identifier }; |
| 10622 | fn printEscapedString( | |
| 10623 | slice: []const u8, | |
| 10624 | quotes: QuoteBehavior, | |
| 10625 | writer: anytype, | |
| 10626 | ) @TypeOf(writer).Error!void { | |
| 10461 | fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *std.io.BufferedWriter) anyerror!void { | |
| 10627 | 10462 | const need_quotes = switch (quotes) { |
| 10628 | 10463 | .always_quote => true, |
| 10629 | 10464 | .quote_unless_valid_identifier => !isValidIdentifier(slice), |
| 10630 | 10465 | }; |
| 10631 | if (need_quotes) try writer.writeByte('"'); | |
| 10466 | if (need_quotes) try bw.writeByte('"'); | |
| 10632 | 10467 | 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}), | |
| 10636 | 10471 | }; |
| 10637 | if (need_quotes) try writer.writeByte('"'); | |
| 10472 | if (need_quotes) try bw.writeByte('"'); | |
| 10638 | 10473 | } |
| 10639 | 10474 | |
| 10640 | 10475 | fn ensureUnusedGlobalCapacity(self: *Builder, name: StrtabString) Allocator.Error!void { |
| ... | ... | @@ -12019,7 +11854,7 @@ pub fn metadataStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: |
| 12019 | 11854 | } |
| 12020 | 11855 | |
| 12021 | 11856 | pub 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); | |
| 12023 | 11858 | return self.trailingMetadataStringAssumeCapacity(); |
| 12024 | 11859 | } |
| 12025 | 11860 |
lib/std/zig/render.zig+23-13| ... | ... | @@ -77,7 +77,7 @@ const Render = struct { |
| 77 | 77 | |
| 78 | 78 | pub fn renderTree(gpa: Allocator, bw: *std.io.BufferedWriter, tree: Ast, fixups: Fixups) anyerror!void { |
| 79 | 79 | 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); | |
| 81 | 81 | defer auto_indenting_stream.deinit(); |
| 82 | 82 | var r: Render = .{ |
| 83 | 83 | .gpa = gpa, |
| ... | ... | @@ -2135,13 +2135,13 @@ fn renderArrayInit( |
| 2135 | 2135 | const section_exprs = row_exprs[0..section_end]; |
| 2136 | 2136 | |
| 2137 | 2137 | 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); | |
| 2139 | 2139 | defer sub_expr_buffer.deinit(); |
| 2140 | 2140 | |
| 2141 | 2141 | const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1); |
| 2142 | 2142 | defer gpa.free(sub_expr_buffer_starts); |
| 2143 | 2143 | |
| 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); | |
| 2145 | 2145 | defer auto_indenting_stream.deinit(); |
| 2146 | 2146 | var sub_render: Render = .{ |
| 2147 | 2147 | .gpa = r.gpa, |
| ... | ... | @@ -2160,8 +2160,9 @@ fn renderArrayInit( |
| 2160 | 2160 | |
| 2161 | 2161 | if (i + 1 < section_exprs.len) { |
| 2162 | 2162 | 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; | |
| 2165 | 2166 | contains_newline = contains_newline or this_contains_newline; |
| 2166 | 2167 | expr_widths[i] = width; |
| 2167 | 2168 | expr_newlines[i] = this_contains_newline; |
| ... | ... | @@ -2183,8 +2184,9 @@ fn renderArrayInit( |
| 2183 | 2184 | try renderExpression(&sub_render, expr, .comma); |
| 2184 | 2185 | ais.popSpace(); |
| 2185 | 2186 | |
| 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; | |
| 2188 | 2190 | contains_newline = contains_newline or this_contains_newline; |
| 2189 | 2191 | expr_widths[i] = width; |
| 2190 | 2192 | expr_newlines[i] = contains_newline; |
| ... | ... | @@ -2682,7 +2684,7 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: |
| 2682 | 2684 | const tree = r.tree; |
| 2683 | 2685 | const ais = r.ais; |
| 2684 | 2686 | const lexeme = tokenSliceForRender(tree, token_index); |
| 2685 | try ais.writer().writeAll(lexeme); | |
| 2687 | try ais.writeAll(lexeme); | |
| 2686 | 2688 | ais.enableSpaceMode(override_space); |
| 2687 | 2689 | defer ais.disableSpaceMode(); |
| 2688 | 2690 | 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 |
| 3259 | 3261 | const AutoIndentingStream = struct { |
| 3260 | 3262 | underlying_writer: *std.io.BufferedWriter, |
| 3261 | 3263 | |
| 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 | ||
| 3262 | 3272 | indent_count: usize = 0, |
| 3263 | 3273 | indent_delta: usize, |
| 3264 | 3274 | indent_stack: std.ArrayList(StackElem), |
| ... | ... | @@ -3284,12 +3294,12 @@ const AutoIndentingStream = struct { |
| 3284 | 3294 | indent_count: usize, |
| 3285 | 3295 | }; |
| 3286 | 3296 | |
| 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 { | |
| 3288 | 3298 | return .{ |
| 3289 | .underlying_writer = buffer.writer(), | |
| 3299 | .underlying_writer = bw, | |
| 3290 | 3300 | .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), | |
| 3293 | 3303 | }; |
| 3294 | 3304 | } |
| 3295 | 3305 | |
| ... | ... | @@ -3477,7 +3487,7 @@ const AutoIndentingStream = struct { |
| 3477 | 3487 | const current_indent = ais.currentIndent(); |
| 3478 | 3488 | if (ais.current_line_empty and current_indent > 0) { |
| 3479 | 3489 | if (ais.disabled_offset == null) { |
| 3480 | try ais.underlying_writer.writeByteNTimes(' ', current_indent); | |
| 3490 | try ais.underlying_writer.splatByteAll(' ', current_indent); | |
| 3481 | 3491 | } |
| 3482 | 3492 | ais.applied_indent = current_indent; |
| 3483 | 3493 | } |
lib/std/zig/string_literal.zig+16-22| ... | ... | @@ -44,50 +44,44 @@ pub const Error = union(enum) { |
| 44 | 44 | raw_string: []const u8, |
| 45 | 45 | }; |
| 46 | 46 | |
| 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 { | |
| 53 | 48 | _ = f; |
| 54 | _ = options; | |
| 55 | 49 | switch (self.err) { |
| 56 | .invalid_escape_character => |bad_index| try writer.print( | |
| 50 | .invalid_escape_character => |bad_index| try bw.print( | |
| 57 | 51 | "invalid escape character: '{c}'", |
| 58 | 52 | .{self.raw_string[bad_index]}, |
| 59 | 53 | ), |
| 60 | .expected_hex_digit => |bad_index| try writer.print( | |
| 54 | .expected_hex_digit => |bad_index| try bw.print( | |
| 61 | 55 | "expected hex digit, found '{c}'", |
| 62 | 56 | .{self.raw_string[bad_index]}, |
| 63 | 57 | ), |
| 64 | .empty_unicode_escape_sequence => try writer.writeAll( | |
| 58 | .empty_unicode_escape_sequence => try bw.writeAll( | |
| 65 | 59 | "empty unicode escape sequence", |
| 66 | 60 | ), |
| 67 | .expected_hex_digit_or_rbrace => |bad_index| try writer.print( | |
| 61 | .expected_hex_digit_or_rbrace => |bad_index| try bw.print( | |
| 68 | 62 | "expected hex digit or '}}', found '{c}'", |
| 69 | 63 | .{self.raw_string[bad_index]}, |
| 70 | 64 | ), |
| 71 | .invalid_unicode_codepoint => try writer.writeAll( | |
| 65 | .invalid_unicode_codepoint => try bw.writeAll( | |
| 72 | 66 | "unicode escape does not correspond to a valid unicode scalar value", |
| 73 | 67 | ), |
| 74 | .expected_lbrace => |bad_index| try writer.print( | |
| 68 | .expected_lbrace => |bad_index| try bw.print( | |
| 75 | 69 | "expected '{{', found '{c}'", |
| 76 | 70 | .{self.raw_string[bad_index]}, |
| 77 | 71 | ), |
| 78 | .expected_rbrace => |bad_index| try writer.print( | |
| 72 | .expected_rbrace => |bad_index| try bw.print( | |
| 79 | 73 | "expected '}}', found '{c}'", |
| 80 | 74 | .{self.raw_string[bad_index]}, |
| 81 | 75 | ), |
| 82 | .expected_single_quote => |bad_index| try writer.print( | |
| 76 | .expected_single_quote => |bad_index| try bw.print( | |
| 83 | 77 | "expected single quote ('), found '{c}'", |
| 84 | 78 | .{self.raw_string[bad_index]}, |
| 85 | 79 | ), |
| 86 | .invalid_character => |bad_index| try writer.print( | |
| 80 | .invalid_character => |bad_index| try bw.print( | |
| 87 | 81 | "invalid byte in string or character literal: '{c}'", |
| 88 | 82 | .{self.raw_string[bad_index]}, |
| 89 | 83 | ), |
| 90 | .empty_char_literal => try writer.writeAll( | |
| 84 | .empty_char_literal => try bw.writeAll( | |
| 91 | 85 | "empty character literal", |
| 92 | 86 | ), |
| 93 | 87 | } |
| ... | ... | @@ -363,13 +357,13 @@ pub fn parseWrite(writer: *std.io.BufferedWriter, bytes: []const u8) anyerror!Re |
| 363 | 357 | /// Higher level API. Does not return extra info about parse errors. |
| 364 | 358 | /// Caller owns returned memory. |
| 365 | 359 | pub 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(); | |
| 369 | 363 | // 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); | |
| 371 | 365 | switch (result) { |
| 372 | .success => return buf.toOwnedSlice(), | |
| 366 | .success => return aw.toOwnedSlice(), | |
| 373 | 367 | .failure => return error.InvalidLiteral, |
| 374 | 368 | } |
| 375 | 369 | } |
lib/std/zon/stringify.zig+5-5| ... | ... | @@ -583,7 +583,7 @@ pub const Serializer = struct { |
| 583 | 583 | |
| 584 | 584 | /// Serialize an integer. |
| 585 | 585 | 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, .{}); | |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | 589 | /// Serialize a float. |
| ... | ... | @@ -613,7 +613,7 @@ pub const Serializer = struct { |
| 613 | 613 | /// |
| 614 | 614 | /// Escapes the identifier if necessary. |
| 615 | 615 | 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)}); | |
| 617 | 617 | } |
| 618 | 618 | |
| 619 | 619 | /// Serialize `val` as a Unicode codepoint. |
| ... | ... | @@ -626,7 +626,7 @@ pub const Serializer = struct { |
| 626 | 626 | var buf: [8]u8 = undefined; |
| 627 | 627 | const len = std.unicode.utf8Encode(val, &buf) catch return error.InvalidCodepoint; |
| 628 | 628 | 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)}); | |
| 630 | 630 | } |
| 631 | 631 | |
| 632 | 632 | /// Like `value`, but always serializes `val` as a tuple. |
| ... | ... | @@ -684,7 +684,7 @@ pub const Serializer = struct { |
| 684 | 684 | |
| 685 | 685 | /// Like `value`, but always serializes `val` as a string. |
| 686 | 686 | 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)}); | |
| 688 | 688 | } |
| 689 | 689 | |
| 690 | 690 | /// Options for formatting multiline strings. |
| ... | ... | @@ -758,7 +758,7 @@ pub const Serializer = struct { |
| 758 | 758 | |
| 759 | 759 | fn indent(self: *Serializer) anyerror!void { |
| 760 | 760 | if (self.options.whitespace) { |
| 761 | try self.writer.writeByteNTimes(' ', 4 * self.indent_level); | |
| 761 | try self.writer.splatByteAll(' ', 4 * self.indent_level); | |
| 762 | 762 | } |
| 763 | 763 | } |
| 764 | 764 |
src/Air.zig+4-9| ... | ... | @@ -957,18 +957,13 @@ pub const Inst = struct { |
| 957 | 957 | return index.unwrap().target; |
| 958 | 958 | } |
| 959 | 959 | |
| 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('%'); | |
| 967 | 962 | switch (index.unwrap()) { |
| 968 | 963 | .ref => {}, |
| 969 | .target => try writer.writeByte('t'), | |
| 964 | .target => try bw.writeByte('t'), | |
| 970 | 965 | } |
| 971 | try writer.print("{d}", .{@as(u31, @truncate(@intFromEnum(index)))}); | |
| 966 | try bw.print("{d}", .{@as(u31, @truncate(@intFromEnum(index)))}); | |
| 972 | 967 | } |
| 973 | 968 | }; |
| 974 | 969 |
src/Air/Liveness.zig+25-25| ... | ... | @@ -1323,7 +1323,7 @@ fn analyzeOperands( |
| 1323 | 1323 | const mask = @as(Bpi, 1) << @as(OperandInt, @intCast(i)); |
| 1324 | 1324 | |
| 1325 | 1325 | 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 }); | |
| 1327 | 1327 | tomb_bits |= mask; |
| 1328 | 1328 | } |
| 1329 | 1329 | } |
| ... | ... | @@ -1462,19 +1462,19 @@ fn analyzeInstBlock( |
| 1462 | 1462 | }, |
| 1463 | 1463 | |
| 1464 | 1464 | .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) }); | |
| 1466 | 1466 | // We can move the live set because the body should have a noreturn |
| 1467 | 1467 | // instruction which overrides the set. |
| 1468 | 1468 | try data.block_scopes.put(gpa, inst, .{ |
| 1469 | 1469 | .live_set = data.live_set.move(), |
| 1470 | 1470 | }); |
| 1471 | 1471 | defer { |
| 1472 | log.debug("[{}] %{}: popped block scope", .{ pass, inst }); | |
| 1472 | log.debug("[{}] %{f}: popped block scope", .{ pass, inst }); | |
| 1473 | 1473 | var scope = data.block_scopes.fetchRemove(inst).?.value; |
| 1474 | 1474 | scope.live_set.deinit(gpa); |
| 1475 | 1475 | } |
| 1476 | 1476 | |
| 1477 | log.debug("[{}] %{}: pushed new block scope", .{ pass, inst }); | |
| 1477 | log.debug("[{}] %{f}: pushed new block scope", .{ pass, inst }); | |
| 1478 | 1478 | try analyzeBody(a, pass, data, body); |
| 1479 | 1479 | |
| 1480 | 1480 | // If the block is noreturn, block deaths not only aren't useful, they're impossible to |
| ... | ... | @@ -1501,7 +1501,7 @@ fn analyzeInstBlock( |
| 1501 | 1501 | } |
| 1502 | 1502 | assert(measured_num == num_deaths); // post-live-set should be a subset of pre-live-set |
| 1503 | 1503 | try a.special.put(gpa, inst, extra_index); |
| 1504 | log.debug("[{}] %{}: block deaths are {}", .{ | |
| 1504 | log.debug("[{}] %{f}: block deaths are {f}", .{ | |
| 1505 | 1505 | pass, |
| 1506 | 1506 | inst, |
| 1507 | 1507 | fmtInstList(@ptrCast(a.extra.items[extra_index + 1 ..][0..num_deaths])), |
| ... | ... | @@ -1538,7 +1538,7 @@ fn writeLoopInfo( |
| 1538 | 1538 | const block_inst = key.*; |
| 1539 | 1539 | a.extra.appendAssumeCapacity(@intFromEnum(block_inst)); |
| 1540 | 1540 | } |
| 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) }); | |
| 1542 | 1542 | |
| 1543 | 1543 | // Now we put the live operands from the loop body in too |
| 1544 | 1544 | const num_live = data.live_set.count(); |
| ... | ... | @@ -1550,7 +1550,7 @@ fn writeLoopInfo( |
| 1550 | 1550 | const alive = key.*; |
| 1551 | 1551 | a.extra.appendAssumeCapacity(@intFromEnum(alive)); |
| 1552 | 1552 | } |
| 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) }); | |
| 1554 | 1554 | |
| 1555 | 1555 | try a.special.put(gpa, inst, extra_index); |
| 1556 | 1556 | |
| ... | ... | @@ -1591,7 +1591,7 @@ fn resolveLoopLiveSet( |
| 1591 | 1591 | try data.live_set.ensureUnusedCapacity(gpa, @intCast(loop_live.len)); |
| 1592 | 1592 | for (loop_live) |alive| data.live_set.putAssumeCapacity(alive, {}); |
| 1593 | 1593 | |
| 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) }); | |
| 1595 | 1595 | |
| 1596 | 1596 | for (breaks) |block_inst| { |
| 1597 | 1597 | // We might break to this block, so include every operand that the block needs alive |
| ... | ... | @@ -1604,7 +1604,7 @@ fn resolveLoopLiveSet( |
| 1604 | 1604 | } |
| 1605 | 1605 | } |
| 1606 | 1606 | |
| 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) }); | |
| 1608 | 1608 | } |
| 1609 | 1609 | |
| 1610 | 1610 | fn analyzeInstLoop( |
| ... | ... | @@ -1642,7 +1642,7 @@ fn analyzeInstLoop( |
| 1642 | 1642 | .live_set = data.live_set.move(), |
| 1643 | 1643 | }); |
| 1644 | 1644 | defer { |
| 1645 | log.debug("[{}] %{}: popped loop block scop", .{ pass, inst }); | |
| 1645 | log.debug("[{}] %{f}: popped loop block scop", .{ pass, inst }); | |
| 1646 | 1646 | var scope = data.block_scopes.fetchRemove(inst).?.value; |
| 1647 | 1647 | scope.live_set.deinit(gpa); |
| 1648 | 1648 | } |
| ... | ... | @@ -1743,13 +1743,13 @@ fn analyzeInstCondBr( |
| 1743 | 1743 | } |
| 1744 | 1744 | } |
| 1745 | 1745 | |
| 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) }); | |
| 1748 | 1748 | |
| 1749 | 1749 | data.live_set.deinit(gpa); |
| 1750 | 1750 | data.live_set = then_live.move(); // Really the union of both live sets |
| 1751 | 1751 | |
| 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) }); | |
| 1753 | 1753 | |
| 1754 | 1754 | // Write the mirrored deaths to `extra` |
| 1755 | 1755 | const then_death_count = @as(u32, @intCast(then_mirrored_deaths.items.len)); |
| ... | ... | @@ -1817,7 +1817,7 @@ fn analyzeInstSwitchBr( |
| 1817 | 1817 | }); |
| 1818 | 1818 | } |
| 1819 | 1819 | defer if (is_dispatch_loop) { |
| 1820 | log.debug("[{}] %{}: popped loop block scop", .{ pass, inst }); | |
| 1820 | log.debug("[{}] %{f}: popped loop block scop", .{ pass, inst }); | |
| 1821 | 1821 | var scope = data.block_scopes.fetchRemove(inst).?.value; |
| 1822 | 1822 | scope.live_set.deinit(gpa); |
| 1823 | 1823 | }; |
| ... | ... | @@ -1875,13 +1875,13 @@ fn analyzeInstSwitchBr( |
| 1875 | 1875 | } |
| 1876 | 1876 | |
| 1877 | 1877 | 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) }); | |
| 1879 | 1879 | } |
| 1880 | 1880 | |
| 1881 | 1881 | data.live_set.deinit(gpa); |
| 1882 | 1882 | data.live_set = all_alive.move(); |
| 1883 | 1883 | |
| 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) }); | |
| 1885 | 1885 | } |
| 1886 | 1886 | |
| 1887 | 1887 | const else_death_count = @as(u32, @intCast(mirrored_deaths[ncases].items.len)); |
| ... | ... | @@ -1980,7 +1980,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type { |
| 1980 | 1980 | |
| 1981 | 1981 | .main_analysis => { |
| 1982 | 1982 | 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 }); | |
| 1984 | 1984 | big.extra_tombs[extra_byte] |= @as(u32, 1) << extra_bit; |
| 1985 | 1985 | } |
| 1986 | 1986 | }, |
| ... | ... | @@ -2036,15 +2036,15 @@ fn fmtInstSet(set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void)) FmtIns |
| 2036 | 2036 | const FmtInstSet = struct { |
| 2037 | 2037 | set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void), |
| 2038 | 2038 | |
| 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 { | |
| 2040 | 2040 | if (val.set.count() == 0) { |
| 2041 | try w.writeAll("[no instructions]"); | |
| 2041 | try bw.writeAll("[no instructions]"); | |
| 2042 | 2042 | return; |
| 2043 | 2043 | } |
| 2044 | 2044 | var it = val.set.keyIterator(); |
| 2045 | try w.print("%{}", .{it.next().?.*}); | |
| 2045 | try bw.print("%{f}", .{it.next().?.*}); | |
| 2046 | 2046 | while (it.next()) |key| { |
| 2047 | try w.print(" %{}", .{key.*}); | |
| 2047 | try bw.print(" %{f}", .{key.*}); | |
| 2048 | 2048 | } |
| 2049 | 2049 | } |
| 2050 | 2050 | }; |
| ... | ... | @@ -2056,14 +2056,14 @@ fn fmtInstList(list: []const Air.Inst.Index) FmtInstList { |
| 2056 | 2056 | const FmtInstList = struct { |
| 2057 | 2057 | list: []const Air.Inst.Index, |
| 2058 | 2058 | |
| 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 { | |
| 2060 | 2060 | if (val.list.len == 0) { |
| 2061 | try w.writeAll("[no instructions]"); | |
| 2061 | try bw.writeAll("[no instructions]"); | |
| 2062 | 2062 | return; |
| 2063 | 2063 | } |
| 2064 | try w.print("%{}", .{val.list[0]}); | |
| 2064 | try bw.print("%{f}", .{val.list[0]}); | |
| 2065 | 2065 | for (val.list[1..]) |inst| { |
| 2066 | try w.print(" %{}", .{inst}); | |
| 2066 | try bw.print(" %{f}", .{inst}); | |
| 2067 | 2067 | } |
| 2068 | 2068 | } |
| 2069 | 2069 | }; |
src/Air/Liveness/Verify.zig+8-8| ... | ... | @@ -73,7 +73,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 73 | 73 | .trap, .unreach => { |
| 74 | 74 | try self.verifyInstOperands(inst, .{ .none, .none, .none }); |
| 75 | 75 | // 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}); | |
| 77 | 77 | }, |
| 78 | 78 | |
| 79 | 79 | // unary |
| ... | ... | @@ -166,7 +166,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 166 | 166 | const un_op = data[@intFromEnum(inst)].un_op; |
| 167 | 167 | try self.verifyInstOperands(inst, .{ un_op, .none, .none }); |
| 168 | 168 | // 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}); | |
| 170 | 170 | }, |
| 171 | 171 | .dbg_var_ptr, |
| 172 | 172 | .dbg_var_val, |
| ... | ... | @@ -450,7 +450,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 450 | 450 | .repeat => { |
| 451 | 451 | const repeat = data[@intFromEnum(inst)].repeat; |
| 452 | 452 | 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) }); | |
| 454 | 454 | |
| 455 | 455 | try self.verifyMatchingLiveness(repeat.loop_inst, expected_live); |
| 456 | 456 | }, |
| ... | ... | @@ -460,7 +460,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 460 | 460 | try self.verifyOperand(inst, br.operand, self.liveness.operandDies(inst, 0)); |
| 461 | 461 | |
| 462 | 462 | 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) }); | |
| 464 | 464 | |
| 465 | 465 | try self.verifyMatchingLiveness(br.block_inst, expected_live); |
| 466 | 466 | }, |
| ... | ... | @@ -601,9 +601,9 @@ fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies |
| 601 | 601 | return; |
| 602 | 602 | }; |
| 603 | 603 | 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 }); | |
| 605 | 605 | } 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 }); | |
| 607 | 607 | } |
| 608 | 608 | } |
| 609 | 609 | |
| ... | ... | @@ -628,9 +628,9 @@ fn verifyInst(self: *Verify, inst: Air.Inst.Index) Error!void { |
| 628 | 628 | } |
| 629 | 629 | |
| 630 | 630 | fn 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}); | |
| 632 | 632 | 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}); | |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | fn invalid(comptime fmt: []const u8, args: anytype) error{LivenessInvalid} { |
src/Air/print.zig+14-14| ... | ... | @@ -101,7 +101,7 @@ const Writer = struct { |
| 101 | 101 | fn writeInst(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) anyerror!void { |
| 102 | 102 | const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 103 | 103 | try s.splatByteAll(' ', w.indent); |
| 104 | try s.print("{}{c}= {s}(", .{ | |
| 104 | try s.print("{f}{c}= {s}(", .{ | |
| 105 | 105 | inst, |
| 106 | 106 | @as(u8, if (if (w.liveness) |liveness| liveness.isUnused(inst) else false) '!' else ' '), |
| 107 | 107 | @tagName(tag), |
| ... | ... | @@ -416,7 +416,7 @@ const Writer = struct { |
| 416 | 416 | try s.writeAll("}"); |
| 417 | 417 | |
| 418 | 418 | for (liveness_block.deaths) |operand| { |
| 419 | try s.print(" {}!", .{operand}); | |
| 419 | try s.print(" {f}!", .{operand}); | |
| 420 | 420 | } |
| 421 | 421 | } |
| 422 | 422 | |
| ... | ... | @@ -708,7 +708,7 @@ const Writer = struct { |
| 708 | 708 | } |
| 709 | 709 | } |
| 710 | 710 | 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)}); | |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | 714 | fn writeDbgStmt(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) anyerror!void { |
| ... | ... | @@ -720,7 +720,7 @@ const Writer = struct { |
| 720 | 720 | const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 721 | 721 | try w.writeOperand(s, inst, 0, pl_op.operand); |
| 722 | 722 | 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))}); | |
| 724 | 724 | } |
| 725 | 725 | |
| 726 | 726 | fn writeCall(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) anyerror!void { |
| ... | ... | @@ -767,7 +767,7 @@ const Writer = struct { |
| 767 | 767 | try s.splatByteAll(' ', w.indent); |
| 768 | 768 | for (liveness_condbr.else_deaths, 0..) |operand, i| { |
| 769 | 769 | if (i != 0) try s.writeAll(" "); |
| 770 | try s.print("{}!", .{operand}); | |
| 770 | try s.print("{f}!", .{operand}); | |
| 771 | 771 | } |
| 772 | 772 | try s.writeAll("\n"); |
| 773 | 773 | } |
| ... | ... | @@ -778,7 +778,7 @@ const Writer = struct { |
| 778 | 778 | try s.writeAll("}"); |
| 779 | 779 | |
| 780 | 780 | for (liveness_condbr.then_deaths) |operand| { |
| 781 | try s.print(" {}!", .{operand}); | |
| 781 | try s.print(" {f}!", .{operand}); | |
| 782 | 782 | } |
| 783 | 783 | } |
| 784 | 784 | |
| ... | ... | @@ -804,7 +804,7 @@ const Writer = struct { |
| 804 | 804 | try s.splatByteAll(' ', w.indent); |
| 805 | 805 | for (liveness_condbr.else_deaths, 0..) |operand, i| { |
| 806 | 806 | if (i != 0) try s.writeAll(" "); |
| 807 | try s.print("{}!", .{operand}); | |
| 807 | try s.print("{f}!", .{operand}); | |
| 808 | 808 | } |
| 809 | 809 | try s.writeAll("\n"); |
| 810 | 810 | } |
| ... | ... | @@ -815,7 +815,7 @@ const Writer = struct { |
| 815 | 815 | try s.writeAll("}"); |
| 816 | 816 | |
| 817 | 817 | for (liveness_condbr.then_deaths) |operand| { |
| 818 | try s.print(" {}!", .{operand}); | |
| 818 | try s.print(" {f}!", .{operand}); | |
| 819 | 819 | } |
| 820 | 820 | } |
| 821 | 821 | |
| ... | ... | @@ -846,7 +846,7 @@ const Writer = struct { |
| 846 | 846 | try s.splatByteAll(' ', w.indent); |
| 847 | 847 | for (liveness_condbr.then_deaths, 0..) |operand, i| { |
| 848 | 848 | if (i != 0) try s.writeAll(" "); |
| 849 | try s.print("{}!", .{operand}); | |
| 849 | try s.print("{f}!", .{operand}); | |
| 850 | 850 | } |
| 851 | 851 | try s.writeAll("\n"); |
| 852 | 852 | } |
| ... | ... | @@ -866,7 +866,7 @@ const Writer = struct { |
| 866 | 866 | try s.splatByteAll(' ', w.indent); |
| 867 | 867 | for (liveness_condbr.else_deaths, 0..) |operand, i| { |
| 868 | 868 | if (i != 0) try s.writeAll(" "); |
| 869 | try s.print("{}!", .{operand}); | |
| 869 | try s.print("{f}!", .{operand}); | |
| 870 | 870 | } |
| 871 | 871 | try s.writeAll("\n"); |
| 872 | 872 | } |
| ... | ... | @@ -923,7 +923,7 @@ const Writer = struct { |
| 923 | 923 | try s.splatByteAll(' ', w.indent); |
| 924 | 924 | for (deaths, 0..) |operand, i| { |
| 925 | 925 | if (i != 0) try s.writeAll(" "); |
| 926 | try s.print("{}!", .{operand}); | |
| 926 | try s.print("{f}!", .{operand}); | |
| 927 | 927 | } |
| 928 | 928 | try s.writeAll("\n"); |
| 929 | 929 | } |
| ... | ... | @@ -949,7 +949,7 @@ const Writer = struct { |
| 949 | 949 | try s.splatByteAll(' ', w.indent); |
| 950 | 950 | for (deaths, 0..) |operand, i| { |
| 951 | 951 | if (i != 0) try s.writeAll(" "); |
| 952 | try s.print("{}!", .{operand}); | |
| 952 | try s.print("{f}!", .{operand}); | |
| 953 | 953 | } |
| 954 | 954 | try s.writeAll("\n"); |
| 955 | 955 | } |
| ... | ... | @@ -1017,7 +1017,7 @@ const Writer = struct { |
| 1017 | 1017 | } else if (operand.toInterned()) |ip_index| { |
| 1018 | 1018 | const pt = w.pt; |
| 1019 | 1019 | const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf()); |
| 1020 | try s.print("<{}, {}>", .{ | |
| 1020 | try s.print("<{f}, {f}>", .{ | |
| 1021 | 1021 | ty.fmt(pt), |
| 1022 | 1022 | Value.fromInterned(ip_index).fmtValue(pt), |
| 1023 | 1023 | }); |
| ... | ... | @@ -1033,7 +1033,7 @@ const Writer = struct { |
| 1033 | 1033 | dies: bool, |
| 1034 | 1034 | ) anyerror!void { |
| 1035 | 1035 | _ = w; |
| 1036 | try s.print("{}", .{inst}); | |
| 1036 | try s.print("{f}", .{inst}); | |
| 1037 | 1037 | if (dies) try s.writeByte('!'); |
| 1038 | 1038 | } |
| 1039 | 1039 |
src/Builtin.zig+17-17| ... | ... | @@ -57,18 +57,18 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 57 | 57 | \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks. |
| 58 | 58 | \\pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable; |
| 59 | 59 | \\pub const zig_version_string = "{s}"; |
| 60 | \\pub const zig_backend = std.builtin.CompilerBackend.{p_}; | |
| 60 | \\pub const zig_backend = std.builtin.CompilerBackend.{fp_}; | |
| 61 | 61 | \\ |
| 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_}; | |
| 65 | 65 | \\pub const is_test = {}; |
| 66 | 66 | \\pub const single_threaded = {}; |
| 67 | \\pub const abi: std.Target.Abi = .{p_}; | |
| 67 | \\pub const abi: std.Target.Abi = .{fp_}; | |
| 68 | 68 | \\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(&.{{ | |
| 72 | 72 | \\ |
| 73 | 73 | , .{ |
| 74 | 74 | build_options.version, |
| ... | ... | @@ -89,14 +89,14 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 89 | 89 | const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize)); |
| 90 | 90 | const is_enabled = target.cpu.features.isEnabled(index); |
| 91 | 91 | 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)}); | |
| 93 | 93 | } |
| 94 | 94 | } |
| 95 | 95 | try buffer.print( |
| 96 | 96 | \\ }}), |
| 97 | 97 | \\}}; |
| 98 | 98 | \\pub const os: std.Target.Os = .{{ |
| 99 | \\ .tag = .{p_}, | |
| 99 | \\ .tag = .{fp_}, | |
| 100 | 100 | \\ .version_range = .{{ |
| 101 | 101 | , |
| 102 | 102 | .{std.zig.fmtId(@tagName(target.os.tag))}, |
| ... | ... | @@ -200,8 +200,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 200 | 200 | }), |
| 201 | 201 | .windows => |windows| try buffer.print( |
| 202 | 202 | \\ .windows = .{{ |
| 203 | \\ .min = {c}, | |
| 204 | \\ .max = {c}, | |
| 203 | \\ .min = {fc}, | |
| 204 | \\ .max = {fc}, | |
| 205 | 205 | \\ }}}}, |
| 206 | 206 | \\ |
| 207 | 207 | , .{ windows.min, windows.max }), |
| ... | ... | @@ -238,8 +238,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 238 | 238 | const link_libc = opts.link_libc; |
| 239 | 239 | |
| 240 | 240 | 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_}; | |
| 243 | 243 | \\pub const link_libc = {}; |
| 244 | 244 | \\pub const link_libcpp = {}; |
| 245 | 245 | \\pub const have_error_return_tracing = {}; |
| ... | ... | @@ -249,7 +249,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 249 | 249 | \\pub const position_independent_code = {}; |
| 250 | 250 | \\pub const position_independent_executable = {}; |
| 251 | 251 | \\pub const strip_debug_info = {}; |
| 252 | \\pub const code_model: std.builtin.CodeModel = .{p_}; | |
| 252 | \\pub const code_model: std.builtin.CodeModel = .{fp_}; | |
| 253 | 253 | \\pub const omit_frame_pointer = {}; |
| 254 | 254 | \\ |
| 255 | 255 | , .{ |
| ... | ... | @@ -270,7 +270,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 270 | 270 | |
| 271 | 271 | if (target.os.tag == .wasi) { |
| 272 | 272 | try buffer.print( |
| 273 | \\pub const wasi_exec_model: std.builtin.WasiExecModel = .{p_}; | |
| 273 | \\pub const wasi_exec_model: std.builtin.WasiExecModel = .{fp_}; | |
| 274 | 274 | \\ |
| 275 | 275 | , .{std.zig.fmtId(@tagName(opts.wasi_exec_model))}); |
| 276 | 276 | } |
| ... | ... | @@ -317,7 +317,7 @@ pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { |
| 317 | 317 | if (root_dir.statFile(sub_path)) |stat| { |
| 318 | 318 | if (stat.size != file.source.?.len) { |
| 319 | 319 | 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}. " ++ | |
| 321 | 321 | "Overwriting with correct file contents now", |
| 322 | 322 | .{ file.path.fmt(comp), file.source.?.len, stat.size }, |
| 323 | 323 | ); |
src/Compilation.zig+20-23| ... | ... | @@ -1068,11 +1068,12 @@ pub const CObject = struct { |
| 1068 | 1068 | } |
| 1069 | 1069 | }; |
| 1070 | 1070 | |
| 1071 | var buffer: [1024]u8 = undefined; | |
| 1071 | 1072 | const file = try std.fs.cwd().openFile(path, .{}); |
| 1072 | 1073 | 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 }); | |
| 1076 | 1077 | defer bc.deinit(); |
| 1077 | 1078 | |
| 1078 | 1079 | 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 { |
| 2709 | 2710 | const prefix = man.cache.prefixes()[pp.prefix]; |
| 2710 | 2711 | return comp.setMiscFailure( |
| 2711 | 2712 | .check_whole_cache, |
| 2712 | "failed to check cache: '{}{s}' {s} {s}", | |
| 2713 | "failed to check cache: '{f}{s}' {s} {s}", | |
| 2713 | 2714 | .{ prefix, pp.sub_path, @tagName(man.diagnostic), @errorName(op.err) }, |
| 2714 | 2715 | ); |
| 2715 | 2716 | }, |
| ... | ... | @@ -2926,7 +2927,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2926 | 2927 | renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| { |
| 2927 | 2928 | return comp.setMiscFailure( |
| 2928 | 2929 | .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}", | |
| 2930 | 2931 | .{ |
| 2931 | 2932 | comp.dirs.local_cache, tmp_dir_sub_path, |
| 2932 | 2933 | comp.dirs.local_cache, o_sub_path, |
| ... | ... | @@ -4847,7 +4848,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4847 | 4848 | var out_dir = docs_path.root_dir.handle.makeOpenPath(docs_path.sub_path, .{}) catch |err| { |
| 4848 | 4849 | return comp.lockAndSetMiscFailure( |
| 4849 | 4850 | .docs_copy, |
| 4850 | "unable to create output directory '{}': {s}", | |
| 4851 | "unable to create output directory '{f}': {s}", | |
| 4851 | 4852 | .{ docs_path, @errorName(err) }, |
| 4852 | 4853 | ); |
| 4853 | 4854 | }; |
| ... | ... | @@ -4867,7 +4868,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4867 | 4868 | var tar_file = out_dir.createFile("sources.tar", .{}) catch |err| { |
| 4868 | 4869 | return comp.lockAndSetMiscFailure( |
| 4869 | 4870 | .docs_copy, |
| 4870 | "unable to create '{}/sources.tar': {s}", | |
| 4871 | "unable to create '{f}/sources.tar': {s}", | |
| 4871 | 4872 | .{ docs_path, @errorName(err) }, |
| 4872 | 4873 | ); |
| 4873 | 4874 | }; |
| ... | ... | @@ -4896,7 +4897,7 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, |
| 4896 | 4897 | const root_dir, const sub_path = root.openInfo(comp.dirs); |
| 4897 | 4898 | break :d root_dir.openDir(sub_path, .{ .iterate = true }); |
| 4898 | 4899 | } 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}", .{ | |
| 4900 | 4901 | root.fmt(comp), @errorName(err), |
| 4901 | 4902 | }); |
| 4902 | 4903 | }; |
| ... | ... | @@ -5142,7 +5143,7 @@ fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void { |
| 5142 | 5143 | defer comp.mutex.unlock(); |
| 5143 | 5144 | comp.setMiscFailure( |
| 5144 | 5145 | .write_builtin_zig, |
| 5145 | "unable to write '{}': {s}", | |
| 5146 | "unable to write '{f}': {s}", | |
| 5146 | 5147 | .{ file.path.fmt(comp), @errorName(err) }, |
| 5147 | 5148 | ); |
| 5148 | 5149 | }; |
| ... | ... | @@ -5863,7 +5864,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5863 | 5864 | |
| 5864 | 5865 | try child.spawn(); |
| 5865 | 5866 | |
| 5866 | const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize)); | |
| 5867 | const stderr = try child.stderr.?.readToEndAlloc(arena, .unlimited); | |
| 5867 | 5868 | |
| 5868 | 5869 | const term = child.wait() catch |err| { |
| 5869 | 5870 | 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 |
| 6023 | 6024 | |
| 6024 | 6025 | // In .rc files, a " within a quoted string is escaped as "" |
| 6025 | 6026 | 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 { | |
| 6027 | 6028 | _ = fmt; |
| 6028 | _ = options; | |
| 6029 | 6029 | 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), | |
| 6033 | 6033 | }; |
| 6034 | 6034 | } |
| 6035 | 6035 | |
| ... | ... | @@ -6047,7 +6047,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6047 | 6047 | // 24 is RT_MANIFEST |
| 6048 | 6048 | const resource_type = 24; |
| 6049 | 6049 | |
| 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) }); | |
| 6051 | 6051 | |
| 6052 | 6052 | try o_dir.writeFile(.{ .sub_path = rc_basename, .data = input }); |
| 6053 | 6053 | |
| ... | ... | @@ -6227,13 +6227,10 @@ fn spawnZigRc( |
| 6227 | 6227 | const stdout = poller.fifo(.stdout); |
| 6228 | 6228 | |
| 6229 | 6229 | 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; | |
| 6237 | 6234 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 6238 | 6235 | |
| 6239 | 6236 | switch (header.tag) { |
src/InternPool.zig+6-11| ... | ... | @@ -1888,17 +1888,12 @@ pub const NullTerminatedString = enum(u32) { |
| 1888 | 1888 | string: NullTerminatedString, |
| 1889 | 1889 | ip: *const InternPool, |
| 1890 | 1890 | }; |
| 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 { | |
| 1897 | 1892 | const slice = data.string.toSlice(data.ip); |
| 1898 | 1893 | if (comptime std.mem.eql(u8, specifier, "")) { |
| 1899 | try writer.writeAll(slice); | |
| 1894 | try bw.writeAll(slice); | |
| 1900 | 1895 | } 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)}); | |
| 1902 | 1897 | } else @compileError("invalid format string '" ++ specifier ++ "' for '" ++ @typeName(NullTerminatedString) ++ "'"); |
| 1903 | 1898 | } |
| 1904 | 1899 | |
| ... | ... | @@ -9758,7 +9753,7 @@ fn finishFuncInstance( |
| 9758 | 9753 | const fn_namespace = fn_owner_nav.analysis.?.namespace; |
| 9759 | 9754 | |
| 9760 | 9755 | // 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}", .{ | |
| 9762 | 9757 | fn_owner_nav.name.fmt(ip), @intFromEnum(func_index), |
| 9763 | 9758 | }, .no_embedded_nulls); |
| 9764 | 9759 | const nav_index = try ip.createNav(gpa, tid, .{ |
| ... | ... | @@ -11415,12 +11410,12 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) |
| 11415 | 11410 | var it = instances.iterator(); |
| 11416 | 11411 | while (it.next()) |entry| { |
| 11417 | 11412 | 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 }); | |
| 11419 | 11414 | for (entry.value_ptr.items) |index| { |
| 11420 | 11415 | const unwrapped_index = index.unwrap(ip); |
| 11421 | 11416 | const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip)); |
| 11422 | 11417 | 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)}); | |
| 11424 | 11419 | for (func.comptime_args.get(ip)) |arg| { |
| 11425 | 11420 | if (arg != .none) { |
| 11426 | 11421 | const key = ip.indexToKey(arg); |
src/Package.zig+1-1| ... | ... | @@ -134,7 +134,7 @@ pub const Hash = struct { |
| 134 | 134 | } |
| 135 | 135 | var bin_digest: [Algo.digest_length]u8 = undefined; |
| 136 | 136 | 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; | |
| 138 | 138 | return result; |
| 139 | 139 | } |
| 140 | 140 | }; |
src/Package/Fetch.zig+15-15| ... | ... | @@ -185,7 +185,7 @@ pub const JobQueue = struct { |
| 185 | 185 | const hash_slice = hash.toSlice(); |
| 186 | 186 | |
| 187 | 187 | try buf.print( |
| 188 | \\ pub const {} = struct {{ | |
| 188 | \\ pub const {f} = struct {{ | |
| 189 | 189 | \\ |
| 190 | 190 | , .{std.zig.fmtId(hash_slice)}); |
| 191 | 191 | |
| ... | ... | @@ -211,13 +211,13 @@ pub const JobQueue = struct { |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | try buf.print( |
| 214 | \\ pub const build_root = "{q}"; | |
| 214 | \\ pub const build_root = "{fq}"; | |
| 215 | 215 | \\ |
| 216 | 216 | , .{fetch.package_root}); |
| 217 | 217 | |
| 218 | 218 | if (fetch.has_build_zig) { |
| 219 | 219 | try buf.print( |
| 220 | \\ pub const build_zig = @import("{}"); | |
| 220 | \\ pub const build_zig = @import("{f}"); | |
| 221 | 221 | \\ |
| 222 | 222 | , .{std.zig.fmtEscapes(hash_slice)}); |
| 223 | 223 | } |
| ... | ... | @@ -230,7 +230,7 @@ pub const JobQueue = struct { |
| 230 | 230 | for (manifest.dependencies.keys(), manifest.dependencies.values()) |name, dep| { |
| 231 | 231 | const h = depDigest(fetch.package_root, jq.global_cache, dep) orelse continue; |
| 232 | 232 | try buf.print( |
| 233 | " .{{ \"{}\", \"{}\" }},\n", | |
| 233 | " .{{ \"{f}\", \"{f}\" }},\n", | |
| 234 | 234 | .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(h.toSlice()) }, |
| 235 | 235 | ); |
| 236 | 236 | } |
| ... | ... | @@ -262,7 +262,7 @@ pub const JobQueue = struct { |
| 262 | 262 | for (root_manifest.dependencies.keys(), root_manifest.dependencies.values()) |name, dep| { |
| 263 | 263 | const h = depDigest(root_fetch.package_root, jq.global_cache, dep) orelse continue; |
| 264 | 264 | try buf.print( |
| 265 | " .{{ \"{}\", \"{}\" }},\n", | |
| 265 | " .{{ \"{f}\", \"{f}\" }},\n", | |
| 266 | 266 | .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(h.toSlice()) }, |
| 267 | 267 | ); |
| 268 | 268 | } |
| ... | ... | @@ -353,7 +353,7 @@ pub fn run(f: *Fetch) RunError!void { |
| 353 | 353 | if (!std.mem.startsWith(u8, pkg_root.sub_path, expected_prefix)) { |
| 354 | 354 | return f.fail( |
| 355 | 355 | f.location_tok, |
| 356 | try eb.printString("dependency path outside project: '{}'", .{pkg_root}), | |
| 356 | try eb.printString("dependency path outside project: '{f}'", .{pkg_root}), | |
| 357 | 357 | ); |
| 358 | 358 | } |
| 359 | 359 | } |
| ... | ... | @@ -604,7 +604,7 @@ pub fn computedPackageHash(f: *const Fetch) Package.Hash { |
| 604 | 604 | const saturated_size = std.math.cast(u32, f.computed_hash.total_size) orelse std.math.maxInt(u32); |
| 605 | 605 | if (f.manifest) |man| { |
| 606 | 606 | 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; | |
| 608 | 608 | return .init(f.computed_hash.digest, man.name, version, man.id, saturated_size); |
| 609 | 609 | } |
| 610 | 610 | // 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 { |
| 622 | 622 | error.FileNotFound => {}, |
| 623 | 623 | else => |e| { |
| 624 | 624 | try eb.addRootErrorMessage(.{ |
| 625 | .msg = try eb.printString("unable to access '{}{s}': {s}", .{ | |
| 625 | .msg = try eb.printString("unable to access '{f}{s}': {s}", .{ | |
| 626 | 626 | f.package_root, Package.build_zig_basename, @errorName(e), |
| 627 | 627 | }), |
| 628 | 628 | }); |
| ... | ... | @@ -636,9 +636,9 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { |
| 636 | 636 | const eb = &f.error_bundle; |
| 637 | 637 | const arena = f.arena.allocator(); |
| 638 | 638 | const manifest_bytes = pkg_root.root_dir.handle.readFileAllocOptions( |
| 639 | arena, | |
| 640 | 639 | try fs.path.join(arena, &.{ pkg_root.sub_path, Manifest.basename }), |
| 641 | Manifest.max_bytes, | |
| 640 | arena, | |
| 641 | .limited(Manifest.max_bytes), | |
| 642 | 642 | null, |
| 643 | 643 | .@"1", |
| 644 | 644 | 0, |
| ... | ... | @@ -647,7 +647,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { |
| 647 | 647 | else => |e| { |
| 648 | 648 | const file_path = try pkg_root.join(arena, Manifest.basename); |
| 649 | 649 | 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}", .{ | |
| 651 | 651 | file_path, @errorName(e), |
| 652 | 652 | }), |
| 653 | 653 | }); |
| ... | ... | @@ -659,7 +659,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { |
| 659 | 659 | ast.* = try std.zig.Ast.parse(arena, manifest_bytes, .zon); |
| 660 | 660 | |
| 661 | 661 | 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}); | |
| 663 | 663 | try std.zig.putAstErrorsIntoBundle(arena, ast.*, file_path, eb); |
| 664 | 664 | return error.FetchFailed; |
| 665 | 665 | } |
| ... | ... | @@ -672,7 +672,7 @@ fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { |
| 672 | 672 | const manifest = &f.manifest.?; |
| 673 | 673 | |
| 674 | 674 | 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 }); | |
| 676 | 676 | try manifest.copyErrorsIntoBundle(ast.*, src_path, eb); |
| 677 | 677 | return error.FetchFailed; |
| 678 | 678 | } |
| ... | ... | @@ -827,7 +827,7 @@ fn srcLoc( |
| 827 | 827 | const ast = f.parent_manifest_ast orelse return .none; |
| 828 | 828 | const eb = &f.error_bundle; |
| 829 | 829 | 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}); | |
| 831 | 831 | const msg_off = 0; |
| 832 | 832 | return eb.addSourceLocation(.{ |
| 833 | 833 | .src_path = src_path, |
| ... | ... | @@ -1512,7 +1512,7 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute |
| 1512 | 1512 | |
| 1513 | 1513 | while (walker.next() catch |err| { |
| 1514 | 1514 | try eb.addRootErrorMessage(.{ .msg = try eb.printString( |
| 1515 | "unable to walk temporary directory '{}': {s}", | |
| 1515 | "unable to walk temporary directory '{f}': {s}", | |
| 1516 | 1516 | .{ pkg_path, @errorName(err) }, |
| 1517 | 1517 | ) }); |
| 1518 | 1518 | return error.FetchFailed; |
src/Package/Fetch/git.zig+2-8| ... | ... | @@ -119,15 +119,9 @@ pub const Oid = union(Format) { |
| 119 | 119 | } else error.InvalidOid; |
| 120 | 120 | } |
| 121 | 121 | |
| 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 { | |
| 128 | 123 | _ = fmt; |
| 129 | _ = options; | |
| 130 | try writer.print("{x}", .{oid.slice()}); | |
| 124 | try bw.print("{x}", .{oid.slice()}); | |
| 131 | 125 | } |
| 132 | 126 | |
| 133 | 127 | pub fn slice(oid: *const Oid) []const u8 { |
src/Package/Manifest.zig+2-2| ... | ... | @@ -401,7 +401,7 @@ const Parse = struct { |
| 401 | 401 | return fail(p, main_token, "name must be a valid bare zig identifier (hint: switch from string to enum literal)", .{}); |
| 402 | 402 | |
| 403 | 403 | 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}", .{ | |
| 405 | 405 | std.zig.fmtId(name), max_name_len, |
| 406 | 406 | }); |
| 407 | 407 | |
| ... | ... | @@ -416,7 +416,7 @@ const Parse = struct { |
| 416 | 416 | return fail(p, main_token, "name must be a valid bare zig identifier", .{}); |
| 417 | 417 | |
| 418 | 418 | 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}", .{ | |
| 420 | 420 | std.zig.fmtId(ident_name), max_name_len, |
| 421 | 421 | }); |
| 422 | 422 |
src/Sema.zig+419-416| ... | ... | @@ -888,7 +888,7 @@ const ComptimeReason = union(enum) { |
| 888 | 888 | /// Evaluating at comptime because of a comptime-only type. This field is separate so that |
| 889 | 889 | /// the type in question can be included in the error message. AstGen could never emit this |
| 890 | 890 | /// 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. | |
| 892 | 892 | /// We will then explain why this type is comptime-only. |
| 893 | 893 | comptime_only: struct { |
| 894 | 894 | ty: Type, |
| ... | ... | @@ -930,17 +930,17 @@ const ComptimeReason = union(enum) { |
| 930 | 930 | .struct_init => .{ "initializer of comptime-only struct", "must be comptime-known" }, |
| 931 | 931 | .tuple_init => .{ "initializer of comptime-only tuple", "must be comptime-known" }, |
| 932 | 932 | }; |
| 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 }); | |
| 934 | 934 | try sema.explainWhyTypeIsComptime(err_msg, src, co.ty); |
| 935 | 935 | }, |
| 936 | 936 | .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)}); | |
| 938 | 938 | try sema.errNote(co.param_ty_src, err_msg, "parameter type declared here", .{}); |
| 939 | 939 | try sema.explainWhyTypeIsComptime(err_msg, src, co.ty); |
| 940 | 940 | }, |
| 941 | 941 | .comptime_only_ret_ty => |co| { |
| 942 | 942 | 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) }); | |
| 944 | 944 | try sema.errNote(co.ret_ty_src, err_msg, "return type declared here", .{}); |
| 945 | 945 | try sema.explainWhyTypeIsComptime(err_msg, src, co.ty); |
| 946 | 946 | }, |
| ... | ... | @@ -1909,7 +1909,7 @@ fn analyzeBodyInner( |
| 1909 | 1909 | const err_union = try sema.resolveInst(extra.data.operand); |
| 1910 | 1910 | const err_union_ty = sema.typeOf(err_union); |
| 1911 | 1911 | 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}'", .{ | |
| 1913 | 1913 | err_union_ty.fmt(pt), |
| 1914 | 1914 | }); |
| 1915 | 1915 | } |
| ... | ... | @@ -2343,7 +2343,7 @@ pub fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) Compile |
| 2343 | 2343 | |
| 2344 | 2344 | fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { |
| 2345 | 2345 | 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", .{ | |
| 2347 | 2347 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), |
| 2348 | 2348 | }); |
| 2349 | 2349 | } |
| ... | ... | @@ -2351,7 +2351,7 @@ fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: T |
| 2351 | 2351 | fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError { |
| 2352 | 2352 | const pt = sema.pt; |
| 2353 | 2353 | 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}'", .{ | |
| 2355 | 2355 | non_optional_ty.fmt(pt), |
| 2356 | 2356 | }); |
| 2357 | 2357 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -2367,12 +2367,12 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non |
| 2367 | 2367 | fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { |
| 2368 | 2368 | const pt = sema.pt; |
| 2369 | 2369 | 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", .{ | |
| 2371 | 2371 | ty.fmt(pt), |
| 2372 | 2372 | }); |
| 2373 | 2373 | errdefer msg.destroy(sema.gpa); |
| 2374 | 2374 | 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)}); | |
| 2376 | 2376 | } |
| 2377 | 2377 | break :msg msg; |
| 2378 | 2378 | }; |
| ... | ... | @@ -2381,7 +2381,7 @@ fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty |
| 2381 | 2381 | |
| 2382 | 2382 | fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { |
| 2383 | 2383 | 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", .{ | |
| 2385 | 2385 | ty.fmt(pt), |
| 2386 | 2386 | }); |
| 2387 | 2387 | } |
| ... | ... | @@ -2394,7 +2394,7 @@ fn failWithErrorSetCodeMissing( |
| 2394 | 2394 | src_err_set_ty: Type, |
| 2395 | 2395 | ) CompileError { |
| 2396 | 2396 | 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}'", .{ | |
| 2398 | 2398 | dest_err_set_ty.fmt(pt), src_err_set_ty.fmt(pt), |
| 2399 | 2399 | }); |
| 2400 | 2400 | } |
| ... | ... | @@ -2402,7 +2402,7 @@ fn failWithErrorSetCodeMissing( |
| 2402 | 2402 | pub fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: ?usize) CompileError { |
| 2403 | 2403 | const pt = sema.pt; |
| 2404 | 2404 | 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}'", .{ | |
| 2406 | 2406 | int_ty.fmt(pt), val.fmtValueSema(pt, sema), |
| 2407 | 2407 | }); |
| 2408 | 2408 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -2452,7 +2452,7 @@ fn failWithInvalidFieldAccess( |
| 2452 | 2452 | const child_ty = inner_ty.optionalChild(zcu); |
| 2453 | 2453 | if (!typeSupportsFieldAccess(zcu, child_ty, field_name)) break :opt; |
| 2454 | 2454 | 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)}); | |
| 2456 | 2456 | errdefer msg.destroy(sema.gpa); |
| 2457 | 2457 | try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{}); |
| 2458 | 2458 | break :msg msg; |
| ... | ... | @@ -2462,14 +2462,14 @@ fn failWithInvalidFieldAccess( |
| 2462 | 2462 | const child_ty = inner_ty.errorUnionPayload(zcu); |
| 2463 | 2463 | if (!typeSupportsFieldAccess(zcu, child_ty, field_name)) break :err; |
| 2464 | 2464 | 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)}); | |
| 2466 | 2466 | errdefer msg.destroy(sema.gpa); |
| 2467 | 2467 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 2468 | 2468 | break :msg msg; |
| 2469 | 2469 | }; |
| 2470 | 2470 | return sema.failWithOwnedErrorMsg(block, msg); |
| 2471 | 2471 | } |
| 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)}); | |
| 2473 | 2473 | } |
| 2474 | 2474 | |
| 2475 | 2475 | fn typeSupportsFieldAccess(zcu: *const Zcu, ty: Type, field_name: InternPool.NullTerminatedString) bool { |
| ... | ... | @@ -2498,7 +2498,7 @@ fn failWithComptimeErrorRetTrace( |
| 2498 | 2498 | const pt = sema.pt; |
| 2499 | 2499 | const zcu = pt.zcu; |
| 2500 | 2500 | 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)}); | |
| 2502 | 2502 | errdefer msg.destroy(sema.gpa); |
| 2503 | 2503 | |
| 2504 | 2504 | for (sema.comptime_err_ret_trace.items) |src_loc| { |
| ... | ... | @@ -3009,7 +3009,7 @@ pub fn createTypeName( |
| 3009 | 3009 | inst: ?Zir.Inst.Index, |
| 3010 | 3010 | /// This is used purely to give the type a unique name in the `anon` case. |
| 3011 | 3011 | type_index: InternPool.Index, |
| 3012 | ) !struct { | |
| 3012 | ) CompileError!struct { | |
| 3013 | 3013 | name: InternPool.NullTerminatedString, |
| 3014 | 3014 | nav: InternPool.Nav.Index.Optional, |
| 3015 | 3015 | } { |
| ... | ... | @@ -3028,11 +3028,11 @@ pub fn createTypeName( |
| 3028 | 3028 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail); |
| 3029 | 3029 | const zir_tags = sema.code.instructions.items(.tag); |
| 3030 | 3030 | |
| 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); | |
| 3036 | 3036 | |
| 3037 | 3037 | var arg_i: usize = 0; |
| 3038 | 3038 | for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) { |
| ... | ... | @@ -3045,18 +3045,18 @@ pub fn createTypeName( |
| 3045 | 3045 | // result in a compile error. |
| 3046 | 3046 | const arg_val = try sema.resolveValue(arg) orelse break :func_strat; // fall through to anon strat |
| 3047 | 3047 | |
| 3048 | if (arg_i != 0) try writer.writeByte(','); | |
| 3048 | if (arg_i != 0) bw.writeByte(',') catch |err| return @errorCast(err); | |
| 3049 | 3049 | |
| 3050 | 3050 | // Limiting the depth here helps avoid type names getting too long, which |
| 3051 | 3051 | // in turn helps to avoid unreasonably long symbol names for namespaced |
| 3052 | 3052 | // symbols. Such names should ideally be human-readable, and additionally, |
| 3053 | 3053 | // some tooling may not support very long symbol names. |
| 3054 | try writer.print("{}", .{Value.fmtValueSemaFull(.{ | |
| 3054 | bw.print("{f}", .{Value.fmtValueSemaFull(.{ | |
| 3055 | 3055 | .val = arg_val, |
| 3056 | 3056 | .pt = pt, |
| 3057 | 3057 | .opt_sema = sema, |
| 3058 | 3058 | .depth = 1, |
| 3059 | })}); | |
| 3059 | })}) catch |err| return @errorCast(err); | |
| 3060 | 3060 | |
| 3061 | 3061 | arg_i += 1; |
| 3062 | 3062 | continue; |
| ... | ... | @@ -3064,9 +3064,9 @@ pub fn createTypeName( |
| 3064 | 3064 | else => continue, |
| 3065 | 3065 | }; |
| 3066 | 3066 | |
| 3067 | try writer.writeByte(')'); | |
| 3067 | try bw.writeByte(')'); | |
| 3068 | 3068 | 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), | |
| 3070 | 3070 | .nav = .none, |
| 3071 | 3071 | }; |
| 3072 | 3072 | }, |
| ... | ... | @@ -3078,7 +3078,7 @@ pub fn createTypeName( |
| 3078 | 3078 | for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) { |
| 3079 | 3079 | .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) { |
| 3080 | 3080 | return .{ |
| 3081 | .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{ | |
| 3081 | .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}.{s}", .{ | |
| 3082 | 3082 | block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code), |
| 3083 | 3083 | }, .no_embedded_nulls), |
| 3084 | 3084 | .nav = .none, |
| ... | ... | @@ -3101,7 +3101,7 @@ pub fn createTypeName( |
| 3101 | 3101 | // that builtin from the language, we can consider this. |
| 3102 | 3102 | |
| 3103 | 3103 | return .{ |
| 3104 | .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{ | |
| 3104 | .name = try ip.getOrPutStringFmt(gpa, pt.tid, "{f}__{s}_{d}", .{ | |
| 3105 | 3105 | block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index), |
| 3106 | 3106 | }, .no_embedded_nulls), |
| 3107 | 3107 | .nav = .none, |
| ... | ... | @@ -3585,7 +3585,7 @@ fn ensureResultUsed( |
| 3585 | 3585 | }, |
| 3586 | 3586 | else => { |
| 3587 | 3587 | 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)}); | |
| 3589 | 3589 | errdefer msg.destroy(sema.gpa); |
| 3590 | 3590 | try sema.errNote(src, msg, "all non-void values must be used", .{}); |
| 3591 | 3591 | 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 |
| 3855 | 3855 | // The value was initialized through RLS, so we didn't detect the runtime condition earlier. |
| 3856 | 3856 | // TODO: source location of runtime control flow |
| 3857 | 3857 | 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)}); | |
| 3859 | 3859 | } |
| 3860 | 3860 | |
| 3861 | 3861 | // This is a runtime value. |
| ... | ... | @@ -4352,7 +4352,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4352 | 4352 | // The alloc wasn't comptime-known per the above logic, so the |
| 4353 | 4353 | // type cannot be comptime-only. |
| 4354 | 4354 | // 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)}); | |
| 4356 | 4356 | } |
| 4357 | 4357 | if (sema.func_is_naked and try final_elem_ty.hasRuntimeBitsSema(pt)) { |
| 4358 | 4358 | 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. |
| 4449 | 4449 | if (!object_ty.isIndexable(zcu)) { |
| 4450 | 4450 | // Instead of using checkIndexable we customize this error. |
| 4451 | 4451 | 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)}); | |
| 4453 | 4453 | errdefer msg.destroy(sema.gpa); |
| 4454 | 4454 | try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{}); |
| 4455 | 4455 | |
| ... | ... | @@ -4484,10 +4484,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4484 | 4484 | .for_node_offset = inst_data.src_node, |
| 4485 | 4485 | .input_index = len_idx, |
| 4486 | 4486 | } }); |
| 4487 | try sema.errNote(a_src, msg, "length {} here", .{ | |
| 4487 | try sema.errNote(a_src, msg, "length {f} here", .{ | |
| 4488 | 4488 | v.fmtValueSema(pt, sema), |
| 4489 | 4489 | }); |
| 4490 | try sema.errNote(arg_src, msg, "length {} here", .{ | |
| 4490 | try sema.errNote(arg_src, msg, "length {f} here", .{ | |
| 4491 | 4491 | arg_val.fmtValueSema(pt, sema), |
| 4492 | 4492 | }); |
| 4493 | 4493 | break :msg msg; |
| ... | ... | @@ -4519,7 +4519,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4519 | 4519 | .for_node_offset = inst_data.src_node, |
| 4520 | 4520 | .input_index = i, |
| 4521 | 4521 | } }); |
| 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", .{ | |
| 4523 | 4523 | object_ty.fmt(pt), |
| 4524 | 4524 | }); |
| 4525 | 4525 | } |
| ... | ... | @@ -4595,7 +4595,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4595 | 4595 | switch (val_ty.zigTypeTag(zcu)) { |
| 4596 | 4596 | .array, .vector => {}, |
| 4597 | 4597 | 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) }); | |
| 4599 | 4599 | }, |
| 4600 | 4600 | } |
| 4601 | 4601 | const want_ty = try pt.arrayType(.{ |
| ... | ... | @@ -4669,7 +4669,7 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4669 | 4669 | const ty_operand = try sema.resolveTypeOrPoison(block, src, un_tok.operand) orelse return; |
| 4670 | 4670 | if (ty_operand.optEuBaseType(zcu).zigTypeTag(zcu) != .pointer) { |
| 4671 | 4671 | 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)}); | |
| 4673 | 4673 | errdefer msg.destroy(sema.gpa); |
| 4674 | 4674 | try sema.errNote(src, msg, "address-of operator always returns a pointer", .{}); |
| 4675 | 4675 | break :msg msg; |
| ... | ... | @@ -5078,7 +5078,7 @@ fn validateStructInit( |
| 5078 | 5078 | } |
| 5079 | 5079 | continue; |
| 5080 | 5080 | }; |
| 5081 | const template = "missing struct field: {}"; | |
| 5081 | const template = "missing struct field: {f}"; | |
| 5082 | 5082 | const args = .{field_name.fmt(ip)}; |
| 5083 | 5083 | if (root_msg) |msg| { |
| 5084 | 5084 | try sema.errNote(init_src, msg, template, args); |
| ... | ... | @@ -5208,7 +5208,7 @@ fn validateStructInit( |
| 5208 | 5208 | } |
| 5209 | 5209 | continue; |
| 5210 | 5210 | }; |
| 5211 | const template = "missing struct field: {}"; | |
| 5211 | const template = "missing struct field: {f}"; | |
| 5212 | 5212 | const args = .{field_name.fmt(ip)}; |
| 5213 | 5213 | if (root_msg) |msg| { |
| 5214 | 5214 | try sema.errNote(init_src, msg, template, args); |
| ... | ... | @@ -5512,11 +5512,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 5512 | 5512 | const operand_ty = sema.typeOf(operand); |
| 5513 | 5513 | |
| 5514 | 5514 | 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)}); | |
| 5516 | 5516 | } else switch (operand_ty.ptrSize(zcu)) { |
| 5517 | 5517 | .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)}), | |
| 5520 | 5520 | } |
| 5521 | 5521 | |
| 5522 | 5522 | if ((try sema.typeHasOnePossibleValue(operand_ty.childType(zcu))) != null) { |
| ... | ... | @@ -5533,7 +5533,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 5533 | 5533 | const msg = msg: { |
| 5534 | 5534 | const msg = try sema.errMsg( |
| 5535 | 5535 | 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", | |
| 5537 | 5537 | .{elem_ty.fmt(pt)}, |
| 5538 | 5538 | ); |
| 5539 | 5539 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -5565,7 +5565,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 5565 | 5565 | |
| 5566 | 5566 | if (!typeIsDestructurable(operand_ty, zcu)) { |
| 5567 | 5567 | 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)}); | |
| 5569 | 5569 | errdefer msg.destroy(sema.gpa); |
| 5570 | 5570 | try sema.errNote(destructure_src, msg, "result destructured here", .{}); |
| 5571 | 5571 | if (operand_ty.zigTypeTag(pt.zcu) == .error_union) { |
| ... | ... | @@ -5608,12 +5608,12 @@ fn failWithBadMemberAccess( |
| 5608 | 5608 | else => unreachable, |
| 5609 | 5609 | }; |
| 5610 | 5610 | 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}'", .{ | |
| 5612 | 5612 | agg_ty.fmt(pt), field_name.fmt(ip), |
| 5613 | 5613 | }); |
| 5614 | 5614 | }; |
| 5615 | 5615 | |
| 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}'", .{ | |
| 5617 | 5617 | kw_name, agg_ty.fmt(pt), field_name.fmt(ip), |
| 5618 | 5618 | }); |
| 5619 | 5619 | } |
| ... | ... | @@ -5633,7 +5633,7 @@ fn failWithBadStructFieldAccess( |
| 5633 | 5633 | const msg = msg: { |
| 5634 | 5634 | const msg = try sema.errMsg( |
| 5635 | 5635 | field_src, |
| 5636 | "no field named '{}' in struct '{}'", | |
| 5636 | "no field named '{f}' in struct '{f}'", | |
| 5637 | 5637 | .{ field_name.fmt(ip), struct_type.name.fmt(ip) }, |
| 5638 | 5638 | ); |
| 5639 | 5639 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -5659,7 +5659,7 @@ fn failWithBadUnionFieldAccess( |
| 5659 | 5659 | const msg = msg: { |
| 5660 | 5660 | const msg = try sema.errMsg( |
| 5661 | 5661 | field_src, |
| 5662 | "no field named '{}' in union '{}'", | |
| 5662 | "no field named '{f}' in union '{f}'", | |
| 5663 | 5663 | .{ field_name.fmt(ip), union_obj.name.fmt(ip) }, |
| 5664 | 5664 | ); |
| 5665 | 5665 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -5911,30 +5911,30 @@ fn zirCompileLog( |
| 5911 | 5911 | const zcu = pt.zcu; |
| 5912 | 5912 | const gpa = zcu.gpa; |
| 5913 | 5913 | |
| 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(); | |
| 5918 | 5917 | |
| 5919 | 5918 | const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand); |
| 5920 | 5919 | const src_node = extra.data.src_node; |
| 5921 | 5920 | const args = sema.code.refSlice(extra.end, extended.small); |
| 5922 | 5921 | |
| 5923 | 5922 | for (args, 0..) |arg_ref, i| { |
| 5924 | if (i != 0) try writer.print(", ", .{}); | |
| 5923 | if (i != 0) bw.writeAll(", ") catch |err| return @errorCast(err); | |
| 5925 | 5924 | |
| 5926 | 5925 | const arg = try sema.resolveInst(arg_ref); |
| 5927 | 5926 | const arg_ty = sema.typeOf(arg); |
| 5928 | 5927 | if (try sema.resolveValueResolveLazy(arg)) |val| { |
| 5929 | try writer.print("@as({}, {})", .{ | |
| 5928 | bw.print("@as({f}, {f})", .{ | |
| 5930 | 5929 | arg_ty.fmt(pt), val.fmtValueSema(pt, sema), |
| 5931 | }); | |
| 5930 | }) catch |err| return @errorCast(err); | |
| 5932 | 5931 | } 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); | |
| 5934 | 5933 | } |
| 5935 | 5934 | } |
| 5935 | try bw.print("\n", .{}); | |
| 5936 | 5936 | |
| 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); | |
| 5938 | 5938 | |
| 5939 | 5939 | const line_idx: Zcu.CompileLogLine.Index = if (zcu.free_compile_log_lines.pop()) |idx| idx: { |
| 5940 | 5940 | zcu.compile_log_lines.items[@intFromEnum(idx)] = .{ |
| ... | ... | @@ -6476,7 +6476,7 @@ fn resolveAnalyzedBlock( |
| 6476 | 6476 | const type_src = src; // TODO: better source location |
| 6477 | 6477 | if (try resolved_ty.comptimeOnlySema(pt)) { |
| 6478 | 6478 | 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)}); | |
| 6480 | 6480 | errdefer msg.destroy(sema.gpa); |
| 6481 | 6481 | |
| 6482 | 6482 | 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 |
| 6592 | 6592 | |
| 6593 | 6593 | { |
| 6594 | 6594 | 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)}); | |
| 6596 | 6596 | } |
| 6597 | 6597 | const ptr_ty_info = ptr_ty.ptrInfo(zcu); |
| 6598 | 6598 | if (ptr_ty_info.flags.size == .slice) { |
| ... | ... | @@ -6615,7 +6615,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 6615 | 6615 | const export_ty = Value.fromInterned(uav.val).typeOf(zcu); |
| 6616 | 6616 | if (!try sema.validateExternType(export_ty, .other)) { |
| 6617 | 6617 | 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)}); | |
| 6619 | 6619 | errdefer msg.destroy(sema.gpa); |
| 6620 | 6620 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); |
| 6621 | 6621 | try sema.addDeclaredHereNote(msg, export_ty); |
| ... | ... | @@ -6667,7 +6667,7 @@ pub fn analyzeExport( |
| 6667 | 6667 | |
| 6668 | 6668 | if (!try sema.validateExternType(export_ty, .other)) { |
| 6669 | 6669 | 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)}); | |
| 6671 | 6671 | errdefer msg.destroy(gpa); |
| 6672 | 6672 | |
| 6673 | 6673 | try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other); |
| ... | ... | @@ -7363,7 +7363,7 @@ fn checkCallArgumentCount( |
| 7363 | 7363 | opt_child.childType(zcu).zigTypeTag(zcu) == .@"fn")) |
| 7364 | 7364 | { |
| 7365 | 7365 | 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}'", .{ | |
| 7367 | 7367 | callee_ty.fmt(pt), |
| 7368 | 7368 | }); |
| 7369 | 7369 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -7375,7 +7375,7 @@ fn checkCallArgumentCount( |
| 7375 | 7375 | }, |
| 7376 | 7376 | else => {}, |
| 7377 | 7377 | } |
| 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)}); | |
| 7379 | 7379 | }; |
| 7380 | 7380 | |
| 7381 | 7381 | const func_ty_info = zcu.typeToFunc(func_ty).?; |
| ... | ... | @@ -7438,7 +7438,7 @@ fn callBuiltin( |
| 7438 | 7438 | }, |
| 7439 | 7439 | else => {}, |
| 7440 | 7440 | } |
| 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)}); | |
| 7442 | 7442 | }; |
| 7443 | 7443 | |
| 7444 | 7444 | const func_ty_info = zcu.typeToFunc(func_ty).?; |
| ... | ... | @@ -7826,7 +7826,7 @@ fn analyzeCall( |
| 7826 | 7826 | |
| 7827 | 7827 | if (!param_ty.isValidParamType(zcu)) { |
| 7828 | 7828 | 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", .{ | |
| 7830 | 7830 | opaque_str, param_ty.fmt(pt), |
| 7831 | 7831 | }); |
| 7832 | 7832 | } |
| ... | ... | @@ -7923,7 +7923,7 @@ fn analyzeCall( |
| 7923 | 7923 | |
| 7924 | 7924 | if (!full_ty.isValidReturnType(zcu)) { |
| 7925 | 7925 | 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", .{ | |
| 7927 | 7927 | opaque_str, full_ty.fmt(pt), |
| 7928 | 7928 | }); |
| 7929 | 7929 | } |
| ... | ... | @@ -8382,7 +8382,7 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ |
| 8382 | 8382 | } |
| 8383 | 8383 | const owner_func_ty: Type = .fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty); |
| 8384 | 8384 | 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}'", .{ | |
| 8386 | 8386 | func_ty.fmt(pt), owner_func_ty.fmt(pt), |
| 8387 | 8387 | }); |
| 8388 | 8388 | } |
| ... | ... | @@ -8406,9 +8406,9 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 8406 | 8406 | const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node }); |
| 8407 | 8407 | const child_type = try sema.resolveType(block, operand_src, inst_data.operand); |
| 8408 | 8408 | 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)}); | |
| 8410 | 8410 | } 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)}); | |
| 8412 | 8412 | } |
| 8413 | 8413 | const opt_type = try pt.optionalType(child_type.toIntern()); |
| 8414 | 8414 | |
| ... | ... | @@ -8469,7 +8469,7 @@ fn zirVecArrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8469 | 8469 | const vec_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, un_node.operand) orelse return .generic_poison_type; |
| 8470 | 8470 | switch (vec_ty.zigTypeTag(zcu)) { |
| 8471 | 8471 | .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)}), | |
| 8473 | 8473 | } |
| 8474 | 8474 | return Air.internedToRef(vec_ty.childType(zcu).toIntern()); |
| 8475 | 8475 | } |
| ... | ... | @@ -8537,7 +8537,7 @@ fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: |
| 8537 | 8537 | const pt = sema.pt; |
| 8538 | 8538 | const zcu = pt.zcu; |
| 8539 | 8539 | 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)}); | |
| 8541 | 8541 | } else if (elem_type.zigTypeTag(zcu) == .noreturn) { |
| 8542 | 8542 | return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{}); |
| 8543 | 8543 | } |
| ... | ... | @@ -8573,7 +8573,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8573 | 8573 | const payload = try sema.resolveType(block, rhs_src, extra.rhs); |
| 8574 | 8574 | |
| 8575 | 8575 | 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}'", .{ | |
| 8577 | 8577 | error_set.fmt(pt), |
| 8578 | 8578 | }); |
| 8579 | 8579 | } |
| ... | ... | @@ -8586,11 +8586,11 @@ fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, p |
| 8586 | 8586 | const pt = sema.pt; |
| 8587 | 8587 | const zcu = pt.zcu; |
| 8588 | 8588 | 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", .{ | |
| 8590 | 8590 | payload_ty.fmt(pt), |
| 8591 | 8591 | }); |
| 8592 | 8592 | } 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", .{ | |
| 8594 | 8594 | payload_ty.fmt(pt), |
| 8595 | 8595 | }); |
| 8596 | 8596 | } |
| ... | ... | @@ -8728,9 +8728,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 8728 | 8728 | const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs); |
| 8729 | 8729 | const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs); |
| 8730 | 8730 | 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)}); | |
| 8732 | 8732 | 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)}); | |
| 8734 | 8734 | |
| 8735 | 8735 | // Anything merged with anyerror is anyerror. |
| 8736 | 8736 | 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 |
| 8840 | 8840 | return sema.fail( |
| 8841 | 8841 | block, |
| 8842 | 8842 | operand_src, |
| 8843 | "untagged union '{}' cannot be converted to integer", | |
| 8843 | "untagged union '{f}' cannot be converted to integer", | |
| 8844 | 8844 | .{operand_ty.fmt(pt)}, |
| 8845 | 8845 | ); |
| 8846 | 8846 | }; |
| ... | ... | @@ -8848,7 +8848,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8848 | 8848 | break :blk try sema.unionToTag(block, tag_ty, operand, operand_src); |
| 8849 | 8849 | }, |
| 8850 | 8850 | 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}'", .{ | |
| 8852 | 8852 | operand_ty.fmt(pt), |
| 8853 | 8853 | }); |
| 8854 | 8854 | }, |
| ... | ... | @@ -8859,7 +8859,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8859 | 8859 | // TODO: use correct solution |
| 8860 | 8860 | // https://github.com/ziglang/zig/issues/15909 |
| 8861 | 8861 | 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}'", .{ | |
| 8863 | 8863 | enum_tag_ty.fmt(pt), |
| 8864 | 8864 | }); |
| 8865 | 8865 | } |
| ... | ... | @@ -8893,7 +8893,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8893 | 8893 | const operand_ty = sema.typeOf(operand); |
| 8894 | 8894 | |
| 8895 | 8895 | 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)}); | |
| 8897 | 8897 | } |
| 8898 | 8898 | _ = try sema.checkIntType(block, operand_src, operand_ty); |
| 8899 | 8899 | |
| ... | ... | @@ -8903,7 +8903,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8903 | 8903 | if (try sema.intFitsInType(int_val, int_tag_ty, null)) { |
| 8904 | 8904 | return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern()); |
| 8905 | 8905 | } |
| 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}'", .{ | |
| 8907 | 8907 | int_val.fmtValueSema(pt, sema), dest_ty.fmt(pt), |
| 8908 | 8908 | }); |
| 8909 | 8909 | } |
| ... | ... | @@ -8911,7 +8911,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8911 | 8911 | return sema.failWithUseOfUndef(block, operand_src); |
| 8912 | 8912 | } |
| 8913 | 8913 | 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}'", .{ | |
| 8915 | 8915 | dest_ty.fmt(pt), int_val.fmtValueSema(pt, sema), |
| 8916 | 8916 | }); |
| 8917 | 8917 | } |
| ... | ... | @@ -9105,7 +9105,7 @@ fn zirErrUnionPayload( |
| 9105 | 9105 | const operand_src = src; |
| 9106 | 9106 | const err_union_ty = sema.typeOf(operand); |
| 9107 | 9107 | 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}'", .{ | |
| 9109 | 9109 | err_union_ty.fmt(pt), |
| 9110 | 9110 | }); |
| 9111 | 9111 | } |
| ... | ... | @@ -9173,7 +9173,7 @@ fn analyzeErrUnionPayloadPtr( |
| 9173 | 9173 | assert(operand_ty.zigTypeTag(zcu) == .pointer); |
| 9174 | 9174 | |
| 9175 | 9175 | 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}'", .{ | |
| 9177 | 9177 | operand_ty.childType(zcu).fmt(pt), |
| 9178 | 9178 | }); |
| 9179 | 9179 | } |
| ... | ... | @@ -9250,7 +9250,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air |
| 9250 | 9250 | const zcu = pt.zcu; |
| 9251 | 9251 | const operand_ty = sema.typeOf(operand); |
| 9252 | 9252 | 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}'", .{ | |
| 9254 | 9254 | operand_ty.fmt(pt), |
| 9255 | 9255 | }); |
| 9256 | 9256 | } |
| ... | ... | @@ -9286,7 +9286,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: |
| 9286 | 9286 | assert(operand_ty.zigTypeTag(zcu) == .pointer); |
| 9287 | 9287 | |
| 9288 | 9288 | 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}'", .{ | |
| 9290 | 9290 | operand_ty.childType(zcu).fmt(pt), |
| 9291 | 9291 | }); |
| 9292 | 9292 | } |
| ... | ... | @@ -9544,19 +9544,18 @@ fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention.Tag) bool { |
| 9544 | 9544 | fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention.Tag) CompileError!void { |
| 9545 | 9545 | const CallingConventionsSupportingVarArgsList = struct { |
| 9546 | 9546 | 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 { | |
| 9548 | 9548 | _ = fmt; |
| 9549 | _ = options; | |
| 9550 | 9549 | var first = true; |
| 9551 | 9550 | for (calling_conventions_supporting_var_args) |cc_inner| { |
| 9552 | 9551 | for (std.Target.Cpu.Arch.fromCallingConvention(cc_inner)) |supported_arch| { |
| 9553 | 9552 | if (supported_arch == ctx.arch) break; |
| 9554 | 9553 | } else continue; // callconv not supported by this arch |
| 9555 | 9554 | if (!first) { |
| 9556 | try writer.writeAll(", "); | |
| 9555 | try bw.writeAll(", "); | |
| 9557 | 9556 | } |
| 9558 | 9557 | first = false; |
| 9559 | try writer.print("'{s}'", .{@tagName(cc_inner)}); | |
| 9558 | try bw.print("'{s}'", .{@tagName(cc_inner)}); | |
| 9560 | 9559 | } |
| 9561 | 9560 | } |
| 9562 | 9561 | }; |
| ... | ... | @@ -9566,7 +9565,7 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: |
| 9566 | 9565 | const msg = try sema.errMsg(src, "variadic function does not support '{s}' calling convention", .{@tagName(cc)}); |
| 9567 | 9566 | errdefer msg.destroy(sema.gpa); |
| 9568 | 9567 | 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 }}); | |
| 9570 | 9569 | break :msg msg; |
| 9571 | 9570 | }); |
| 9572 | 9571 | } |
| ... | ... | @@ -9614,7 +9613,7 @@ fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type) |
| 9614 | 9613 | } |
| 9615 | 9614 | |
| 9616 | 9615 | 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)}); | |
| 9618 | 9617 | errdefer msg.destroy(sema.gpa); |
| 9619 | 9618 | |
| 9620 | 9619 | const runtime_src = block.runtime_cond orelse block.runtime_loop.?; |
| ... | ... | @@ -9692,13 +9691,13 @@ fn funcCommon( |
| 9692 | 9691 | } |
| 9693 | 9692 | if (!param_ty.isValidParamType(zcu)) { |
| 9694 | 9693 | 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", .{ | |
| 9696 | 9695 | opaque_str, param_ty.fmt(pt), |
| 9697 | 9696 | }); |
| 9698 | 9697 | } |
| 9699 | 9698 | if (!param_ty_generic and !target_util.fnCallConvAllowsZigTypes(cc) and !try sema.validateExternType(param_ty, .param_ty)) { |
| 9700 | 9699 | 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}'", .{ | |
| 9702 | 9701 | param_ty.fmt(pt), @tagName(cc), |
| 9703 | 9702 | }); |
| 9704 | 9703 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -9712,7 +9711,7 @@ fn funcCommon( |
| 9712 | 9711 | } |
| 9713 | 9712 | if (param_ty_comptime and !param_is_comptime and has_body and !block.isComptime()) { |
| 9714 | 9713 | 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", .{ | |
| 9716 | 9715 | param_ty.fmt(pt), |
| 9717 | 9716 | }); |
| 9718 | 9717 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -9892,7 +9891,7 @@ fn finishFunc( |
| 9892 | 9891 | |
| 9893 | 9892 | if (!return_type.isValidReturnType(zcu)) { |
| 9894 | 9893 | 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", .{ | |
| 9896 | 9895 | opaque_str, return_type.fmt(pt), |
| 9897 | 9896 | }); |
| 9898 | 9897 | } |
| ... | ... | @@ -9900,7 +9899,7 @@ fn finishFunc( |
| 9900 | 9899 | !try sema.validateExternType(return_type, .ret_ty)) |
| 9901 | 9900 | { |
| 9902 | 9901 | 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}'", .{ | |
| 9904 | 9903 | return_type.fmt(pt), @tagName(cc_resolved), |
| 9905 | 9904 | }); |
| 9906 | 9905 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -9922,7 +9921,7 @@ fn finishFunc( |
| 9922 | 9921 | |
| 9923 | 9922 | const msg = try sema.errMsg( |
| 9924 | 9923 | 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", | |
| 9926 | 9925 | .{return_type.fmt(pt)}, |
| 9927 | 9926 | ); |
| 9928 | 9927 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -9991,17 +9990,16 @@ fn finishFunc( |
| 9991 | 9990 | .bad_arch => |allowed_archs| { |
| 9992 | 9991 | const ArchListFormatter = struct { |
| 9993 | 9992 | 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 { | |
| 9995 | 9994 | _ = fmt; |
| 9996 | _ = options; | |
| 9997 | 9995 | for (formatter.archs, 0..) |arch, i| { |
| 9998 | 9996 | 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)}); | |
| 10001 | 9999 | } |
| 10002 | 10000 | } |
| 10003 | 10001 | }; |
| 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}", .{ | |
| 10005 | 10003 | @tagName(cc_resolved), |
| 10006 | 10004 | ArchListFormatter{ .archs = allowed_archs }, |
| 10007 | 10005 | }); |
| ... | ... | @@ -10102,7 +10100,7 @@ fn analyzeAs( |
| 10102 | 10100 | const operand = try sema.resolveInst(zir_operand); |
| 10103 | 10101 | const dest_ty = try sema.resolveTypeOrPoison(block, src, zir_dest_type) orelse return operand; |
| 10104 | 10102 | 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)}), | |
| 10106 | 10104 | .noreturn => return sema.fail(block, src, "cannot cast to noreturn", .{}), |
| 10107 | 10105 | else => {}, |
| 10108 | 10106 | } |
| ... | ... | @@ -10130,12 +10128,12 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 10130 | 10128 | const ptr_ty = operand_ty.scalarType(zcu); |
| 10131 | 10129 | const is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 10132 | 10130 | 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)}); | |
| 10134 | 10132 | } |
| 10135 | 10133 | const pointee_ty = ptr_ty.childType(zcu); |
| 10136 | 10134 | if (try ptr_ty.comptimeOnlySema(pt)) { |
| 10137 | 10135 | 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)}); | |
| 10139 | 10137 | errdefer msg.destroy(sema.gpa); |
| 10140 | 10138 | try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty); |
| 10141 | 10139 | break :msg msg; |
| ... | ... | @@ -10383,14 +10381,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10383 | 10381 | .type, |
| 10384 | 10382 | .undefined, |
| 10385 | 10383 | .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)}), | |
| 10387 | 10385 | |
| 10388 | 10386 | .@"enum" => { |
| 10389 | 10387 | 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)}); | |
| 10391 | 10389 | errdefer msg.destroy(sema.gpa); |
| 10392 | 10390 | 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)}), | |
| 10394 | 10392 | else => {}, |
| 10395 | 10393 | } |
| 10396 | 10394 | |
| ... | ... | @@ -10401,11 +10399,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10401 | 10399 | |
| 10402 | 10400 | .pointer => { |
| 10403 | 10401 | 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)}); | |
| 10405 | 10403 | errdefer msg.destroy(sema.gpa); |
| 10406 | 10404 | 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)}), | |
| 10409 | 10407 | else => {}, |
| 10410 | 10408 | } |
| 10411 | 10409 | |
| ... | ... | @@ -10419,7 +10417,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10419 | 10417 | .@"union" => "union", |
| 10420 | 10418 | else => unreachable, |
| 10421 | 10419 | }; |
| 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", .{ | |
| 10423 | 10421 | dest_ty.fmt(pt), container, |
| 10424 | 10422 | }); |
| 10425 | 10423 | }, |
| ... | ... | @@ -10447,14 +10445,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10447 | 10445 | .type, |
| 10448 | 10446 | .undefined, |
| 10449 | 10447 | .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)}), | |
| 10451 | 10449 | |
| 10452 | 10450 | .@"enum" => { |
| 10453 | 10451 | 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)}); | |
| 10455 | 10453 | errdefer msg.destroy(sema.gpa); |
| 10456 | 10454 | 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)}), | |
| 10458 | 10456 | else => {}, |
| 10459 | 10457 | } |
| 10460 | 10458 | |
| ... | ... | @@ -10464,11 +10462,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10464 | 10462 | }, |
| 10465 | 10463 | .pointer => { |
| 10466 | 10464 | 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)}); | |
| 10468 | 10466 | errdefer msg.destroy(sema.gpa); |
| 10469 | 10467 | 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)}), | |
| 10472 | 10470 | else => {}, |
| 10473 | 10471 | } |
| 10474 | 10472 | |
| ... | ... | @@ -10482,7 +10480,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10482 | 10480 | .@"union" => "union", |
| 10483 | 10481 | else => unreachable, |
| 10484 | 10482 | }; |
| 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", .{ | |
| 10486 | 10484 | operand_ty.fmt(pt), container, |
| 10487 | 10485 | }); |
| 10488 | 10486 | }, |
| ... | ... | @@ -10525,7 +10523,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10525 | 10523 | else => return sema.fail( |
| 10526 | 10524 | block, |
| 10527 | 10525 | src, |
| 10528 | "expected float or vector type, found '{}'", | |
| 10526 | "expected float or vector type, found '{f}'", | |
| 10529 | 10527 | .{dest_ty.fmt(pt)}, |
| 10530 | 10528 | ), |
| 10531 | 10529 | }; |
| ... | ... | @@ -10535,7 +10533,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 10535 | 10533 | else => return sema.fail( |
| 10536 | 10534 | block, |
| 10537 | 10535 | operand_src, |
| 10538 | "expected float or vector type, found '{}'", | |
| 10536 | "expected float or vector type, found '{f}'", | |
| 10539 | 10537 | .{operand_ty.fmt(pt)}, |
| 10540 | 10538 | ), |
| 10541 | 10539 | } |
| ... | ... | @@ -10619,7 +10617,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 10619 | 10617 | if (indexable_ty.zigTypeTag(zcu) != .pointer) { |
| 10620 | 10618 | const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node }); |
| 10621 | 10619 | 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}'", .{ | |
| 10623 | 10621 | indexable_ty.fmt(pt), |
| 10624 | 10622 | }); |
| 10625 | 10623 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -10761,7 +10759,7 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 10761 | 10759 | const lhs_ptr_ty = sema.typeOf(try sema.resolveInst(inst_data.operand)); |
| 10762 | 10760 | const lhs_ty = switch (lhs_ptr_ty.zigTypeTag(zcu)) { |
| 10763 | 10761 | .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)}), | |
| 10765 | 10763 | }; |
| 10766 | 10764 | |
| 10767 | 10765 | const sentinel_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) { |
| ... | ... | @@ -10776,7 +10774,7 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 10776 | 10774 | }; |
| 10777 | 10775 | }, |
| 10778 | 10776 | }, |
| 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)}), | |
| 10780 | 10778 | }; |
| 10781 | 10779 | |
| 10782 | 10780 | return Air.internedToRef(sentinel_ty.toIntern()); |
| ... | ... | @@ -10971,7 +10969,7 @@ const SwitchProngAnalysis = struct { |
| 10971 | 10969 | .base_node_inst = capture_src.base_node_inst, |
| 10972 | 10970 | .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture }, |
| 10973 | 10971 | }; |
| 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}'", .{ | |
| 10975 | 10973 | operand_ty.fmt(pt), |
| 10976 | 10974 | }); |
| 10977 | 10975 | } |
| ... | ... | @@ -11403,7 +11401,7 @@ fn switchCond( |
| 11403 | 11401 | .@"enum", |
| 11404 | 11402 | => { |
| 11405 | 11403 | 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)}); | |
| 11407 | 11405 | } |
| 11408 | 11406 | if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| { |
| 11409 | 11407 | return Air.internedToRef(opv.toIntern()); |
| ... | ... | @@ -11438,7 +11436,7 @@ fn switchCond( |
| 11438 | 11436 | .vector, |
| 11439 | 11437 | .frame, |
| 11440 | 11438 | .@"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)}), | |
| 11442 | 11440 | } |
| 11443 | 11441 | } |
| 11444 | 11442 | |
| ... | ... | @@ -11539,7 +11537,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 11539 | 11537 | operand_ty; |
| 11540 | 11538 | |
| 11541 | 11539 | 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}'", .{ | |
| 11543 | 11541 | operand_ty.fmt(pt), |
| 11544 | 11542 | }); |
| 11545 | 11543 | } |
| ... | ... | @@ -11793,7 +11791,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11793 | 11791 | // Even if the operand is comptime-known, this `switch` is runtime. |
| 11794 | 11792 | if (try operand_ty.comptimeOnlySema(pt)) { |
| 11795 | 11793 | 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)}); | |
| 11797 | 11795 | errdefer msg.destroy(gpa); |
| 11798 | 11796 | try sema.errNote(operand_src, msg, "switch loops are evaluated at runtime outside of comptime scopes", .{}); |
| 11799 | 11797 | break :msg msg; |
| ... | ... | @@ -12017,14 +12015,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12017 | 12015 | cond_ty, |
| 12018 | 12016 | i, |
| 12019 | 12017 | msg, |
| 12020 | "unhandled enumeration value: '{}'", | |
| 12018 | "unhandled enumeration value: '{f}'", | |
| 12021 | 12019 | .{field_name.fmt(&zcu.intern_pool)}, |
| 12022 | 12020 | ); |
| 12023 | 12021 | } |
| 12024 | 12022 | try sema.errNote( |
| 12025 | 12023 | cond_ty.srcLoc(zcu), |
| 12026 | 12024 | msg, |
| 12027 | "enum '{}' declared here", | |
| 12025 | "enum '{f}' declared here", | |
| 12028 | 12026 | .{cond_ty.fmt(pt)}, |
| 12029 | 12027 | ); |
| 12030 | 12028 | break :msg msg; |
| ... | ... | @@ -12236,7 +12234,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12236 | 12234 | return sema.fail( |
| 12237 | 12235 | block, |
| 12238 | 12236 | src, |
| 12239 | "else prong required when switching on type '{}'", | |
| 12237 | "else prong required when switching on type '{f}'", | |
| 12240 | 12238 | .{cond_ty.fmt(pt)}, |
| 12241 | 12239 | ); |
| 12242 | 12240 | } |
| ... | ... | @@ -12312,7 +12310,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 12312 | 12310 | .@"anyframe", |
| 12313 | 12311 | .comptime_float, |
| 12314 | 12312 | .float, |
| 12315 | => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{ | |
| 12313 | => return sema.fail(block, operand_src, "invalid switch operand type '{f}'", .{ | |
| 12316 | 12314 | raw_operand_ty.fmt(pt), |
| 12317 | 12315 | }), |
| 12318 | 12316 | } |
| ... | ... | @@ -12841,7 +12839,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12841 | 12839 | if (special.is_inline) switch (operand_ty.zigTypeTag(zcu)) { |
| 12842 | 12840 | .@"enum" => { |
| 12843 | 12841 | 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'", .{ | |
| 12845 | 12843 | operand_ty.fmt(pt), |
| 12846 | 12844 | }); |
| 12847 | 12845 | } |
| ... | ... | @@ -12897,7 +12895,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12897 | 12895 | }, |
| 12898 | 12896 | .error_set => { |
| 12899 | 12897 | 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'", .{ | |
| 12901 | 12899 | operand_ty.fmt(pt), |
| 12902 | 12900 | }); |
| 12903 | 12901 | } |
| ... | ... | @@ -13058,7 +13056,7 @@ fn analyzeSwitchRuntimeBlock( |
| 13058 | 13056 | cases_extra.appendSliceAssumeCapacity(@ptrCast(case_block.instructions.items)); |
| 13059 | 13057 | } |
| 13060 | 13058 | }, |
| 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'", .{ | |
| 13062 | 13060 | operand_ty.fmt(pt), |
| 13063 | 13061 | }), |
| 13064 | 13062 | }; |
| ... | ... | @@ -13572,7 +13570,7 @@ fn validateErrSetSwitch( |
| 13572 | 13570 | try sema.errNote( |
| 13573 | 13571 | src, |
| 13574 | 13572 | msg, |
| 13575 | "unhandled error value: 'error.{}'", | |
| 13573 | "unhandled error value: 'error.{f}'", | |
| 13576 | 13574 | .{error_name.fmt(ip)}, |
| 13577 | 13575 | ); |
| 13578 | 13576 | } |
| ... | ... | @@ -13798,7 +13796,7 @@ fn validateSwitchNoRange( |
| 13798 | 13796 | const msg = msg: { |
| 13799 | 13797 | const msg = try sema.errMsg( |
| 13800 | 13798 | operand_src, |
| 13801 | "ranges not allowed when switching on type '{}'", | |
| 13799 | "ranges not allowed when switching on type '{f}'", | |
| 13802 | 13800 | .{operand_ty.fmt(sema.pt)}, |
| 13803 | 13801 | ); |
| 13804 | 13802 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -13956,7 +13954,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13956 | 13954 | .array_type => break :hf field_name.eqlSlice("len", ip), |
| 13957 | 13955 | else => {}, |
| 13958 | 13956 | } |
| 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'", .{ | |
| 13960 | 13958 | ty.fmt(pt), |
| 13961 | 13959 | }); |
| 13962 | 13960 | }; |
| ... | ... | @@ -14145,7 +14143,7 @@ fn zirShl( |
| 14145 | 14143 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { |
| 14146 | 14144 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14147 | 14145 | 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}'", .{ | |
| 14149 | 14147 | rhs_elem.fmtValueSema(pt, sema), |
| 14150 | 14148 | i, |
| 14151 | 14149 | scalar_ty.fmt(pt), |
| ... | ... | @@ -14153,7 +14151,7 @@ fn zirShl( |
| 14153 | 14151 | } |
| 14154 | 14152 | } |
| 14155 | 14153 | } 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}'", .{ | |
| 14157 | 14155 | rhs_val.fmtValueSema(pt, sema), |
| 14158 | 14156 | scalar_ty.fmt(pt), |
| 14159 | 14157 | }); |
| ... | ... | @@ -14164,14 +14162,14 @@ fn zirShl( |
| 14164 | 14162 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { |
| 14165 | 14163 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14166 | 14164 | 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}'", .{ | |
| 14168 | 14166 | rhs_elem.fmtValueSema(pt, sema), |
| 14169 | 14167 | i, |
| 14170 | 14168 | }); |
| 14171 | 14169 | } |
| 14172 | 14170 | } |
| 14173 | 14171 | } 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}'", .{ | |
| 14175 | 14173 | rhs_val.fmtValueSema(pt, sema), |
| 14176 | 14174 | }); |
| 14177 | 14175 | } |
| ... | ... | @@ -14326,7 +14324,7 @@ fn zirShr( |
| 14326 | 14324 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { |
| 14327 | 14325 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14328 | 14326 | 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}'", .{ | |
| 14330 | 14328 | rhs_elem.fmtValueSema(pt, sema), |
| 14331 | 14329 | i, |
| 14332 | 14330 | scalar_ty.fmt(pt), |
| ... | ... | @@ -14334,7 +14332,7 @@ fn zirShr( |
| 14334 | 14332 | } |
| 14335 | 14333 | } |
| 14336 | 14334 | } 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}'", .{ | |
| 14338 | 14336 | rhs_val.fmtValueSema(pt, sema), |
| 14339 | 14337 | scalar_ty.fmt(pt), |
| 14340 | 14338 | }); |
| ... | ... | @@ -14345,14 +14343,14 @@ fn zirShr( |
| 14345 | 14343 | while (i < rhs_ty.vectorLen(zcu)) : (i += 1) { |
| 14346 | 14344 | const rhs_elem = try rhs_val.elemValue(pt, i); |
| 14347 | 14345 | 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}'", .{ | |
| 14349 | 14347 | rhs_elem.fmtValueSema(pt, sema), |
| 14350 | 14348 | i, |
| 14351 | 14349 | }); |
| 14352 | 14350 | } |
| 14353 | 14351 | } |
| 14354 | 14352 | } 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}'", .{ | |
| 14356 | 14354 | rhs_val.fmtValueSema(pt, sema), |
| 14357 | 14355 | }); |
| 14358 | 14356 | } |
| ... | ... | @@ -14638,11 +14636,11 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14638 | 14636 | |
| 14639 | 14637 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: { |
| 14640 | 14638 | 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)}); | |
| 14642 | 14640 | }; |
| 14643 | 14641 | const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs, lhs_ty) orelse { |
| 14644 | 14642 | 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)}); | |
| 14646 | 14644 | }; |
| 14647 | 14645 | |
| 14648 | 14646 | const resolved_elem_ty = t: { |
| ... | ... | @@ -15095,7 +15093,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15095 | 15093 | // Analyze the lhs first, to catch the case that someone tried to do exponentiation |
| 15096 | 15094 | const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse { |
| 15097 | 15095 | 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)}); | |
| 15099 | 15097 | errdefer msg.destroy(sema.gpa); |
| 15100 | 15098 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 15101 | 15099 | .int, .float, .comptime_float, .comptime_int, .vector => { |
| ... | ... | @@ -15227,7 +15225,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15227 | 15225 | .int, .comptime_int, .float, .comptime_float => false, |
| 15228 | 15226 | else => true, |
| 15229 | 15227 | }) { |
| 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)}); | |
| 15231 | 15229 | } |
| 15232 | 15230 | |
| 15233 | 15231 | if (rhs_scalar_ty.isAnyFloat()) { |
| ... | ... | @@ -15258,7 +15256,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15258 | 15256 | |
| 15259 | 15257 | switch (rhs_scalar_ty.zigTypeTag(zcu)) { |
| 15260 | 15258 | .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)}), | |
| 15262 | 15260 | } |
| 15263 | 15261 | |
| 15264 | 15262 | 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 |
| 15332 | 15330 | return sema.fail( |
| 15333 | 15331 | block, |
| 15334 | 15332 | src, |
| 15335 | "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", | |
| 15333 | "ambiguous coercion of division operands '{f}' and '{f}'; non-zero remainder '{f}'", | |
| 15336 | 15334 | .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt), rem.fmtValueSema(pt, sema) }, |
| 15337 | 15335 | ); |
| 15338 | 15336 | } |
| ... | ... | @@ -15384,7 +15382,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15384 | 15382 | return sema.fail( |
| 15385 | 15383 | block, |
| 15386 | 15384 | 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", | |
| 15388 | 15386 | .{ lhs_ty.fmt(pt), rhs_ty.fmt(pt) }, |
| 15389 | 15387 | ); |
| 15390 | 15388 | } |
| ... | ... | @@ -16046,7 +16044,7 @@ fn zirOverflowArithmetic( |
| 16046 | 16044 | const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src); |
| 16047 | 16045 | |
| 16048 | 16046 | 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)}); | |
| 16050 | 16048 | } |
| 16051 | 16049 | |
| 16052 | 16050 | const maybe_lhs_val = try sema.resolveValue(lhs); |
| ... | ... | @@ -16252,14 +16250,14 @@ fn analyzeArithmetic( |
| 16252 | 16250 | return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction"); |
| 16253 | 16251 | } |
| 16254 | 16252 | 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}'", .{ | |
| 16256 | 16254 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), |
| 16257 | 16255 | }); |
| 16258 | 16256 | } |
| 16259 | 16257 | |
| 16260 | 16258 | const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu); |
| 16261 | 16259 | 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", .{ | |
| 16263 | 16261 | lhs_ty.elemType2(zcu).fmt(pt), |
| 16264 | 16262 | }); |
| 16265 | 16263 | } |
| ... | ... | @@ -16310,7 +16308,7 @@ fn analyzeArithmetic( |
| 16310 | 16308 | }; |
| 16311 | 16309 | |
| 16312 | 16310 | 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", .{ | |
| 16314 | 16312 | lhs_ty.elemType2(zcu).fmt(pt), |
| 16315 | 16313 | }); |
| 16316 | 16314 | } |
| ... | ... | @@ -16714,7 +16712,7 @@ fn zirCmpEq( |
| 16714 | 16712 | |
| 16715 | 16713 | if (lhs_ty_tag == .null or rhs_ty_tag == .null) { |
| 16716 | 16714 | 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)}); | |
| 16718 | 16716 | } |
| 16719 | 16717 | |
| 16720 | 16718 | if (lhs_ty_tag == .@"union" and (rhs_ty_tag == .enum_literal or rhs_ty_tag == .@"enum")) { |
| ... | ... | @@ -16771,7 +16769,7 @@ fn analyzeCmpUnionTag( |
| 16771 | 16769 | const msg = msg: { |
| 16772 | 16770 | const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); |
| 16773 | 16771 | 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)}); | |
| 16775 | 16773 | break :msg msg; |
| 16776 | 16774 | }; |
| 16777 | 16775 | return sema.failWithOwnedErrorMsg(block, msg); |
| ... | ... | @@ -16857,7 +16855,7 @@ fn analyzeCmp( |
| 16857 | 16855 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 16858 | 16856 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); |
| 16859 | 16857 | 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}'", .{ | |
| 16861 | 16859 | compareOperatorName(op), resolved_type.fmt(pt), |
| 16862 | 16860 | }); |
| 16863 | 16861 | } |
| ... | ... | @@ -16966,7 +16964,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 16966 | 16964 | .undefined, |
| 16967 | 16965 | .null, |
| 16968 | 16966 | .@"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)}), | |
| 16970 | 16968 | |
| 16971 | 16969 | .type, |
| 16972 | 16970 | .enum_literal, |
| ... | ... | @@ -17007,7 +17005,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 17007 | 17005 | .undefined, |
| 17008 | 17006 | .null, |
| 17009 | 17007 | .@"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)}), | |
| 17011 | 17009 | |
| 17012 | 17010 | .type, |
| 17013 | 17011 | .enum_literal, |
| ... | ... | @@ -18319,7 +18317,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi |
| 18319 | 18317 | return sema.fail( |
| 18320 | 18318 | block, |
| 18321 | 18319 | src, |
| 18322 | "bit shifting operation expected integer type, found '{}'", | |
| 18320 | "bit shifting operation expected integer type, found '{f}'", | |
| 18323 | 18321 | .{operand.fmt(pt)}, |
| 18324 | 18322 | ); |
| 18325 | 18323 | } |
| ... | ... | @@ -18558,7 +18556,7 @@ fn checkSentinelType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !voi |
| 18558 | 18556 | const pt = sema.pt; |
| 18559 | 18557 | const zcu = pt.zcu; |
| 18560 | 18558 | 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)}); | |
| 18562 | 18560 | } |
| 18563 | 18561 | } |
| 18564 | 18562 | |
| ... | ... | @@ -18608,7 +18606,7 @@ fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 18608 | 18606 | const zcu = pt.zcu; |
| 18609 | 18607 | switch (ty.zigTypeTag(zcu)) { |
| 18610 | 18608 | .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}'", .{ | |
| 18612 | 18610 | ty.fmt(pt), |
| 18613 | 18611 | }), |
| 18614 | 18612 | } |
| ... | ... | @@ -18752,7 +18750,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 18752 | 18750 | const pt = sema.pt; |
| 18753 | 18751 | const zcu = pt.zcu; |
| 18754 | 18752 | 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}'", .{ | |
| 18756 | 18754 | err_union_ty.fmt(pt), |
| 18757 | 18755 | }); |
| 18758 | 18756 | } |
| ... | ... | @@ -18812,7 +18810,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 18812 | 18810 | const pt = sema.pt; |
| 18813 | 18811 | const zcu = pt.zcu; |
| 18814 | 18812 | 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}'", .{ | |
| 18816 | 18814 | err_union_ty.fmt(pt), |
| 18817 | 18815 | }); |
| 18818 | 18816 | } |
| ... | ... | @@ -19010,7 +19008,7 @@ fn zirRetImplicit( |
| 19010 | 19008 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu); |
| 19011 | 19009 | if (base_tag == .noreturn) { |
| 19012 | 19010 | 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", .{ | |
| 19014 | 19012 | sema.fn_ret_ty.fmt(pt), |
| 19015 | 19013 | }); |
| 19016 | 19014 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -19020,7 +19018,7 @@ fn zirRetImplicit( |
| 19020 | 19018 | return sema.failWithOwnedErrorMsg(block, msg); |
| 19021 | 19019 | } else if (base_tag != .void) { |
| 19022 | 19020 | 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", .{ | |
| 19024 | 19022 | sema.fn_ret_ty.fmt(pt), |
| 19025 | 19023 | }); |
| 19026 | 19024 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -19409,13 +19407,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19409 | 19407 | |
| 19410 | 19408 | if (host_size != 0) { |
| 19411 | 19409 | 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", .{ | |
| 19413 | 19411 | elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size, |
| 19414 | 19412 | }); |
| 19415 | 19413 | } |
| 19416 | 19414 | const elem_bit_size = try elem_ty.bitSizeSema(pt); |
| 19417 | 19415 | 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", .{ | |
| 19419 | 19417 | elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size, |
| 19420 | 19418 | }); |
| 19421 | 19419 | } |
| ... | ... | @@ -19430,7 +19428,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19430 | 19428 | } else if (inst_data.size == .c) { |
| 19431 | 19429 | if (!try sema.validateExternType(elem_ty, .other)) { |
| 19432 | 19430 | 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)}); | |
| 19434 | 19432 | errdefer msg.destroy(sema.gpa); |
| 19435 | 19433 | |
| 19436 | 19434 | 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 |
| 19447 | 19445 | |
| 19448 | 19446 | if (host_size != 0 and !try sema.validatePackedType(elem_ty)) { |
| 19449 | 19447 | 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)}); | |
| 19451 | 19449 | errdefer msg.destroy(sema.gpa); |
| 19452 | 19450 | try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty); |
| 19453 | 19451 | break :msg msg; |
| ... | ... | @@ -19616,7 +19614,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 19616 | 19614 | const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data; |
| 19617 | 19615 | const union_ty = try sema.resolveType(block, ty_src, extra.union_type); |
| 19618 | 19616 | 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)}); | |
| 19620 | 19618 | } |
| 19621 | 19619 | const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .union_field_name }); |
| 19622 | 19620 | const init = try sema.resolveInst(extra.init); |
| ... | ... | @@ -19779,7 +19777,7 @@ fn zirStructInit( |
| 19779 | 19777 | const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{}); |
| 19780 | 19778 | errdefer msg.destroy(sema.gpa); |
| 19781 | 19779 | |
| 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", .{ | |
| 19783 | 19781 | field_name.fmt(ip), |
| 19784 | 19782 | }); |
| 19785 | 19783 | try sema.addDeclaredHereNote(msg, resolved_ty); |
| ... | ... | @@ -19898,7 +19896,7 @@ fn finishStructInit( |
| 19898 | 19896 | const field_init = struct_type.fieldInit(ip, i); |
| 19899 | 19897 | if (field_init == .none) { |
| 19900 | 19898 | const field_name = struct_type.field_names.get(ip)[i]; |
| 19901 | const template = "missing struct field: {}"; | |
| 19899 | const template = "missing struct field: {f}"; | |
| 19902 | 19900 | const args = .{field_name.fmt(ip)}; |
| 19903 | 19901 | if (root_msg) |msg| { |
| 19904 | 19902 | try sema.errNote(init_src, msg, template, args); |
| ... | ... | @@ -20513,7 +20511,7 @@ fn fieldType( |
| 20513 | 20511 | }, |
| 20514 | 20512 | else => {}, |
| 20515 | 20513 | } |
| 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}'", .{ | |
| 20517 | 20515 | cur_ty.fmt(pt), |
| 20518 | 20516 | }); |
| 20519 | 20517 | } |
| ... | ... | @@ -20560,7 +20558,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20560 | 20558 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 20561 | 20559 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 20562 | 20560 | 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)}); | |
| 20564 | 20562 | } |
| 20565 | 20563 | const val = try ty.lazyAbiAlignment(sema.pt); |
| 20566 | 20564 | return Air.internedToRef(val.toIntern()); |
| ... | ... | @@ -20638,7 +20636,7 @@ fn zirAbs( |
| 20638 | 20636 | else => return sema.fail( |
| 20639 | 20637 | block, |
| 20640 | 20638 | 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}'", | |
| 20642 | 20640 | .{operand_ty.fmt(pt)}, |
| 20643 | 20641 | ), |
| 20644 | 20642 | }; |
| ... | ... | @@ -20707,7 +20705,7 @@ fn zirUnaryMath( |
| 20707 | 20705 | else => return sema.fail( |
| 20708 | 20706 | block, |
| 20709 | 20707 | operand_src, |
| 20710 | "expected vector of floats or float type, found '{}'", | |
| 20708 | "expected vector of floats or float type, found '{f}'", | |
| 20711 | 20709 | .{operand_ty.fmt(pt)}, |
| 20712 | 20710 | ), |
| 20713 | 20711 | } |
| ... | ... | @@ -20736,8 +20734,8 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20736 | 20734 | }, |
| 20737 | 20735 | .@"enum" => operand_ty, |
| 20738 | 20736 | .@"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}'", .{ | |
| 20741 | 20739 | operand_ty.fmt(pt), |
| 20742 | 20740 | }), |
| 20743 | 20741 | }; |
| ... | ... | @@ -20745,7 +20743,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20745 | 20743 | // TODO I don't think this is the correct way to handle this but |
| 20746 | 20744 | // it prevents a crash. |
| 20747 | 20745 | // 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}'", .{ | |
| 20749 | 20747 | enum_ty.fmt(pt), |
| 20750 | 20748 | }); |
| 20751 | 20749 | } |
| ... | ... | @@ -20753,7 +20751,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 20753 | 20751 | if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| { |
| 20754 | 20752 | const field_index = enum_ty.enumTagFieldIndex(val, zcu) orelse { |
| 20755 | 20753 | 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}'", .{ | |
| 20757 | 20755 | val.fmtValueSema(pt, sema), enum_ty.fmt(pt), |
| 20758 | 20756 | }); |
| 20759 | 20757 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -20940,7 +20938,7 @@ fn zirReify( |
| 20940 | 20938 | } else if (ptr_size == .c) { |
| 20941 | 20939 | if (!try sema.validateExternType(elem_ty, .other)) { |
| 20942 | 20940 | 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)}); | |
| 20944 | 20942 | errdefer msg.destroy(gpa); |
| 20945 | 20943 | |
| 20946 | 20944 | try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other); |
| ... | ... | @@ -21053,7 +21051,7 @@ fn zirReify( |
| 21053 | 21051 | _ = try pt.getErrorValue(name); |
| 21054 | 21052 | const gop = names.getOrPutAssumeCapacity(name); |
| 21055 | 21053 | if (gop.found_existing) { |
| 21056 | return sema.fail(block, src, "duplicate error '{}'", .{ | |
| 21054 | return sema.fail(block, src, "duplicate error '{f}'", .{ | |
| 21057 | 21055 | name.fmt(ip), |
| 21058 | 21056 | }); |
| 21059 | 21057 | } |
| ... | ... | @@ -21401,7 +21399,7 @@ fn reifyEnum( |
| 21401 | 21399 | |
| 21402 | 21400 | if (!try sema.intFitsInType(field_value_val, tag_ty, null)) { |
| 21403 | 21401 | // 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}'", .{ | |
| 21405 | 21403 | field_name.fmt(ip), |
| 21406 | 21404 | field_value_val.fmtValueSema(pt, sema), |
| 21407 | 21405 | tag_ty.fmt(pt), |
| ... | ... | @@ -21412,14 +21410,14 @@ fn reifyEnum( |
| 21412 | 21410 | if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| { |
| 21413 | 21411 | return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) { |
| 21414 | 21412 | .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)}); | |
| 21416 | 21414 | errdefer msg.destroy(gpa); |
| 21417 | 21415 | _ = conflict.prev_field_idx; // TODO: this note is incorrect |
| 21418 | 21416 | try sema.errNote(src, msg, "other field here", .{}); |
| 21419 | 21417 | break :msg msg; |
| 21420 | 21418 | }, |
| 21421 | 21419 | .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)}); | |
| 21423 | 21421 | errdefer msg.destroy(gpa); |
| 21424 | 21422 | _ = conflict.prev_field_idx; // TODO: this note is incorrect |
| 21425 | 21423 | try sema.errNote(src, msg, "other enum tag value here", .{}); |
| ... | ... | @@ -21567,13 +21565,13 @@ fn reifyUnion( |
| 21567 | 21565 | |
| 21568 | 21566 | const enum_index = enum_tag_ty.enumFieldIndex(field_name, zcu) orelse { |
| 21569 | 21567 | // 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}'", .{ | |
| 21571 | 21569 | field_name.fmt(ip), enum_tag_ty.fmt(pt), |
| 21572 | 21570 | }); |
| 21573 | 21571 | }; |
| 21574 | 21572 | if (seen_tags.isSet(enum_index)) { |
| 21575 | 21573 | // 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)}); | |
| 21577 | 21575 | } |
| 21578 | 21576 | seen_tags.set(enum_index); |
| 21579 | 21577 | |
| ... | ... | @@ -21594,7 +21592,7 @@ fn reifyUnion( |
| 21594 | 21592 | var it = seen_tags.iterator(.{ .kind = .unset }); |
| 21595 | 21593 | while (it.next()) |enum_index| { |
| 21596 | 21594 | 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", .{ | |
| 21598 | 21596 | field_name.fmt(ip), |
| 21599 | 21597 | }); |
| 21600 | 21598 | } |
| ... | ... | @@ -21619,7 +21617,7 @@ fn reifyUnion( |
| 21619 | 21617 | const gop = field_names.getOrPutAssumeCapacity(field_name); |
| 21620 | 21618 | if (gop.found_existing) { |
| 21621 | 21619 | // 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)}); | |
| 21623 | 21621 | } |
| 21624 | 21622 | |
| 21625 | 21623 | field_ty.* = field_type_val.toIntern(); |
| ... | ... | @@ -21651,7 +21649,7 @@ fn reifyUnion( |
| 21651 | 21649 | } |
| 21652 | 21650 | if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) { |
| 21653 | 21651 | 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)}); | |
| 21655 | 21653 | errdefer msg.destroy(gpa); |
| 21656 | 21654 | |
| 21657 | 21655 | try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field); |
| ... | ... | @@ -21661,7 +21659,7 @@ fn reifyUnion( |
| 21661 | 21659 | }); |
| 21662 | 21660 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 21663 | 21661 | 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)}); | |
| 21665 | 21663 | errdefer msg.destroy(gpa); |
| 21666 | 21664 | |
| 21667 | 21665 | try sema.explainWhyTypeIsNotPacked(msg, src, field_ty); |
| ... | ... | @@ -21743,7 +21741,7 @@ fn reifyTuple( |
| 21743 | 21741 | const field_name_index = field_name.toUnsigned(ip) orelse return sema.fail( |
| 21744 | 21742 | block, |
| 21745 | 21743 | src, |
| 21746 | "tuple cannot have non-numeric field '{}'", | |
| 21744 | "tuple cannot have non-numeric field '{f}'", | |
| 21747 | 21745 | .{field_name.fmt(ip)}, |
| 21748 | 21746 | ); |
| 21749 | 21747 | if (field_name_index != field_idx) { |
| ... | ... | @@ -21921,7 +21919,7 @@ fn reifyStruct( |
| 21921 | 21919 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| 21922 | 21920 | if (struct_type.addFieldName(ip, field_name)) |prev_index| { |
| 21923 | 21921 | _ = 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)}); | |
| 21925 | 21923 | } |
| 21926 | 21924 | |
| 21927 | 21925 | if (any_aligned_fields) { |
| ... | ... | @@ -21990,7 +21988,7 @@ fn reifyStruct( |
| 21990 | 21988 | } |
| 21991 | 21989 | if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) { |
| 21992 | 21990 | 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)}); | |
| 21994 | 21992 | errdefer msg.destroy(gpa); |
| 21995 | 21993 | |
| 21996 | 21994 | try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field); |
| ... | ... | @@ -22000,7 +21998,7 @@ fn reifyStruct( |
| 22000 | 21998 | }); |
| 22001 | 21999 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 22002 | 22000 | 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)}); | |
| 22004 | 22002 | errdefer msg.destroy(gpa); |
| 22005 | 22003 | |
| 22006 | 22004 | try sema.explainWhyTypeIsNotPacked(msg, src, field_ty); |
| ... | ... | @@ -22077,7 +22075,7 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 22077 | 22075 | |
| 22078 | 22076 | if (!try sema.validateExternType(arg_ty, .param_ty)) { |
| 22079 | 22077 | 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)}); | |
| 22081 | 22079 | errdefer msg.destroy(sema.gpa); |
| 22082 | 22080 | |
| 22083 | 22081 | 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 |
| 22136 | 22134 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 22137 | 22135 | const ty = try sema.resolveType(block, ty_src, inst_data.operand); |
| 22138 | 22136 | |
| 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); | |
| 22140 | 22138 | return sema.addNullTerminatedStrLit(type_name); |
| 22141 | 22139 | } |
| 22142 | 22140 | |
| ... | ... | @@ -22270,7 +22268,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22270 | 22268 | |
| 22271 | 22269 | if (ptr_ty.isSlice(zcu)) { |
| 22272 | 22270 | 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)}); | |
| 22274 | 22272 | errdefer msg.destroy(sema.gpa); |
| 22275 | 22273 | try sema.errNote(src, msg, "slice length cannot be inferred from address", .{}); |
| 22276 | 22274 | break :msg msg; |
| ... | ... | @@ -22297,7 +22295,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 22297 | 22295 | } |
| 22298 | 22296 | if (try ptr_ty.comptimeOnlySema(pt)) { |
| 22299 | 22297 | 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)}); | |
| 22301 | 22299 | errdefer msg.destroy(sema.gpa); |
| 22302 | 22300 | |
| 22303 | 22301 | try sema.explainWhyTypeIsComptime(msg, src, ptr_ty); |
| ... | ... | @@ -22354,7 +22352,7 @@ fn ptrFromIntVal( |
| 22354 | 22352 | } |
| 22355 | 22353 | const addr = try operand_val.toUnsignedIntSema(pt); |
| 22356 | 22354 | 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)}); | |
| 22358 | 22356 | if (addr != 0 and ptr_align != .none) { |
| 22359 | 22357 | const masked_addr = if (ptr_ty.childType(zcu).fnPtrMaskOrNull(zcu)) |mask| |
| 22360 | 22358 | addr & mask |
| ... | ... | @@ -22407,8 +22405,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22407 | 22405 | errdefer msg.destroy(sema.gpa); |
| 22408 | 22406 | const dest_payload_ty = dest_ty.errorUnionPayload(zcu); |
| 22409 | 22407 | 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)}); | |
| 22412 | 22410 | try addDeclaredHereNote(sema, msg, dest_ty); |
| 22413 | 22411 | try addDeclaredHereNote(sema, msg, operand_ty); |
| 22414 | 22412 | break :msg msg; |
| ... | ... | @@ -22453,7 +22451,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22453 | 22451 | break :disjoint true; |
| 22454 | 22452 | }; |
| 22455 | 22453 | 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", .{ | |
| 22457 | 22455 | operand_err_ty.fmt(pt), dest_err_ty.fmt(pt), |
| 22458 | 22456 | }); |
| 22459 | 22457 | } |
| ... | ... | @@ -22473,7 +22471,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData |
| 22473 | 22471 | }; |
| 22474 | 22472 | |
| 22475 | 22473 | 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}'", .{ | |
| 22477 | 22475 | err_name.fmt(ip), dest_err_ty.fmt(pt), |
| 22478 | 22476 | }); |
| 22479 | 22477 | } |
| ... | ... | @@ -22633,13 +22631,15 @@ fn ptrCastFull( |
| 22633 | 22631 | const src_elem_size = src_elem_ty.abiSize(zcu); |
| 22634 | 22632 | const dest_elem_size = dest_elem_ty.abiSize(zcu); |
| 22635 | 22633 | 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 | }); | |
| 22637 | 22637 | } |
| 22638 | 22638 | if (opt_src_len) |src_len| { |
| 22639 | 22639 | const bytes = src_len * src_elem_size; |
| 22640 | 22640 | const dest_len = std.math.divExact(u64, bytes, dest_elem_size) catch switch (src_info.flags.size) { |
| 22641 | 22641 | .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)}), | |
| 22643 | 22643 | else => unreachable, |
| 22644 | 22644 | }; |
| 22645 | 22645 | break :len .{ .constant = dest_len }; |
| ... | ... | @@ -22657,7 +22657,9 @@ fn ptrCastFull( |
| 22657 | 22657 | // The source value has `src_len * src_base_per_elem` values of type `src_base_ty`. |
| 22658 | 22658 | // The result value will have `dest_len * dest_base_per_elem` values of type `dest_base_ty`. |
| 22659 | 22659 | 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 | }); | |
| 22661 | 22663 | } |
| 22662 | 22664 | // `src_base_ty` is comptime-only, so `src_elem_ty` is comptime-only, so `operand_ty` is |
| 22663 | 22665 | // comptime-only, so `operand` is comptime-known, so `opt_src_len` is non-`null`. |
| ... | ... | @@ -22665,7 +22667,7 @@ fn ptrCastFull( |
| 22665 | 22667 | const base_len = src_len * src_base_per_elem; |
| 22666 | 22668 | const dest_len = std.math.divExact(u64, base_len, dest_base_per_elem) catch switch (src_info.flags.size) { |
| 22667 | 22669 | .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)}), | |
| 22669 | 22671 | else => unreachable, |
| 22670 | 22672 | }; |
| 22671 | 22673 | break :len .{ .constant = dest_len }; |
| ... | ... | @@ -22726,7 +22728,7 @@ fn ptrCastFull( |
| 22726 | 22728 | ); |
| 22727 | 22729 | if (imc_res == .ok) break :check_child; |
| 22728 | 22730 | 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}'", .{ | |
| 22730 | 22732 | src_child.fmt(pt), dest_child.fmt(pt), |
| 22731 | 22733 | }); |
| 22732 | 22734 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -22753,11 +22755,11 @@ fn ptrCastFull( |
| 22753 | 22755 | } |
| 22754 | 22756 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22755 | 22757 | 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", .{ | |
| 22757 | 22759 | Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema), |
| 22758 | 22760 | }); |
| 22759 | 22761 | } 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}'", .{ | |
| 22761 | 22763 | Value.fromInterned(src_info.sentinel).fmtValueSema(pt, sema), |
| 22762 | 22764 | Value.fromInterned(dest_info.sentinel).fmtValueSema(pt, sema), |
| 22763 | 22765 | }); |
| ... | ... | @@ -22799,7 +22801,7 @@ fn ptrCastFull( |
| 22799 | 22801 | if (dest_allows_zero) break :check_allowzero; |
| 22800 | 22802 | |
| 22801 | 22803 | 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}'", .{ | |
| 22803 | 22805 | operand_ty.fmt(pt), |
| 22804 | 22806 | dest_ty.fmt(pt), |
| 22805 | 22807 | }); |
| ... | ... | @@ -22827,10 +22829,10 @@ fn ptrCastFull( |
| 22827 | 22829 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22828 | 22830 | const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation}); |
| 22829 | 22831 | 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}'", .{ | |
| 22831 | 22833 | operand_ty.fmt(pt), src_align.toByteUnits() orelse 0, |
| 22832 | 22834 | }); |
| 22833 | try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{ | |
| 22835 | try sema.errNote(src, msg, "'{f}' has alignment '{d}'", .{ | |
| 22834 | 22836 | dest_ty.fmt(pt), dest_align.toByteUnits() orelse 0, |
| 22835 | 22837 | }); |
| 22836 | 22838 | try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{}); |
| ... | ... | @@ -22844,10 +22846,10 @@ fn ptrCastFull( |
| 22844 | 22846 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22845 | 22847 | const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation}); |
| 22846 | 22848 | 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}'", .{ | |
| 22848 | 22850 | operand_ty.fmt(pt), @tagName(src_info.flags.address_space), |
| 22849 | 22851 | }); |
| 22850 | try sema.errNote(src, msg, "'{}' has address space '{s}'", .{ | |
| 22852 | try sema.errNote(src, msg, "'{f}' has address space '{s}'", .{ | |
| 22851 | 22853 | dest_ty.fmt(pt), @tagName(dest_info.flags.address_space), |
| 22852 | 22854 | }); |
| 22853 | 22855 | try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{}); |
| ... | ... | @@ -22914,7 +22916,7 @@ fn ptrCastFull( |
| 22914 | 22916 | |
| 22915 | 22917 | if (operand_val.isNull(zcu)) { |
| 22916 | 22918 | 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)}); | |
| 22918 | 22920 | } |
| 22919 | 22921 | if (dest_ty.zigTypeTag(zcu) == .optional) { |
| 22920 | 22922 | 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 |
| 23205 | 23207 | const operand_is_vector = operand_ty.zigTypeTag(zcu) == .vector; |
| 23206 | 23208 | const dest_is_vector = dest_ty.zigTypeTag(zcu) == .vector; |
| 23207 | 23209 | 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) }); | |
| 23209 | 23211 | } |
| 23210 | 23212 | |
| 23211 | 23213 | if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_int) { |
| ... | ... | @@ -23225,7 +23227,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23225 | 23227 | } |
| 23226 | 23228 | |
| 23227 | 23229 | 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}'", .{ | |
| 23229 | 23231 | @tagName(dest_info.signedness), operand_ty.fmt(pt), |
| 23230 | 23232 | }); |
| 23231 | 23233 | } |
| ... | ... | @@ -23234,7 +23236,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23234 | 23236 | const msg = msg: { |
| 23235 | 23237 | const msg = try sema.errMsg( |
| 23236 | 23238 | src, |
| 23237 | "destination type '{}' has more bits than source type '{}'", | |
| 23239 | "destination type '{f}' has more bits than source type '{f}'", | |
| 23238 | 23240 | .{ dest_ty.fmt(pt), operand_ty.fmt(pt) }, |
| 23239 | 23241 | ); |
| 23240 | 23242 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -23352,7 +23354,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23352 | 23354 | return sema.fail( |
| 23353 | 23355 | block, |
| 23354 | 23356 | 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", | |
| 23356 | 23358 | .{ scalar_ty.fmt(pt), bits }, |
| 23357 | 23359 | ); |
| 23358 | 23360 | } |
| ... | ... | @@ -23472,7 +23474,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 23472 | 23474 | try ty.resolveLayout(pt); |
| 23473 | 23475 | switch (ty.zigTypeTag(zcu)) { |
| 23474 | 23476 | .@"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)}), | |
| 23476 | 23478 | } |
| 23477 | 23479 | |
| 23478 | 23480 | const field_index = if (ty.isTuple(zcu)) blk: { |
| ... | ... | @@ -23507,7 +23509,7 @@ fn checkNamespaceType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Com |
| 23507 | 23509 | const zcu = pt.zcu; |
| 23508 | 23510 | switch (ty.zigTypeTag(zcu)) { |
| 23509 | 23511 | .@"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)}), | |
| 23511 | 23513 | } |
| 23512 | 23514 | } |
| 23513 | 23515 | |
| ... | ... | @@ -23518,7 +23520,7 @@ fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileEr |
| 23518 | 23520 | switch (ty.zigTypeTag(zcu)) { |
| 23519 | 23521 | .comptime_int => return true, |
| 23520 | 23522 | .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)}), | |
| 23522 | 23524 | } |
| 23523 | 23525 | } |
| 23524 | 23526 | |
| ... | ... | @@ -23572,7 +23574,7 @@ fn checkPtrOperand( |
| 23572 | 23574 | const msg = msg: { |
| 23573 | 23575 | const msg = try sema.errMsg( |
| 23574 | 23576 | ty_src, |
| 23575 | "expected pointer, found '{}'", | |
| 23577 | "expected pointer, found '{f}'", | |
| 23576 | 23578 | .{ty.fmt(pt)}, |
| 23577 | 23579 | ); |
| 23578 | 23580 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -23586,7 +23588,7 @@ fn checkPtrOperand( |
| 23586 | 23588 | .optional => if (ty.childType(zcu).zigTypeTag(zcu) == .pointer) return, |
| 23587 | 23589 | else => {}, |
| 23588 | 23590 | } |
| 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)}); | |
| 23590 | 23592 | } |
| 23591 | 23593 | |
| 23592 | 23594 | fn checkPtrType( |
| ... | ... | @@ -23604,7 +23606,7 @@ fn checkPtrType( |
| 23604 | 23606 | const msg = msg: { |
| 23605 | 23607 | const msg = try sema.errMsg( |
| 23606 | 23608 | ty_src, |
| 23607 | "expected pointer type, found '{}'", | |
| 23609 | "expected pointer type, found '{f}'", | |
| 23608 | 23610 | .{ty.fmt(pt)}, |
| 23609 | 23611 | ); |
| 23610 | 23612 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -23618,7 +23620,7 @@ fn checkPtrType( |
| 23618 | 23620 | .optional => if (ty.childType(zcu).zigTypeTag(zcu) == .pointer) return, |
| 23619 | 23621 | else => {}, |
| 23620 | 23622 | } |
| 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)}); | |
| 23622 | 23624 | } |
| 23623 | 23625 | |
| 23624 | 23626 | fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| ... | ... | @@ -23629,7 +23631,7 @@ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ |
| 23629 | 23631 | const as = ty.ptrAddressSpace(zcu); |
| 23630 | 23632 | if (target_util.arePointersLogical(target, as)) { |
| 23631 | 23633 | 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)}); | |
| 23633 | 23635 | errdefer msg.destroy(sema.gpa); |
| 23634 | 23636 | try sema.errNote( |
| 23635 | 23637 | src, |
| ... | ... | @@ -23660,7 +23662,7 @@ fn checkVectorElemType( |
| 23660 | 23662 | .optional, .pointer => if (ty.isPtrAtRuntime(zcu)) return, |
| 23661 | 23663 | else => {}, |
| 23662 | 23664 | } |
| 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)}); | |
| 23664 | 23666 | } |
| 23665 | 23667 | |
| 23666 | 23668 | fn checkFloatType( |
| ... | ... | @@ -23673,7 +23675,7 @@ fn checkFloatType( |
| 23673 | 23675 | const zcu = pt.zcu; |
| 23674 | 23676 | switch (ty.zigTypeTag(zcu)) { |
| 23675 | 23677 | .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)}), | |
| 23677 | 23679 | } |
| 23678 | 23680 | } |
| 23679 | 23681 | |
| ... | ... | @@ -23691,7 +23693,7 @@ fn checkNumericType( |
| 23691 | 23693 | .comptime_float, .float, .comptime_int, .int => {}, |
| 23692 | 23694 | else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}), |
| 23693 | 23695 | }, |
| 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)}), | |
| 23695 | 23697 | } |
| 23696 | 23698 | } |
| 23697 | 23699 | |
| ... | ... | @@ -23725,7 +23727,7 @@ fn checkAtomicPtrOperand( |
| 23725 | 23727 | error.BadType => return sema.fail( |
| 23726 | 23728 | block, |
| 23727 | 23729 | 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}'", | |
| 23729 | 23731 | .{elem_ty.fmt(pt)}, |
| 23730 | 23732 | ), |
| 23731 | 23733 | }; |
| ... | ... | @@ -23786,12 +23788,12 @@ fn checkIntOrVector( |
| 23786 | 23788 | const elem_ty = operand_ty.childType(zcu); |
| 23787 | 23789 | switch (elem_ty.zigTypeTag(zcu)) { |
| 23788 | 23790 | .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}'", .{ | |
| 23790 | 23792 | elem_ty.fmt(pt), |
| 23791 | 23793 | }), |
| 23792 | 23794 | } |
| 23793 | 23795 | }, |
| 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}'", .{ | |
| 23795 | 23797 | operand_ty.fmt(pt), |
| 23796 | 23798 | }), |
| 23797 | 23799 | } |
| ... | ... | @@ -23811,12 +23813,12 @@ fn checkIntOrVectorAllowComptime( |
| 23811 | 23813 | const elem_ty = operand_ty.childType(zcu); |
| 23812 | 23814 | switch (elem_ty.zigTypeTag(zcu)) { |
| 23813 | 23815 | .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}'", .{ | |
| 23815 | 23817 | elem_ty.fmt(pt), |
| 23816 | 23818 | }), |
| 23817 | 23819 | } |
| 23818 | 23820 | }, |
| 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}'", .{ | |
| 23820 | 23822 | operand_ty.fmt(pt), |
| 23821 | 23823 | }), |
| 23822 | 23824 | } |
| ... | ... | @@ -23907,7 +23909,7 @@ fn checkVectorizableBinaryOperands( |
| 23907 | 23909 | } |
| 23908 | 23910 | } else { |
| 23909 | 23911 | 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}'", .{ | |
| 23911 | 23913 | lhs_ty.fmt(pt), rhs_ty.fmt(pt), |
| 23912 | 23914 | }); |
| 23913 | 23915 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -24041,7 +24043,7 @@ fn zirCmpxchg( |
| 24041 | 24043 | return sema.fail( |
| 24042 | 24044 | block, |
| 24043 | 24045 | 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}'", | |
| 24045 | 24047 | .{elem_ty.fmt(pt)}, |
| 24046 | 24048 | ); |
| 24047 | 24049 | } |
| ... | ... | @@ -24125,7 +24127,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I |
| 24125 | 24127 | |
| 24126 | 24128 | switch (dest_ty.zigTypeTag(zcu)) { |
| 24127 | 24129 | .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)}), | |
| 24129 | 24131 | } |
| 24130 | 24132 | |
| 24131 | 24133 | const operand = try sema.resolveInst(extra.rhs); |
| ... | ... | @@ -24201,7 +24203,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24201 | 24203 | const zcu = pt.zcu; |
| 24202 | 24204 | |
| 24203 | 24205 | 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)}); | |
| 24205 | 24207 | } |
| 24206 | 24208 | |
| 24207 | 24209 | const scalar_ty = operand_ty.childType(zcu); |
| ... | ... | @@ -24210,13 +24212,13 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24210 | 24212 | switch (operation) { |
| 24211 | 24213 | .And, .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) { |
| 24212 | 24214 | .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}'", .{ | |
| 24214 | 24216 | @tagName(operation), operand_ty.fmt(pt), |
| 24215 | 24217 | }), |
| 24216 | 24218 | }, |
| 24217 | 24219 | .Min, .Max, .Add, .Mul => switch (scalar_ty.zigTypeTag(zcu)) { |
| 24218 | 24220 | .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}'", .{ | |
| 24220 | 24222 | @tagName(operation), operand_ty.fmt(pt), |
| 24221 | 24223 | }), |
| 24222 | 24224 | }, |
| ... | ... | @@ -24270,7 +24272,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 24270 | 24272 | |
| 24271 | 24273 | const mask_len = switch (sema.typeOf(mask).zigTypeTag(zcu)) { |
| 24272 | 24274 | .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)}), | |
| 24274 | 24276 | }; |
| 24275 | 24277 | mask_ty = try pt.vectorType(.{ |
| 24276 | 24278 | .len = @intCast(mask_len), |
| ... | ... | @@ -24297,11 +24299,14 @@ fn analyzeShuffle( |
| 24297 | 24299 | const b_src = block.builtinCallArgSrc(src_node, 2); |
| 24298 | 24300 | const mask_src = block.builtinCallArgSrc(src_node, 3); |
| 24299 | 24301 | |
| 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. | |
| 24301 | 24304 | const a_len: u32 = switch (sema.typeOf(a_uncoerced).zigTypeTag(zcu)) { |
| 24302 | 24305 | .array, .vector => @intCast(sema.typeOf(a_uncoerced).arrayLen(zcu)), |
| 24303 | 24306 | .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 | }), | |
| 24305 | 24310 | }; |
| 24306 | 24311 | const a_ty = try pt.vectorType(.{ .len = a_len, .child = elem_ty.toIntern() }); |
| 24307 | 24312 | const a_coerced = try sema.coerce(block, a_ty, a_uncoerced, a_src); |
| ... | ... | @@ -24310,7 +24315,9 @@ fn analyzeShuffle( |
| 24310 | 24315 | const b_len: u32 = switch (sema.typeOf(b_uncoerced).zigTypeTag(zcu)) { |
| 24311 | 24316 | .array, .vector => @intCast(sema.typeOf(b_uncoerced).arrayLen(zcu)), |
| 24312 | 24317 | .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 | }), | |
| 24314 | 24321 | }; |
| 24315 | 24322 | const b_ty = try pt.vectorType(.{ .len = b_len, .child = elem_ty.toIntern() }); |
| 24316 | 24323 | const b_coerced = try sema.coerce(block, b_ty, b_uncoerced, b_src); |
| ... | ... | @@ -24348,7 +24355,7 @@ fn analyzeShuffle( |
| 24348 | 24355 | if (idx >= a_len) return sema.failWithOwnedErrorMsg(block, msg: { |
| 24349 | 24356 | const msg = try sema.errMsg(mask_src, "mask element at index '{d}' selects out-of-bounds index", .{mask_idx}); |
| 24350 | 24357 | 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) }); | |
| 24352 | 24359 | if (idx < b_len) { |
| 24353 | 24360 | try sema.errNote(b_src, msg, "use '~@as(u32, {d})' to index into second vector given here", .{idx}); |
| 24354 | 24361 | } |
| ... | ... | @@ -24464,7 +24471,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24464 | 24471 | |
| 24465 | 24472 | const vec_len_u64 = switch (pred_ty.zigTypeTag(zcu)) { |
| 24466 | 24473 | .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)}), | |
| 24468 | 24475 | }; |
| 24469 | 24476 | const vec_len: u32 = @intCast(try sema.usizeCast(block, pred_src, vec_len_u64)); |
| 24470 | 24477 | |
| ... | ... | @@ -24724,7 +24731,7 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 24724 | 24731 | |
| 24725 | 24732 | switch (ty.scalarType(zcu).zigTypeTag(zcu)) { |
| 24726 | 24733 | .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)}), | |
| 24728 | 24735 | } |
| 24729 | 24736 | |
| 24730 | 24737 | const runtime_src = if (maybe_mulend1) |mulend1_val| rs: { |
| ... | ... | @@ -24833,7 +24840,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 24833 | 24840 | |
| 24834 | 24841 | const args_ty = sema.typeOf(args); |
| 24835 | 24842 | 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)}); | |
| 24837 | 24844 | } |
| 24838 | 24845 | |
| 24839 | 24846 | 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 |
| 24878 | 24885 | try sema.checkPtrType(block, inst_src, parent_ptr_ty, true); |
| 24879 | 24886 | const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu); |
| 24880 | 24887 | 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)}); | |
| 24882 | 24889 | } |
| 24883 | 24890 | const parent_ty: Type = .fromInterned(parent_ptr_info.child); |
| 24884 | 24891 | switch (parent_ty.zigTypeTag(zcu)) { |
| 24885 | 24892 | .@"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)}), | |
| 24887 | 24894 | } |
| 24888 | 24895 | try parent_ty.resolveLayout(pt); |
| 24889 | 24896 | |
| ... | ... | @@ -25033,7 +25040,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins |
| 25033 | 25040 | } |
| 25034 | 25041 | |
| 25035 | 25042 | 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}'", .{ | |
| 25037 | 25044 | field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt), |
| 25038 | 25045 | }); |
| 25039 | 25046 | } |
| ... | ... | @@ -25492,10 +25499,10 @@ fn zirMemcpy( |
| 25492 | 25499 | const msg = msg: { |
| 25493 | 25500 | const msg = try sema.errMsg(src, "unknown copy length", .{}); |
| 25494 | 25501 | 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", .{ | |
| 25496 | 25503 | dest_ty.fmt(pt), |
| 25497 | 25504 | }); |
| 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", .{ | |
| 25499 | 25506 | src_ty.fmt(pt), |
| 25500 | 25507 | }); |
| 25501 | 25508 | break :msg msg; |
| ... | ... | @@ -25519,7 +25526,7 @@ fn zirMemcpy( |
| 25519 | 25526 | if (imc != .ok) return sema.failWithOwnedErrorMsg(block, msg: { |
| 25520 | 25527 | const msg = try sema.errMsg( |
| 25521 | 25528 | src, |
| 25522 | "pointer element type '{}' cannot coerce into element type '{}'", | |
| 25529 | "pointer element type '{f}' cannot coerce into element type '{f}'", | |
| 25523 | 25530 | .{ src_elem_ty.fmt(pt), dest_elem_ty.fmt(pt) }, |
| 25524 | 25531 | ); |
| 25525 | 25532 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -25538,10 +25545,10 @@ fn zirMemcpy( |
| 25538 | 25545 | const msg = msg: { |
| 25539 | 25546 | const msg = try sema.errMsg(src, "non-matching copy lengths", .{}); |
| 25540 | 25547 | errdefer msg.destroy(sema.gpa); |
| 25541 | try sema.errNote(dest_src, msg, "length {} here", .{ | |
| 25548 | try sema.errNote(dest_src, msg, "length {f} here", .{ | |
| 25542 | 25549 | dest_len_val.fmtValueSema(pt, sema), |
| 25543 | 25550 | }); |
| 25544 | try sema.errNote(src_src, msg, "length {} here", .{ | |
| 25551 | try sema.errNote(src_src, msg, "length {f} here", .{ | |
| 25545 | 25552 | src_len_val.fmtValueSema(pt, sema), |
| 25546 | 25553 | }); |
| 25547 | 25554 | break :msg msg; |
| ... | ... | @@ -25756,7 +25763,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25756 | 25763 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 25757 | 25764 | const msg = try sema.errMsg(src, "unknown @memset length", .{}); |
| 25758 | 25765 | 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", .{ | |
| 25760 | 25767 | dest_ptr_ty.fmt(pt), |
| 25761 | 25768 | }); |
| 25762 | 25769 | break :msg msg; |
| ... | ... | @@ -25964,7 +25971,7 @@ fn zirCUndef( |
| 25964 | 25971 | const src = block.builtinCallArgSrc(extra.node, 0); |
| 25965 | 25972 | |
| 25966 | 25973 | 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}); | |
| 25968 | 25975 | return .void_value; |
| 25969 | 25976 | } |
| 25970 | 25977 | |
| ... | ... | @@ -25977,7 +25984,7 @@ fn zirCInclude( |
| 25977 | 25984 | const src = block.builtinCallArgSrc(extra.node, 0); |
| 25978 | 25985 | |
| 25979 | 25986 | 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}); | |
| 25981 | 25988 | return .void_value; |
| 25982 | 25989 | } |
| 25983 | 25990 | |
| ... | ... | @@ -25996,9 +26003,9 @@ fn zirCDefine( |
| 25996 | 26003 | const rhs = try sema.resolveInst(extra.rhs); |
| 25997 | 26004 | if (sema.typeOf(rhs).zigTypeTag(zcu) != .void) { |
| 25998 | 26005 | 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 }); | |
| 26000 | 26007 | } else { |
| 26001 | try block.c_import_buf.?.writer().print("#define {s}\n", .{name}); | |
| 26008 | try block.c_import_buf.?.print("#define {s}\n", .{name}); | |
| 26002 | 26009 | } |
| 26003 | 26010 | return .void_value; |
| 26004 | 26011 | } |
| ... | ... | @@ -26216,7 +26223,7 @@ fn zirBuiltinExtern( |
| 26216 | 26223 | } |
| 26217 | 26224 | if (!try sema.validateExternType(ty, .other)) { |
| 26218 | 26225 | 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)}); | |
| 26220 | 26227 | errdefer msg.destroy(sema.gpa); |
| 26221 | 26228 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other); |
| 26222 | 26229 | break :msg msg; |
| ... | ... | @@ -26456,7 +26463,7 @@ pub fn validateVarType( |
| 26456 | 26463 | if (is_extern) { |
| 26457 | 26464 | if (!try sema.validateExternType(var_ty, .other)) { |
| 26458 | 26465 | 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)}); | |
| 26460 | 26467 | errdefer msg.destroy(sema.gpa); |
| 26461 | 26468 | try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other); |
| 26462 | 26469 | break :msg msg; |
| ... | ... | @@ -26468,7 +26475,7 @@ pub fn validateVarType( |
| 26468 | 26475 | return sema.fail( |
| 26469 | 26476 | block, |
| 26470 | 26477 | src, |
| 26471 | "non-extern variable with opaque type '{}'", | |
| 26478 | "non-extern variable with opaque type '{f}'", | |
| 26472 | 26479 | .{var_ty.fmt(pt)}, |
| 26473 | 26480 | ); |
| 26474 | 26481 | } |
| ... | ... | @@ -26477,7 +26484,7 @@ pub fn validateVarType( |
| 26477 | 26484 | if (!try var_ty.comptimeOnlySema(pt)) return; |
| 26478 | 26485 | |
| 26479 | 26486 | 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)}); | |
| 26481 | 26488 | errdefer msg.destroy(sema.gpa); |
| 26482 | 26489 | |
| 26483 | 26490 | try sema.explainWhyTypeIsComptime(msg, src, var_ty); |
| ... | ... | @@ -26527,7 +26534,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26527 | 26534 | => return, |
| 26528 | 26535 | |
| 26529 | 26536 | .@"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)}); | |
| 26531 | 26538 | }, |
| 26532 | 26539 | |
| 26533 | 26540 | .type => { |
| ... | ... | @@ -26543,7 +26550,7 @@ fn explainWhyTypeIsComptimeInner( |
| 26543 | 26550 | => return, |
| 26544 | 26551 | |
| 26545 | 26552 | .@"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)}); | |
| 26547 | 26554 | }, |
| 26548 | 26555 | |
| 26549 | 26556 | .array, .vector => { |
| ... | ... | @@ -26730,7 +26737,7 @@ fn explainWhyTypeIsNotExtern( |
| 26730 | 26737 | if (!ty.isConstPtr(zcu) and pointee_ty.zigTypeTag(zcu) == .@"fn") { |
| 26731 | 26738 | try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{}); |
| 26732 | 26739 | } 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)}); | |
| 26734 | 26741 | try sema.explainWhyTypeIsComptime(msg, src_loc, ty); |
| 26735 | 26742 | } |
| 26736 | 26743 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other); |
| ... | ... | @@ -26758,7 +26765,7 @@ fn explainWhyTypeIsNotExtern( |
| 26758 | 26765 | }, |
| 26759 | 26766 | .@"enum" => { |
| 26760 | 26767 | 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)}); | |
| 26762 | 26769 | try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position); |
| 26763 | 26770 | }, |
| 26764 | 26771 | .@"struct" => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}), |
| ... | ... | @@ -27194,7 +27201,7 @@ fn fieldVal( |
| 27194 | 27201 | return sema.fail( |
| 27195 | 27202 | block, |
| 27196 | 27203 | field_name_src, |
| 27197 | "no member named '{}' in '{}'", | |
| 27204 | "no member named '{f}' in '{f}'", | |
| 27198 | 27205 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27199 | 27206 | ); |
| 27200 | 27207 | } |
| ... | ... | @@ -27218,7 +27225,7 @@ fn fieldVal( |
| 27218 | 27225 | return sema.fail( |
| 27219 | 27226 | block, |
| 27220 | 27227 | field_name_src, |
| 27221 | "no member named '{}' in '{}'", | |
| 27228 | "no member named '{f}' in '{f}'", | |
| 27222 | 27229 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27223 | 27230 | ); |
| 27224 | 27231 | } |
| ... | ... | @@ -27238,7 +27245,7 @@ fn fieldVal( |
| 27238 | 27245 | switch (ip.indexToKey(child_type.toIntern())) { |
| 27239 | 27246 | .error_set_type => |error_set_type| blk: { |
| 27240 | 27247 | 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}'", .{ | |
| 27242 | 27249 | field_name.fmt(ip), child_type.fmt(pt), |
| 27243 | 27250 | }); |
| 27244 | 27251 | }, |
| ... | ... | @@ -27293,7 +27300,7 @@ fn fieldVal( |
| 27293 | 27300 | return sema.failWithBadMemberAccess(block, child_type, src, field_name); |
| 27294 | 27301 | }, |
| 27295 | 27302 | 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)}); | |
| 27297 | 27304 | errdefer msg.destroy(sema.gpa); |
| 27298 | 27305 | if (child_type.isSlice(zcu)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); |
| 27299 | 27306 | if (child_type.zigTypeTag(zcu) == .array) try sema.errNote(src, msg, "array values have 'len' member", .{}); |
| ... | ... | @@ -27339,7 +27346,7 @@ fn fieldPtr( |
| 27339 | 27346 | const object_ptr_ty = sema.typeOf(object_ptr); |
| 27340 | 27347 | const object_ty = switch (object_ptr_ty.zigTypeTag(zcu)) { |
| 27341 | 27348 | .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)}), | |
| 27343 | 27350 | }; |
| 27344 | 27351 | |
| 27345 | 27352 | // Zig allows dereferencing a single pointer during field lookup. Note that |
| ... | ... | @@ -27392,7 +27399,7 @@ fn fieldPtr( |
| 27392 | 27399 | return sema.fail( |
| 27393 | 27400 | block, |
| 27394 | 27401 | field_name_src, |
| 27395 | "no member named '{}' in '{}'", | |
| 27402 | "no member named '{f}' in '{f}'", | |
| 27396 | 27403 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27397 | 27404 | ); |
| 27398 | 27405 | } |
| ... | ... | @@ -27447,7 +27454,7 @@ fn fieldPtr( |
| 27447 | 27454 | return sema.fail( |
| 27448 | 27455 | block, |
| 27449 | 27456 | field_name_src, |
| 27450 | "no member named '{}' in '{}'", | |
| 27457 | "no member named '{f}' in '{f}'", | |
| 27451 | 27458 | .{ field_name.fmt(ip), object_ty.fmt(pt) }, |
| 27452 | 27459 | ); |
| 27453 | 27460 | } |
| ... | ... | @@ -27470,7 +27477,7 @@ fn fieldPtr( |
| 27470 | 27477 | if (error_set_type.nameIndex(ip, field_name) != null) { |
| 27471 | 27478 | break :blk; |
| 27472 | 27479 | } |
| 27473 | return sema.fail(block, src, "no error named '{}' in '{}'", .{ | |
| 27480 | return sema.fail(block, src, "no error named '{f}' in '{f}'", .{ | |
| 27474 | 27481 | field_name.fmt(ip), child_type.fmt(pt), |
| 27475 | 27482 | }); |
| 27476 | 27483 | }, |
| ... | ... | @@ -27524,7 +27531,7 @@ fn fieldPtr( |
| 27524 | 27531 | } |
| 27525 | 27532 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 27526 | 27533 | }, |
| 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)}), | |
| 27528 | 27535 | } |
| 27529 | 27536 | }, |
| 27530 | 27537 | .@"struct" => { |
| ... | ... | @@ -27579,7 +27586,7 @@ fn fieldCallBind( |
| 27579 | 27586 | const inner_ty = if (raw_ptr_ty.zigTypeTag(zcu) == .pointer and (raw_ptr_ty.ptrSize(zcu) == .one or raw_ptr_ty.ptrSize(zcu) == .c)) |
| 27580 | 27587 | raw_ptr_ty.childType(zcu) |
| 27581 | 27588 | 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)}); | |
| 27583 | 27590 | |
| 27584 | 27591 | // Optionally dereference a second pointer to get the concrete type. |
| 27585 | 27592 | const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one; |
| ... | ... | @@ -27698,7 +27705,7 @@ fn fieldCallBind( |
| 27698 | 27705 | }; |
| 27699 | 27706 | |
| 27700 | 27707 | 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}'", .{ | |
| 27702 | 27709 | field_name.fmt(ip), |
| 27703 | 27710 | concrete_ty.fmt(pt), |
| 27704 | 27711 | }); |
| ... | ... | @@ -27708,7 +27715,7 @@ fn fieldCallBind( |
| 27708 | 27715 | try sema.errNote( |
| 27709 | 27716 | zcu.navSrcLoc(nav_index), |
| 27710 | 27717 | msg, |
| 27711 | "'{}' is not a member function", | |
| 27718 | "'{f}' is not a member function", | |
| 27712 | 27719 | .{field_name.fmt(ip)}, |
| 27713 | 27720 | ); |
| 27714 | 27721 | } |
| ... | ... | @@ -27776,7 +27783,7 @@ fn namespaceLookup( |
| 27776 | 27783 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| { |
| 27777 | 27784 | if (!lookup.accessible) { |
| 27778 | 27785 | 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'", .{ | |
| 27780 | 27787 | decl_name.fmt(&zcu.intern_pool), |
| 27781 | 27788 | }); |
| 27782 | 27789 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -28014,12 +28021,12 @@ fn tupleFieldIndex( |
| 28014 | 28021 | assert(!field_name.eqlSlice("len", ip)); |
| 28015 | 28022 | if (field_name.toUnsigned(ip)) |field_index| { |
| 28016 | 28023 | 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}'", .{ | |
| 28018 | 28025 | field_name.fmt(ip), tuple_ty.fmt(pt), |
| 28019 | 28026 | }); |
| 28020 | 28027 | } |
| 28021 | 28028 | |
| 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}'", .{ | |
| 28023 | 28030 | field_name.fmt(ip), tuple_ty.fmt(pt), |
| 28024 | 28031 | }); |
| 28025 | 28032 | } |
| ... | ... | @@ -28106,7 +28113,7 @@ fn unionFieldPtr( |
| 28106 | 28113 | const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{}); |
| 28107 | 28114 | errdefer msg.destroy(sema.gpa); |
| 28108 | 28115 | |
| 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", .{ | |
| 28110 | 28117 | field_name.fmt(ip), |
| 28111 | 28118 | }); |
| 28112 | 28119 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | ... | @@ -28140,7 +28147,7 @@ fn unionFieldPtr( |
| 28140 | 28147 | const msg = msg: { |
| 28141 | 28148 | const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?; |
| 28142 | 28149 | 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", .{ | |
| 28144 | 28151 | field_name.fmt(ip), |
| 28145 | 28152 | active_field_name.fmt(ip), |
| 28146 | 28153 | }); |
| ... | ... | @@ -28208,7 +28215,7 @@ fn unionFieldVal( |
| 28208 | 28215 | const msg = msg: { |
| 28209 | 28216 | const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?; |
| 28210 | 28217 | 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", .{ | |
| 28212 | 28219 | field_name.fmt(ip), active_field_name.fmt(ip), |
| 28213 | 28220 | }); |
| 28214 | 28221 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -28266,7 +28273,7 @@ fn elemPtr( |
| 28266 | 28273 | |
| 28267 | 28274 | const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(zcu)) { |
| 28268 | 28275 | .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)}), | |
| 28270 | 28277 | }; |
| 28271 | 28278 | try sema.checkIndexable(block, src, indexable_ty); |
| 28272 | 28279 | |
| ... | ... | @@ -28437,7 +28444,7 @@ fn validateRuntimeElemAccess( |
| 28437 | 28444 | const msg = msg: { |
| 28438 | 28445 | const msg = try sema.errMsg( |
| 28439 | 28446 | 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", | |
| 28441 | 28448 | .{parent_ty.fmt(sema.pt)}, |
| 28442 | 28449 | ); |
| 28443 | 28450 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -28453,7 +28460,7 @@ fn validateRuntimeElemAccess( |
| 28453 | 28460 | const target = zcu.getTarget(); |
| 28454 | 28461 | const as = parent_ty.ptrAddressSpace(zcu); |
| 28455 | 28462 | 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)}); | |
| 28457 | 28464 | } |
| 28458 | 28465 | } |
| 28459 | 28466 | } |
| ... | ... | @@ -29149,7 +29156,7 @@ fn coerceExtra( |
| 29149 | 29156 | return sema.fail( |
| 29150 | 29157 | block, |
| 29151 | 29158 | 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}'", | |
| 29153 | 29160 | .{dest_ty.fmt(pt)}, |
| 29154 | 29161 | ); |
| 29155 | 29162 | } |
| ... | ... | @@ -29176,7 +29183,7 @@ fn coerceExtra( |
| 29176 | 29183 | // pointer to tuple to slice |
| 29177 | 29184 | if (!dest_info.flags.is_const) { |
| 29178 | 29185 | 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)}); | |
| 29180 | 29187 | errdefer err_msg.destroy(sema.gpa); |
| 29181 | 29188 | try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{}); |
| 29182 | 29189 | break :err_msg err_msg; |
| ... | ... | @@ -29231,7 +29238,7 @@ fn coerceExtra( |
| 29231 | 29238 | // comptime-known integer to other number |
| 29232 | 29239 | if (!(try sema.intFitsInType(val, dest_ty, null))) { |
| 29233 | 29240 | 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) }); | |
| 29235 | 29242 | } |
| 29236 | 29243 | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 29237 | 29244 | .undef => try pt.undefRef(dest_ty), |
| ... | ... | @@ -29273,7 +29280,7 @@ fn coerceExtra( |
| 29273 | 29280 | return sema.fail( |
| 29274 | 29281 | block, |
| 29275 | 29282 | inst_src, |
| 29276 | "type '{}' cannot represent float value '{}'", | |
| 29283 | "type '{f}' cannot represent float value '{f}'", | |
| 29277 | 29284 | .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) }, |
| 29278 | 29285 | ); |
| 29279 | 29286 | } |
| ... | ... | @@ -29306,7 +29313,7 @@ fn coerceExtra( |
| 29306 | 29313 | // return sema.fail( |
| 29307 | 29314 | // block, |
| 29308 | 29315 | // inst_src, |
| 29309 | // "type '{}' cannot represent integer value '{}'", | |
| 29316 | // "type '{f}' cannot represent integer value '{}'", | |
| 29310 | 29317 | // .{ dest_ty.fmt(pt), val }, |
| 29311 | 29318 | // ); |
| 29312 | 29319 | //} |
| ... | ... | @@ -29320,7 +29327,7 @@ fn coerceExtra( |
| 29320 | 29327 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); |
| 29321 | 29328 | const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal; |
| 29322 | 29329 | 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}'", .{ | |
| 29324 | 29331 | string.fmt(&zcu.intern_pool), dest_ty.fmt(pt), |
| 29325 | 29332 | }); |
| 29326 | 29333 | }; |
| ... | ... | @@ -29469,11 +29476,11 @@ fn coerceExtra( |
| 29469 | 29476 | } |
| 29470 | 29477 | |
| 29471 | 29478 | 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) }); | |
| 29473 | 29480 | errdefer msg.destroy(sema.gpa); |
| 29474 | 29481 | |
| 29475 | 29482 | 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)}); | |
| 29477 | 29484 | } |
| 29478 | 29485 | |
| 29479 | 29486 | // E!T to T |
| ... | ... | @@ -29662,13 +29669,13 @@ const InMemoryCoercionResult = union(enum) { |
| 29662 | 29669 | break; |
| 29663 | 29670 | }, |
| 29664 | 29671 | .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}'", .{ | |
| 29666 | 29673 | int.wanted.fmt(pt), int.actual.fmtValueSema(pt, sema), |
| 29667 | 29674 | }); |
| 29668 | 29675 | break; |
| 29669 | 29676 | }, |
| 29670 | 29677 | .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}'", .{ | |
| 29672 | 29679 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29673 | 29680 | }); |
| 29674 | 29681 | cur = pair.child; |
| ... | ... | @@ -29681,18 +29688,18 @@ const InMemoryCoercionResult = union(enum) { |
| 29681 | 29688 | }, |
| 29682 | 29689 | .array_sentinel => |sentinel| { |
| 29683 | 29690 | 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}'", .{ | |
| 29685 | 29692 | sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema), |
| 29686 | 29693 | }); |
| 29687 | 29694 | } else { |
| 29688 | try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{ | |
| 29695 | try sema.errNote(src, msg, "destination array requires '{f}' sentinel", .{ | |
| 29689 | 29696 | sentinel.wanted.fmtValueSema(pt, sema), |
| 29690 | 29697 | }); |
| 29691 | 29698 | } |
| 29692 | 29699 | break; |
| 29693 | 29700 | }, |
| 29694 | 29701 | .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}'", .{ | |
| 29696 | 29703 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29697 | 29704 | }); |
| 29698 | 29705 | cur = pair.child; |
| ... | ... | @@ -29704,19 +29711,19 @@ const InMemoryCoercionResult = union(enum) { |
| 29704 | 29711 | break; |
| 29705 | 29712 | }, |
| 29706 | 29713 | .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}'", .{ | |
| 29708 | 29715 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29709 | 29716 | }); |
| 29710 | 29717 | cur = pair.child; |
| 29711 | 29718 | }, |
| 29712 | 29719 | .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}'", .{ | |
| 29714 | 29721 | pair.actual.optionalChild(pt.zcu).fmt(pt), pair.wanted.optionalChild(pt.zcu).fmt(pt), |
| 29715 | 29722 | }); |
| 29716 | 29723 | break; |
| 29717 | 29724 | }, |
| 29718 | 29725 | .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}'", .{ | |
| 29720 | 29727 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29721 | 29728 | }); |
| 29722 | 29729 | cur = pair.child; |
| ... | ... | @@ -29727,7 +29734,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29727 | 29734 | }, |
| 29728 | 29735 | .missing_error => |missing_errors| { |
| 29729 | 29736 | 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)}); | |
| 29731 | 29738 | } |
| 29732 | 29739 | break; |
| 29733 | 29740 | }, |
| ... | ... | @@ -29780,7 +29787,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29780 | 29787 | break; |
| 29781 | 29788 | }, |
| 29782 | 29789 | .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}'", .{ | |
| 29784 | 29791 | param.index, param.actual.fmt(pt), param.wanted.fmt(pt), |
| 29785 | 29792 | }); |
| 29786 | 29793 | cur = param.child; |
| ... | ... | @@ -29790,13 +29797,13 @@ const InMemoryCoercionResult = union(enum) { |
| 29790 | 29797 | break; |
| 29791 | 29798 | }, |
| 29792 | 29799 | .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}'", .{ | |
| 29794 | 29801 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29795 | 29802 | }); |
| 29796 | 29803 | cur = pair.child; |
| 29797 | 29804 | }, |
| 29798 | 29805 | .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}'", .{ | |
| 29800 | 29807 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29801 | 29808 | }); |
| 29802 | 29809 | cur = pair.child; |
| ... | ... | @@ -29807,11 +29814,11 @@ const InMemoryCoercionResult = union(enum) { |
| 29807 | 29814 | }, |
| 29808 | 29815 | .ptr_sentinel => |sentinel| { |
| 29809 | 29816 | 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}'", .{ | |
| 29811 | 29818 | sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema), |
| 29812 | 29819 | }); |
| 29813 | 29820 | } else { |
| 29814 | try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{ | |
| 29821 | try sema.errNote(src, msg, "destination pointer requires '{f}' sentinel", .{ | |
| 29815 | 29822 | sentinel.wanted.fmtValueSema(pt, sema), |
| 29816 | 29823 | }); |
| 29817 | 29824 | } |
| ... | ... | @@ -29825,11 +29832,11 @@ const InMemoryCoercionResult = union(enum) { |
| 29825 | 29832 | const wanted_allow_zero = pair.wanted.ptrAllowsZero(pt.zcu); |
| 29826 | 29833 | const actual_allow_zero = pair.actual.ptrAllowsZero(pt.zcu); |
| 29827 | 29834 | 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}'", .{ | |
| 29829 | 29836 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29830 | 29837 | }); |
| 29831 | 29838 | } 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}'", .{ | |
| 29833 | 29840 | pair.wanted.fmt(pt), pair.actual.fmt(pt), |
| 29834 | 29841 | }); |
| 29835 | 29842 | } |
| ... | ... | @@ -29841,7 +29848,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29841 | 29848 | if (actual_const and !wanted_const) { |
| 29842 | 29849 | try sema.errNote(src, msg, "cast discards const qualifier", .{}); |
| 29843 | 29850 | } 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}'", .{ | |
| 29845 | 29852 | pair.wanted.fmt(pt), pair.actual.fmt(pt), |
| 29846 | 29853 | }); |
| 29847 | 29854 | } |
| ... | ... | @@ -29853,7 +29860,7 @@ const InMemoryCoercionResult = union(enum) { |
| 29853 | 29860 | if (actual_volatile and !wanted_volatile) { |
| 29854 | 29861 | try sema.errNote(src, msg, "cast discards volatile qualifier", .{}); |
| 29855 | 29862 | } 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}'", .{ | |
| 29857 | 29864 | pair.wanted.fmt(pt), pair.actual.fmt(pt), |
| 29858 | 29865 | }); |
| 29859 | 29866 | } |
| ... | ... | @@ -29879,13 +29886,13 @@ const InMemoryCoercionResult = union(enum) { |
| 29879 | 29886 | break; |
| 29880 | 29887 | }, |
| 29881 | 29888 | .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}'", .{ | |
| 29883 | 29890 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29884 | 29891 | }); |
| 29885 | 29892 | break; |
| 29886 | 29893 | }, |
| 29887 | 29894 | .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}'", .{ | |
| 29889 | 29896 | pair.actual.fmt(pt), pair.wanted.fmt(pt), |
| 29890 | 29897 | }); |
| 29891 | 29898 | try sema.errNote(src, msg, "consider using '.ptr'", .{}); |
| ... | ... | @@ -30659,7 +30666,7 @@ fn coerceVarArgParam( |
| 30659 | 30666 | const coerced_ty = sema.typeOf(coerced); |
| 30660 | 30667 | if (!try sema.validateExternType(coerced_ty, .param_ty)) { |
| 30661 | 30668 | 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)}); | |
| 30663 | 30670 | errdefer msg.destroy(sema.gpa); |
| 30664 | 30671 | |
| 30665 | 30672 | try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty); |
| ... | ... | @@ -30762,7 +30769,7 @@ fn storePtr2( |
| 30762 | 30769 | // is not comptime-only. We can hit this case with a `@ptrFromInt` pointer. |
| 30763 | 30770 | if (try elem_ty.comptimeOnlySema(pt)) { |
| 30764 | 30771 | 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)}); | |
| 30766 | 30773 | errdefer msg.destroy(sema.gpa); |
| 30767 | 30774 | try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{}); |
| 30768 | 30775 | break :msg msg; |
| ... | ... | @@ -30795,7 +30802,7 @@ fn storePtr2( |
| 30795 | 30802 | }); |
| 30796 | 30803 | return; |
| 30797 | 30804 | } |
| 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}'", .{ | |
| 30799 | 30806 | ptr_ty.fmt(pt), |
| 30800 | 30807 | }); |
| 30801 | 30808 | } |
| ... | ... | @@ -30964,19 +30971,19 @@ fn storePtrVal( |
| 30964 | 30971 | .{}, |
| 30965 | 30972 | ), |
| 30966 | 30973 | .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)}), | |
| 30968 | 30975 | .null_payload => return sema.fail(block, src, "attempt to use null value", .{}), |
| 30969 | 30976 | .inactive_union_field => return sema.fail(block, src, "access of inactive union field", .{}), |
| 30970 | 30977 | .needed_well_defined => |ty| return sema.fail( |
| 30971 | 30978 | block, |
| 30972 | 30979 | src, |
| 30973 | "comptime dereference requires '{}' to have a well-defined layout", | |
| 30980 | "comptime dereference requires '{f}' to have a well-defined layout", | |
| 30974 | 30981 | .{ty.fmt(pt)}, |
| 30975 | 30982 | ), |
| 30976 | 30983 | .out_of_bounds => |ty| return sema.fail( |
| 30977 | 30984 | block, |
| 30978 | 30985 | src, |
| 30979 | "dereference of '{}' exceeds bounds of containing decl of type '{}'", | |
| 30986 | "dereference of '{f}' exceeds bounds of containing decl of type '{f}'", | |
| 30980 | 30987 | .{ ptr_ty.fmt(pt), ty.fmt(pt) }, |
| 30981 | 30988 | ), |
| 30982 | 30989 | .exceeds_host_size => return sema.fail(block, src, "bit-pointer target exceeds host size", .{}), |
| ... | ... | @@ -31002,7 +31009,7 @@ fn bitCast( |
| 31002 | 31009 | const old_bits = old_ty.bitSize(zcu); |
| 31003 | 31010 | |
| 31004 | 31011 | 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", .{ | |
| 31006 | 31013 | dest_ty.fmt(pt), |
| 31007 | 31014 | dest_bits, |
| 31008 | 31015 | old_ty.fmt(pt), |
| ... | ... | @@ -31120,7 +31127,7 @@ fn coerceCompatiblePtrs( |
| 31120 | 31127 | const inst_ty = sema.typeOf(inst); |
| 31121 | 31128 | if (try sema.resolveValue(inst)) |val| { |
| 31122 | 31129 | 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)}); | |
| 31124 | 31131 | } |
| 31125 | 31132 | // The comptime Value representation is compatible with both types. |
| 31126 | 31133 | return Air.internedToRef( |
| ... | ... | @@ -31166,7 +31173,7 @@ fn coerceEnumToUnion( |
| 31166 | 31173 | |
| 31167 | 31174 | const tag_ty = union_ty.unionTagType(zcu) orelse { |
| 31168 | 31175 | 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}'", .{ | |
| 31170 | 31177 | union_ty.fmt(pt), inst_ty.fmt(pt), |
| 31171 | 31178 | }); |
| 31172 | 31179 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -31180,7 +31187,7 @@ fn coerceEnumToUnion( |
| 31180 | 31187 | const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src); |
| 31181 | 31188 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { |
| 31182 | 31189 | 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}'", .{ | |
| 31184 | 31191 | union_ty.fmt(pt), val.fmtValueSema(pt, sema), |
| 31185 | 31192 | }); |
| 31186 | 31193 | }; |
| ... | ... | @@ -31194,7 +31201,7 @@ fn coerceEnumToUnion( |
| 31194 | 31201 | errdefer msg.destroy(sema.gpa); |
| 31195 | 31202 | |
| 31196 | 31203 | 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", .{ | |
| 31198 | 31205 | field_name.fmt(ip), |
| 31199 | 31206 | }); |
| 31200 | 31207 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | ... | @@ -31205,13 +31212,13 @@ fn coerceEnumToUnion( |
| 31205 | 31212 | const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse { |
| 31206 | 31213 | const msg = msg: { |
| 31207 | 31214 | 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}'", .{ | |
| 31209 | 31216 | inst_ty.fmt(pt), union_ty.fmt(pt), |
| 31210 | 31217 | field_ty.fmt(pt), field_name.fmt(ip), |
| 31211 | 31218 | }); |
| 31212 | 31219 | errdefer msg.destroy(sema.gpa); |
| 31213 | 31220 | |
| 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", .{ | |
| 31215 | 31222 | field_name.fmt(ip), |
| 31216 | 31223 | }); |
| 31217 | 31224 | try sema.addDeclaredHereNote(msg, union_ty); |
| ... | ... | @@ -31227,7 +31234,7 @@ fn coerceEnumToUnion( |
| 31227 | 31234 | |
| 31228 | 31235 | if (tag_ty.isNonexhaustiveEnum(zcu)) { |
| 31229 | 31236 | 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", .{ | |
| 31231 | 31238 | union_ty.fmt(pt), |
| 31232 | 31239 | }); |
| 31233 | 31240 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -31246,7 +31253,7 @@ fn coerceEnumToUnion( |
| 31246 | 31253 | if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .noreturn) { |
| 31247 | 31254 | const err_msg = msg orelse try sema.errMsg( |
| 31248 | 31255 | 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", | |
| 31250 | 31257 | .{ tag_ty.fmt(pt), union_ty.fmt(pt) }, |
| 31251 | 31258 | ); |
| 31252 | 31259 | msg = err_msg; |
| ... | ... | @@ -31269,7 +31276,7 @@ fn coerceEnumToUnion( |
| 31269 | 31276 | const msg = msg: { |
| 31270 | 31277 | const msg = try sema.errMsg( |
| 31271 | 31278 | 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", | |
| 31273 | 31280 | .{ tag_ty.fmt(pt), union_ty.fmt(pt) }, |
| 31274 | 31281 | ); |
| 31275 | 31282 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -31278,7 +31285,7 @@ fn coerceEnumToUnion( |
| 31278 | 31285 | const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index]; |
| 31279 | 31286 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 31280 | 31287 | 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}'", .{ | |
| 31282 | 31289 | field_name.fmt(ip), |
| 31283 | 31290 | field_ty.fmt(pt), |
| 31284 | 31291 | }); |
| ... | ... | @@ -31319,7 +31326,7 @@ fn coerceArrayLike( |
| 31319 | 31326 | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(zcu)); |
| 31320 | 31327 | if (dest_len != inst_len) { |
| 31321 | 31328 | 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}'", .{ | |
| 31323 | 31330 | dest_ty.fmt(pt), inst_ty.fmt(pt), |
| 31324 | 31331 | }); |
| 31325 | 31332 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -31407,7 +31414,7 @@ fn coerceTupleToArray( |
| 31407 | 31414 | |
| 31408 | 31415 | if (dest_len != inst_len) { |
| 31409 | 31416 | 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}'", .{ | |
| 31411 | 31418 | dest_ty.fmt(pt), inst_ty.fmt(pt), |
| 31412 | 31419 | }); |
| 31413 | 31420 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -31883,10 +31890,10 @@ fn analyzeLoad( |
| 31883 | 31890 | const ptr_ty = sema.typeOf(ptr); |
| 31884 | 31891 | const elem_ty = switch (ptr_ty.zigTypeTag(zcu)) { |
| 31885 | 31892 | .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)}), | |
| 31887 | 31894 | }; |
| 31888 | 31895 | 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)}); | |
| 31890 | 31897 | } |
| 31891 | 31898 | |
| 31892 | 31899 | if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| { |
| ... | ... | @@ -31907,7 +31914,7 @@ fn analyzeLoad( |
| 31907 | 31914 | const bin_op = sema.getTmpAir().extraData(Air.Bin, ty_pl.payload).data; |
| 31908 | 31915 | return block.addBinOp(.ptr_elem_val, bin_op.lhs, bin_op.rhs); |
| 31909 | 31916 | } |
| 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}'", .{ | |
| 31911 | 31918 | ptr_ty.fmt(pt), |
| 31912 | 31919 | }); |
| 31913 | 31920 | } |
| ... | ... | @@ -32195,7 +32202,7 @@ fn analyzeSlice( |
| 32195 | 32202 | const ptr_ptr_ty = sema.typeOf(ptr_ptr); |
| 32196 | 32203 | const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(zcu)) { |
| 32197 | 32204 | .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)}), | |
| 32199 | 32206 | }; |
| 32200 | 32207 | |
| 32201 | 32208 | var array_ty = ptr_ptr_child_ty; |
| ... | ... | @@ -32244,7 +32251,7 @@ fn analyzeSlice( |
| 32244 | 32251 | try sema.errNote( |
| 32245 | 32252 | start_src, |
| 32246 | 32253 | msg, |
| 32247 | "expected '{}', found '{}'", | |
| 32254 | "expected '{f}', found '{f}'", | |
| 32248 | 32255 | .{ |
| 32249 | 32256 | Value.zero_comptime_int.fmtValueSema(pt, sema), |
| 32250 | 32257 | start_value.fmtValueSema(pt, sema), |
| ... | ... | @@ -32260,7 +32267,7 @@ fn analyzeSlice( |
| 32260 | 32267 | try sema.errNote( |
| 32261 | 32268 | end_src, |
| 32262 | 32269 | msg, |
| 32263 | "expected '{}', found '{}'", | |
| 32270 | "expected '{f}', found '{f}'", | |
| 32264 | 32271 | .{ |
| 32265 | 32272 | Value.one_comptime_int.fmtValueSema(pt, sema), |
| 32266 | 32273 | end_value.fmtValueSema(pt, sema), |
| ... | ... | @@ -32275,7 +32282,7 @@ fn analyzeSlice( |
| 32275 | 32282 | return sema.fail( |
| 32276 | 32283 | block, |
| 32277 | 32284 | 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", | |
| 32279 | 32286 | .{end_value.fmtValueSema(pt, sema)}, |
| 32280 | 32287 | ); |
| 32281 | 32288 | } |
| ... | ... | @@ -32322,7 +32329,7 @@ fn analyzeSlice( |
| 32322 | 32329 | elem_ty = ptr_ptr_child_ty.childType(zcu); |
| 32323 | 32330 | }, |
| 32324 | 32331 | }, |
| 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)}), | |
| 32326 | 32333 | } |
| 32327 | 32334 | |
| 32328 | 32335 | const ptr = if (slice_ty.isSlice(zcu)) |
| ... | ... | @@ -32369,7 +32376,7 @@ fn analyzeSlice( |
| 32369 | 32376 | return sema.fail( |
| 32370 | 32377 | block, |
| 32371 | 32378 | 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}", | |
| 32373 | 32380 | .{ |
| 32374 | 32381 | end_val.fmtValueSema(pt, sema), |
| 32375 | 32382 | len_val.fmtValueSema(pt, sema), |
| ... | ... | @@ -32414,7 +32421,7 @@ fn analyzeSlice( |
| 32414 | 32421 | return sema.fail( |
| 32415 | 32422 | block, |
| 32416 | 32423 | 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}", | |
| 32418 | 32425 | .{ |
| 32419 | 32426 | end_val.fmtValueSema(pt, sema), |
| 32420 | 32427 | try slice_val.sliceLen(pt), |
| ... | ... | @@ -32473,7 +32480,7 @@ fn analyzeSlice( |
| 32473 | 32480 | return sema.fail( |
| 32474 | 32481 | block, |
| 32475 | 32482 | start_src, |
| 32476 | "start index {} is larger than end index {}", | |
| 32483 | "start index {f} is larger than end index {f}", | |
| 32477 | 32484 | .{ |
| 32478 | 32485 | start_val.fmtValueSema(pt, sema), |
| 32479 | 32486 | end_val.fmtValueSema(pt, sema), |
| ... | ... | @@ -32497,13 +32504,13 @@ fn analyzeSlice( |
| 32497 | 32504 | .needed_well_defined => |ty| return sema.fail( |
| 32498 | 32505 | block, |
| 32499 | 32506 | src, |
| 32500 | "comptime dereference requires '{}' to have a well-defined layout", | |
| 32507 | "comptime dereference requires '{f}' to have a well-defined layout", | |
| 32501 | 32508 | .{ty.fmt(pt)}, |
| 32502 | 32509 | ), |
| 32503 | 32510 | .out_of_bounds => |ty| return sema.fail( |
| 32504 | 32511 | block, |
| 32505 | 32512 | 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}'", | |
| 32507 | 32514 | .{ end_int, ty.fmt(pt) }, |
| 32508 | 32515 | ), |
| 32509 | 32516 | }; |
| ... | ... | @@ -32512,7 +32519,7 @@ fn analyzeSlice( |
| 32512 | 32519 | const msg = msg: { |
| 32513 | 32520 | const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{}); |
| 32514 | 32521 | errdefer msg.destroy(sema.gpa); |
| 32515 | try sema.errNote(src, msg, "expected '{}', found '{}'", .{ | |
| 32522 | try sema.errNote(src, msg, "expected '{f}', found '{f}'", .{ | |
| 32516 | 32523 | expected_sentinel.fmtValueSema(pt, sema), |
| 32517 | 32524 | actual_sentinel.fmtValueSema(pt, sema), |
| 32518 | 32525 | }); |
| ... | ... | @@ -33400,7 +33407,7 @@ const PeerResolveResult = union(enum) { |
| 33400 | 33407 | }; |
| 33401 | 33408 | }, |
| 33402 | 33409 | .field_error => |field_error| { |
| 33403 | const fmt = "struct field '{}' has conflicting types"; | |
| 33410 | const fmt = "struct field '{f}' has conflicting types"; | |
| 33404 | 33411 | const args = .{field_error.field_name.fmt(&pt.zcu.intern_pool)}; |
| 33405 | 33412 | if (opt_msg) |msg| { |
| 33406 | 33413 | try sema.errNote(src, msg, fmt, args); |
| ... | ... | @@ -33431,7 +33438,7 @@ const PeerResolveResult = union(enum) { |
| 33431 | 33438 | candidate_srcs.resolve(block, conflict_idx[1]), |
| 33432 | 33439 | }; |
| 33433 | 33440 | |
| 33434 | const fmt = "incompatible types: '{}' and '{}'"; | |
| 33441 | const fmt = "incompatible types: '{f}' and '{f}'"; | |
| 33435 | 33442 | const args = .{ |
| 33436 | 33443 | conflict_tys[0].fmt(pt), |
| 33437 | 33444 | conflict_tys[1].fmt(pt), |
| ... | ... | @@ -33445,8 +33452,8 @@ const PeerResolveResult = union(enum) { |
| 33445 | 33452 | break :msg msg; |
| 33446 | 33453 | }; |
| 33447 | 33454 | |
| 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)}); | |
| 33450 | 33457 | |
| 33451 | 33458 | // No child error |
| 33452 | 33459 | break; |
| ... | ... | @@ -34758,7 +34765,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 34758 | 34765 | if (struct_type.setLayoutWip(ip)) { |
| 34759 | 34766 | const msg = try sema.errMsg( |
| 34760 | 34767 | ty.srcLoc(zcu), |
| 34761 | "struct '{}' depends on itself", | |
| 34768 | "struct '{f}' depends on itself", | |
| 34762 | 34769 | .{ty.fmt(pt)}, |
| 34763 | 34770 | ); |
| 34764 | 34771 | return sema.failWithOwnedErrorMsg(null, msg); |
| ... | ... | @@ -34977,13 +34984,13 @@ fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ |
| 34977 | 34984 | const zcu = pt.zcu; |
| 34978 | 34985 | |
| 34979 | 34986 | 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)}); | |
| 34981 | 34988 | } |
| 34982 | 34989 | if (backing_int_ty.bitSize(zcu) != fields_bit_sum) { |
| 34983 | 34990 | return sema.fail( |
| 34984 | 34991 | block, |
| 34985 | 34992 | 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 {}", | |
| 34987 | 34994 | .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(zcu), fields_bit_sum }, |
| 34988 | 34995 | ); |
| 34989 | 34996 | } |
| ... | ... | @@ -34993,7 +35000,7 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { |
| 34993 | 35000 | const pt = sema.pt; |
| 34994 | 35001 | if (!ty.isIndexable(pt.zcu)) { |
| 34995 | 35002 | 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)}); | |
| 34997 | 35004 | errdefer msg.destroy(sema.gpa); |
| 34998 | 35005 | try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{}); |
| 34999 | 35006 | break :msg msg; |
| ... | ... | @@ -35017,7 +35024,7 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void |
| 35017 | 35024 | } |
| 35018 | 35025 | } |
| 35019 | 35026 | 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)}); | |
| 35021 | 35028 | errdefer msg.destroy(sema.gpa); |
| 35022 | 35029 | try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{}); |
| 35023 | 35030 | break :msg msg; |
| ... | ... | @@ -35085,7 +35092,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35085 | 35092 | .field_types_wip, .layout_wip => { |
| 35086 | 35093 | const msg = try sema.errMsg( |
| 35087 | 35094 | ty.srcLoc(pt.zcu), |
| 35088 | "union '{}' depends on itself", | |
| 35095 | "union '{f}' depends on itself", | |
| 35089 | 35096 | .{ty.fmt(pt)}, |
| 35090 | 35097 | ); |
| 35091 | 35098 | return sema.failWithOwnedErrorMsg(null, msg); |
| ... | ... | @@ -35273,7 +35280,7 @@ pub fn resolveStructFieldTypes( |
| 35273 | 35280 | if (struct_type.setFieldTypesWip(ip)) { |
| 35274 | 35281 | const msg = try sema.errMsg( |
| 35275 | 35282 | Type.fromInterned(ty).srcLoc(zcu), |
| 35276 | "struct '{}' depends on itself", | |
| 35283 | "struct '{f}' depends on itself", | |
| 35277 | 35284 | .{Type.fromInterned(ty).fmt(pt)}, |
| 35278 | 35285 | ); |
| 35279 | 35286 | return sema.failWithOwnedErrorMsg(null, msg); |
| ... | ... | @@ -35302,7 +35309,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { |
| 35302 | 35309 | if (struct_type.setInitsWip(ip)) { |
| 35303 | 35310 | const msg = try sema.errMsg( |
| 35304 | 35311 | ty.srcLoc(zcu), |
| 35305 | "struct '{}' depends on itself", | |
| 35312 | "struct '{f}' depends on itself", | |
| 35306 | 35313 | .{ty.fmt(pt)}, |
| 35307 | 35314 | ); |
| 35308 | 35315 | return sema.failWithOwnedErrorMsg(null, msg); |
| ... | ... | @@ -35328,7 +35335,7 @@ pub fn resolveUnionFieldTypes(sema: *Sema, ty: Type, union_type: InternPool.Load |
| 35328 | 35335 | .field_types_wip => { |
| 35329 | 35336 | const msg = try sema.errMsg( |
| 35330 | 35337 | ty.srcLoc(zcu), |
| 35331 | "union '{}' depends on itself", | |
| 35338 | "union '{f}' depends on itself", | |
| 35332 | 35339 | .{ty.fmt(pt)}, |
| 35333 | 35340 | ); |
| 35334 | 35341 | return sema.failWithOwnedErrorMsg(null, msg); |
| ... | ... | @@ -35698,7 +35705,7 @@ fn structFields( |
| 35698 | 35705 | switch (struct_type.layout) { |
| 35699 | 35706 | .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) { |
| 35700 | 35707 | 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)}); | |
| 35702 | 35709 | errdefer msg.destroy(sema.gpa); |
| 35703 | 35710 | |
| 35704 | 35711 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field); |
| ... | ... | @@ -35710,7 +35717,7 @@ fn structFields( |
| 35710 | 35717 | }, |
| 35711 | 35718 | .@"packed" => if (!try sema.validatePackedType(field_ty)) { |
| 35712 | 35719 | 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)}); | |
| 35714 | 35721 | errdefer msg.destroy(sema.gpa); |
| 35715 | 35722 | |
| 35716 | 35723 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty); |
| ... | ... | @@ -35957,7 +35964,7 @@ fn unionFields( |
| 35957 | 35964 | // The provided type is an integer type and we must construct the enum tag type here. |
| 35958 | 35965 | int_tag_ty = provided_ty; |
| 35959 | 35966 | 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)}); | |
| 35961 | 35968 | } |
| 35962 | 35969 | |
| 35963 | 35970 | if (fields_len > 0) { |
| ... | ... | @@ -35966,7 +35973,7 @@ fn unionFields( |
| 35966 | 35973 | const msg = msg: { |
| 35967 | 35974 | const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{}); |
| 35968 | 35975 | 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}", .{ | |
| 35970 | 35977 | int_tag_ty.fmt(pt), |
| 35971 | 35978 | fields_len - 1, |
| 35972 | 35979 | }); |
| ... | ... | @@ -35981,7 +35988,7 @@ fn unionFields( |
| 35981 | 35988 | // The provided type is the enum tag type. |
| 35982 | 35989 | const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) { |
| 35983 | 35990 | .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)}), | |
| 35985 | 35992 | }; |
| 35986 | 35993 | union_type.setTagType(ip, provided_ty.toIntern()); |
| 35987 | 35994 | // The fields of the union must match the enum exactly. |
| ... | ... | @@ -36078,7 +36085,7 @@ fn unionFields( |
| 36078 | 36085 | if (result.overflow) return sema.fail( |
| 36079 | 36086 | &block_scope, |
| 36080 | 36087 | value_src, |
| 36081 | "enumeration value '{}' too large for type '{}'", | |
| 36088 | "enumeration value '{f}' too large for type '{f}'", | |
| 36082 | 36089 | .{ result.val.fmtValueSema(pt, sema), int_tag_ty.fmt(pt) }, |
| 36083 | 36090 | ); |
| 36084 | 36091 | last_tag_val = result.val; |
| ... | ... | @@ -36096,7 +36103,7 @@ fn unionFields( |
| 36096 | 36103 | const msg = msg: { |
| 36097 | 36104 | const msg = try sema.errMsg( |
| 36098 | 36105 | value_src, |
| 36099 | "enum tag value {} already taken", | |
| 36106 | "enum tag value {f} already taken", | |
| 36100 | 36107 | .{enum_tag_val.fmtValueSema(pt, sema)}, |
| 36101 | 36108 | ); |
| 36102 | 36109 | errdefer msg.destroy(gpa); |
| ... | ... | @@ -36124,7 +36131,7 @@ fn unionFields( |
| 36124 | 36131 | const tag_ty = union_type.tagTypeUnordered(ip); |
| 36125 | 36132 | const tag_info = ip.loadEnumType(tag_ty); |
| 36126 | 36133 | 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}'", .{ | |
| 36128 | 36135 | field_name.fmt(ip), Type.fromInterned(tag_ty).fmt(pt), |
| 36129 | 36136 | }); |
| 36130 | 36137 | }; |
| ... | ... | @@ -36141,7 +36148,7 @@ fn unionFields( |
| 36141 | 36148 | .base_node_inst = Type.fromInterned(tag_ty).typeDeclInstAllowGeneratedTag(zcu).?, |
| 36142 | 36149 | .offset = .{ .container_field_name = enum_index }, |
| 36143 | 36150 | }; |
| 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", .{ | |
| 36145 | 36152 | field_name.fmt(ip), |
| 36146 | 36153 | }); |
| 36147 | 36154 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -36167,7 +36174,7 @@ fn unionFields( |
| 36167 | 36174 | !try sema.validateExternType(field_ty, .union_field)) |
| 36168 | 36175 | { |
| 36169 | 36176 | 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)}); | |
| 36171 | 36178 | errdefer msg.destroy(sema.gpa); |
| 36172 | 36179 | |
| 36173 | 36180 | try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field); |
| ... | ... | @@ -36178,7 +36185,7 @@ fn unionFields( |
| 36178 | 36185 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 36179 | 36186 | } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { |
| 36180 | 36187 | 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)}); | |
| 36182 | 36189 | errdefer msg.destroy(sema.gpa); |
| 36183 | 36190 | |
| 36184 | 36191 | try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty); |
| ... | ... | @@ -36214,7 +36221,7 @@ fn unionFields( |
| 36214 | 36221 | |
| 36215 | 36222 | for (tag_info.names.get(ip), 0..) |field_name, field_index| { |
| 36216 | 36223 | 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", .{ | |
| 36218 | 36225 | field_name.fmt(ip), |
| 36219 | 36226 | }); |
| 36220 | 36227 | } |
| ... | ... | @@ -36250,7 +36257,7 @@ fn generateUnionTagTypeNumbered( |
| 36250 | 36257 | const name = try ip.getOrPutStringFmt( |
| 36251 | 36258 | gpa, |
| 36252 | 36259 | pt.tid, |
| 36253 | "@typeInfo({}).@\"union\".tag_type.?", | |
| 36260 | "@typeInfo({f}).@\"union\".tag_type.?", | |
| 36254 | 36261 | .{union_name.fmt(ip)}, |
| 36255 | 36262 | .no_embedded_nulls, |
| 36256 | 36263 | ); |
| ... | ... | @@ -36286,7 +36293,7 @@ fn generateUnionTagTypeSimple( |
| 36286 | 36293 | const name = try ip.getOrPutStringFmt( |
| 36287 | 36294 | gpa, |
| 36288 | 36295 | pt.tid, |
| 36289 | "@typeInfo({}).@\"union\".tag_type.?", | |
| 36296 | "@typeInfo({f}).@\"union\".tag_type.?", | |
| 36290 | 36297 | .{union_name.fmt(ip)}, |
| 36291 | 36298 | .no_embedded_nulls, |
| 36292 | 36299 | ); |
| ... | ... | @@ -36820,13 +36827,13 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr |
| 36820 | 36827 | .needed_well_defined => |ty| return sema.fail( |
| 36821 | 36828 | block, |
| 36822 | 36829 | src, |
| 36823 | "comptime dereference requires '{}' to have a well-defined layout", | |
| 36830 | "comptime dereference requires '{f}' to have a well-defined layout", | |
| 36824 | 36831 | .{ty.fmt(pt)}, |
| 36825 | 36832 | ), |
| 36826 | 36833 | .out_of_bounds => |ty| return sema.fail( |
| 36827 | 36834 | block, |
| 36828 | 36835 | src, |
| 36829 | "dereference of '{}' exceeds bounds of containing decl of type '{}'", | |
| 36836 | "dereference of '{f}' exceeds bounds of containing decl of type '{f}'", | |
| 36830 | 36837 | .{ ptr_ty.fmt(pt), ty.fmt(pt) }, |
| 36831 | 36838 | ), |
| 36832 | 36839 | } |
| ... | ... | @@ -36846,7 +36853,7 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value |
| 36846 | 36853 | .success => |mv| return .{ .val = try mv.intern(pt, sema.arena) }, |
| 36847 | 36854 | .runtime_load => return .runtime_load, |
| 36848 | 36855 | .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)}), | |
| 36850 | 36857 | .null_payload => return sema.fail(block, src, "attempt to use null value", .{}), |
| 36851 | 36858 | .inactive_union_field => return sema.fail(block, src, "access of inactive union field", .{}), |
| 36852 | 36859 | .needed_well_defined => |ty| return .{ .needed_well_defined = ty }, |
| ... | ... | @@ -36971,12 +36978,12 @@ fn intFromFloatScalar( |
| 36971 | 36978 | |
| 36972 | 36979 | const float = val.toFloat(f128, zcu); |
| 36973 | 36980 | 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}'", .{ | |
| 36975 | 36982 | int_ty.fmt(pt), |
| 36976 | 36983 | }); |
| 36977 | 36984 | } |
| 36978 | 36985 | 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}'", .{ | |
| 36980 | 36987 | int_ty.fmt(pt), |
| 36981 | 36988 | }); |
| 36982 | 36989 | } |
| ... | ... | @@ -36991,7 +36998,7 @@ fn intFromFloatScalar( |
| 36991 | 36998 | .exact => return sema.fail( |
| 36992 | 36999 | block, |
| 36993 | 37000 | src, |
| 36994 | "fractional component prevents float value '{}' from coercion to type '{}'", | |
| 37001 | "fractional component prevents float value '{f}' from coercion to type '{f}'", | |
| 36995 | 37002 | .{ val.fmtValueSema(pt, sema), int_ty.fmt(pt) }, |
| 36996 | 37003 | ), |
| 36997 | 37004 | .truncate => {}, |
| ... | ... | @@ -37003,7 +37010,7 @@ fn intFromFloatScalar( |
| 37003 | 37010 | |
| 37004 | 37011 | const int_info = int_ty.intInfo(zcu); |
| 37005 | 37012 | 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}'", .{ | |
| 37007 | 37014 | val.fmtValueSema(pt, sema), int_ty.fmt(pt), |
| 37008 | 37015 | }); |
| 37009 | 37016 | } |
| ... | ... | @@ -37335,9 +37342,9 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc, |
| 37335 | 37342 | |
| 37336 | 37343 | var first_path: std.ArrayListUnmanaged(u8) = .empty; |
| 37337 | 37344 | 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)}); | |
| 37339 | 37346 | } else { |
| 37340 | try first_path.writer(arena).print("v{}", .{intermediate_value_count - 1}); | |
| 37347 | try first_path.print(arena, "v{}", .{intermediate_value_count - 1}); | |
| 37341 | 37348 | } |
| 37342 | 37349 | |
| 37343 | 37350 | const comptime_ptr = try sema.notePathToComptimeAllocPtrInner(val, &first_path); |
| ... | ... | @@ -37362,30 +37369,26 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc, |
| 37362 | 37369 | error.AnalysisFail => unreachable, |
| 37363 | 37370 | }; |
| 37364 | 37371 | |
| 37365 | var second_path: std.ArrayListUnmanaged(u8) = .empty; | |
| 37372 | var second_path_aw: std.io.AllocatingWriter = undefined; | |
| 37373 | second_path_aw.init(arena); | |
| 37366 | 37374 | const inter_name = try std.fmt.allocPrint(arena, "v{d}", .{intermediate_value_count}); |
| 37367 | 37375 | const deriv_start = @import("print_value.zig").printPtrDerivation( |
| 37368 | 37376 | derivation, |
| 37369 | second_path.writer(arena), | |
| 37377 | &second_path_aw.buffered_writer, | |
| 37370 | 37378 | pt, |
| 37371 | 37379 | .lvalue, |
| 37372 | 37380 | .{ .str = inter_name }, |
| 37373 | 37381 | 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); | |
| 37380 | 37383 | |
| 37381 | 37384 | switch (deriv_start) { |
| 37382 | 37385 | .int, .nav_ptr => unreachable, |
| 37383 | 37386 | .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() }); | |
| 37385 | 37388 | return .{ .new_val = .fromInterned(uav.val) }; |
| 37386 | 37389 | }, |
| 37387 | 37390 | .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() }); | |
| 37389 | 37392 | const cta = sema.getComptimeAlloc(cta_info.idx); |
| 37390 | 37393 | if (cta.is_const) { |
| 37391 | 37394 | return .{ .new_val = cta_info.val }; |
| ... | ... | @@ -37395,7 +37398,7 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc, |
| 37395 | 37398 | } |
| 37396 | 37399 | }, |
| 37397 | 37400 | .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() }); | |
| 37399 | 37402 | try sema.errNote(src, msg, "'{s}' is a comptime field", .{inter_name}); |
| 37400 | 37403 | return .done; |
| 37401 | 37404 | }, |
| ... | ... | @@ -37435,7 +37438,7 @@ fn notePathToComptimeAllocPtrInner(sema: *Sema, val: Value, path: *std.ArrayList |
| 37435 | 37438 | const backing_enum = union_ty.unionTagTypeHypothetical(zcu); |
| 37436 | 37439 | const field_idx = backing_enum.enumTagFieldIndex(.fromInterned(un.tag), zcu).?; |
| 37437 | 37440 | 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)}); | |
| 37439 | 37442 | return sema.notePathToComptimeAllocPtrInner(.fromInterned(un.val), path); |
| 37440 | 37443 | }, |
| 37441 | 37444 | .aggregate => |agg| { |
| ... | ... | @@ -37450,17 +37453,17 @@ fn notePathToComptimeAllocPtrInner(sema: *Sema, val: Value, path: *std.ArrayList |
| 37450 | 37453 | }; |
| 37451 | 37454 | const agg_ty: Type = .fromInterned(agg.ty); |
| 37452 | 37455 | 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}), | |
| 37454 | 37457 | .pointer => switch (elem_idx) { |
| 37455 | 37458 | Value.slice_ptr_index => try path.appendSlice(arena, ".ptr"), |
| 37456 | 37459 | Value.slice_len_index => try path.appendSlice(arena, ".len"), |
| 37457 | 37460 | else => unreachable, |
| 37458 | 37461 | }, |
| 37459 | 37462 | .@"struct" => if (agg_ty.isTuple(zcu)) { |
| 37460 | try path.writer(arena).print("[{d}]", .{elem_idx}); | |
| 37463 | try path.print(arena, "[{d}]", .{elem_idx}); | |
| 37461 | 37464 | } else { |
| 37462 | 37465 | 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)}); | |
| 37464 | 37467 | }, |
| 37465 | 37468 | else => unreachable, |
| 37466 | 37469 | } |
| ... | ... | @@ -37737,7 +37740,7 @@ fn resolveDeclaredEnumInner( |
| 37737 | 37740 | if (tag_type_ref != .none) { |
| 37738 | 37741 | const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref); |
| 37739 | 37742 | 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)}); | |
| 37741 | 37744 | } |
| 37742 | 37745 | break :ty ty; |
| 37743 | 37746 | } else if (fields_len == 0) { |
| ... | ... | @@ -37791,7 +37794,7 @@ fn resolveDeclaredEnumInner( |
| 37791 | 37794 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 37792 | 37795 | }; |
| 37793 | 37796 | 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)}); | |
| 37795 | 37798 | errdefer msg.destroy(gpa); |
| 37796 | 37799 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 37797 | 37800 | break :msg msg; |
| ... | ... | @@ -37814,7 +37817,7 @@ fn resolveDeclaredEnumInner( |
| 37814 | 37817 | .offset = .{ .container_field_value = conflict.prev_field_idx }, |
| 37815 | 37818 | }; |
| 37816 | 37819 | 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)}); | |
| 37818 | 37821 | errdefer msg.destroy(gpa); |
| 37819 | 37822 | try sema.errNote(other_field_src, msg, "other occurrence here", .{}); |
| 37820 | 37823 | break :msg msg; |
| ... | ... | @@ -37831,7 +37834,7 @@ fn resolveDeclaredEnumInner( |
| 37831 | 37834 | }; |
| 37832 | 37835 | |
| 37833 | 37836 | 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}'", .{ | |
| 37835 | 37838 | last_tag_val.?.fmtValueSema(pt, sema), int_tag_ty.fmt(pt), |
| 37836 | 37839 | }); |
| 37837 | 37840 | return sema.failWithOwnedErrorMsg(block, msg); |
src/Sema/LowerZon.zig+16-16| ... | ... | @@ -338,7 +338,7 @@ fn failUnsupportedResultType( |
| 338 | 338 | const gpa = sema.gpa; |
| 339 | 339 | const pt = sema.pt; |
| 340 | 340 | 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)}); | |
| 342 | 342 | errdefer msg.destroy(gpa); |
| 343 | 343 | if (opt_note) |n| try sema.errNote(self.import_loc, msg, "{s}", .{n}); |
| 344 | 344 | break :msg msg; |
| ... | ... | @@ -362,7 +362,7 @@ fn lowerExprKnownResTy(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) Com |
| 362 | 362 | return self.lowerExprKnownResTyInner(node, res_ty) catch |err| switch (err) { |
| 363 | 363 | error.WrongType => return self.fail( |
| 364 | 364 | node, |
| 365 | "expected type '{}'", | |
| 365 | "expected type '{f}'", | |
| 366 | 366 | .{res_ty.fmt(pt)}, |
| 367 | 367 | ), |
| 368 | 368 | else => |e| return e, |
| ... | ... | @@ -428,7 +428,7 @@ fn lowerExprKnownResTyInner( |
| 428 | 428 | .frame, |
| 429 | 429 | .@"anyframe", |
| 430 | 430 | .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)}), | |
| 432 | 432 | } |
| 433 | 433 | } |
| 434 | 434 | |
| ... | ... | @@ -458,7 +458,7 @@ fn lowerInt( |
| 458 | 458 | // If lhs is unsigned and rhs is less than 0, we're out of bounds |
| 459 | 459 | if (lhs_info.signedness == .unsigned and rhs < 0) return self.fail( |
| 460 | 460 | node, |
| 461 | "type '{}' cannot represent integer value '{}'", | |
| 461 | "type '{f}' cannot represent integer value '{}'", | |
| 462 | 462 | .{ res_ty.fmt(self.sema.pt), rhs }, |
| 463 | 463 | ); |
| 464 | 464 | |
| ... | ... | @@ -478,7 +478,7 @@ fn lowerInt( |
| 478 | 478 | if (rhs < min_int or rhs > max_int) { |
| 479 | 479 | return self.fail( |
| 480 | 480 | node, |
| 481 | "type '{}' cannot represent integer value '{}'", | |
| 481 | "type '{f}' cannot represent integer value '{}'", | |
| 482 | 482 | .{ res_ty.fmt(self.sema.pt), rhs }, |
| 483 | 483 | ); |
| 484 | 484 | } |
| ... | ... | @@ -496,7 +496,7 @@ fn lowerInt( |
| 496 | 496 | if (!val.fitsInTwosComp(int_info.signedness, int_info.bits)) { |
| 497 | 497 | return self.fail( |
| 498 | 498 | node, |
| 499 | "type '{}' cannot represent integer value '{}'", | |
| 499 | "type '{f}' cannot represent integer value '{f}'", | |
| 500 | 500 | .{ res_ty.fmt(self.sema.pt), val }, |
| 501 | 501 | ); |
| 502 | 502 | } |
| ... | ... | @@ -517,7 +517,7 @@ fn lowerInt( |
| 517 | 517 | switch (big_int.setFloat(val, .trunc)) { |
| 518 | 518 | .inexact => return self.fail( |
| 519 | 519 | node, |
| 520 | "fractional component prevents float value '{}' from coercion to type '{}'", | |
| 520 | "fractional component prevents float value '{}' from coercion to type '{f}'", | |
| 521 | 521 | .{ val, res_ty.fmt(self.sema.pt) }, |
| 522 | 522 | ), |
| 523 | 523 | .exact => {}, |
| ... | ... | @@ -528,7 +528,7 @@ fn lowerInt( |
| 528 | 528 | if (!big_int.toConst().fitsInTwosComp(int_info.signedness, int_info.bits)) { |
| 529 | 529 | return self.fail( |
| 530 | 530 | node, |
| 531 | "type '{}' cannot represent integer value '{}'", | |
| 531 | "type '{}' cannot represent integer value '{f}'", | |
| 532 | 532 | .{ val, res_ty.fmt(self.sema.pt) }, |
| 533 | 533 | ); |
| 534 | 534 | } |
| ... | ... | @@ -550,7 +550,7 @@ fn lowerInt( |
| 550 | 550 | if (val >= out_of_range) { |
| 551 | 551 | return self.fail( |
| 552 | 552 | node, |
| 553 | "type '{}' cannot represent integer value '{}'", | |
| 553 | "type '{f}' cannot represent integer value '{}'", | |
| 554 | 554 | .{ res_ty.fmt(self.sema.pt), val }, |
| 555 | 555 | ); |
| 556 | 556 | } |
| ... | ... | @@ -584,7 +584,7 @@ fn lowerFloat( |
| 584 | 584 | .pos_inf => b: { |
| 585 | 585 | if (res_ty.toIntern() == .comptime_float_type) return self.fail( |
| 586 | 586 | node, |
| 587 | "expected type '{}'", | |
| 587 | "expected type '{f}'", | |
| 588 | 588 | .{res_ty.fmt(self.sema.pt)}, |
| 589 | 589 | ); |
| 590 | 590 | break :b try self.sema.pt.floatValue(res_ty, std.math.inf(f128)); |
| ... | ... | @@ -592,7 +592,7 @@ fn lowerFloat( |
| 592 | 592 | .neg_inf => b: { |
| 593 | 593 | if (res_ty.toIntern() == .comptime_float_type) return self.fail( |
| 594 | 594 | node, |
| 595 | "expected type '{}'", | |
| 595 | "expected type '{f}'", | |
| 596 | 596 | .{res_ty.fmt(self.sema.pt)}, |
| 597 | 597 | ); |
| 598 | 598 | break :b try self.sema.pt.floatValue(res_ty, -std.math.inf(f128)); |
| ... | ... | @@ -600,7 +600,7 @@ fn lowerFloat( |
| 600 | 600 | .nan => b: { |
| 601 | 601 | if (res_ty.toIntern() == .comptime_float_type) return self.fail( |
| 602 | 602 | node, |
| 603 | "expected type '{}'", | |
| 603 | "expected type '{f}'", | |
| 604 | 604 | .{res_ty.fmt(self.sema.pt)}, |
| 605 | 605 | ); |
| 606 | 606 | 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 |
| 661 | 661 | const field_index = res_ty.enumFieldIndex(field_name_interned, self.sema.pt.zcu) orelse { |
| 662 | 662 | return self.fail( |
| 663 | 663 | node, |
| 664 | "enum {} has no member named '{}'", | |
| 664 | "enum {f} has no member named '{f}'", | |
| 665 | 665 | .{ |
| 666 | 666 | res_ty.fmt(self.sema.pt), |
| 667 | 667 | 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 |
| 795 | 795 | const field_node = fields.vals.at(@intCast(i)); |
| 796 | 796 | |
| 797 | 797 | 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)}); | |
| 799 | 799 | }; |
| 800 | 800 | |
| 801 | 801 | 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 |
| 816 | 816 | |
| 817 | 817 | const field_names = struct_info.field_names.get(ip); |
| 818 | 818 | 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)}); | |
| 820 | 820 | } |
| 821 | 821 | |
| 822 | 822 | return self.sema.pt.intern(.{ .aggregate = .{ |
| ... | ... | @@ -934,7 +934,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool. |
| 934 | 934 | .struct_literal => b: { |
| 935 | 935 | const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) { |
| 936 | 936 | .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)}), | |
| 938 | 938 | }; |
| 939 | 939 | if (fields.names.len != 1) { |
| 940 | 940 | return error.WrongType; |
src/Type.zig+67-91| ... | ... | @@ -142,9 +142,9 @@ const FormatContext = struct { |
| 142 | 142 | pt: Zcu.PerThread, |
| 143 | 143 | }; |
| 144 | 144 | |
| 145 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) anyerror!usize { | |
| 145 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) anyerror!void { | |
| 146 | 146 | comptime assert(f.len == 0); |
| 147 | return print(ctx.ty, bw, ctx.pt); | |
| 147 | try print(ctx.ty, bw, ctx.pt); | |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) { |
| ... | ... | @@ -153,20 +153,14 @@ pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) { |
| 153 | 153 | |
| 154 | 154 | /// This is a debug function. In order to print types in a meaningful way |
| 155 | 155 | /// we also need access to the module. |
| 156 | pub 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; | |
| 156 | pub fn dump(start_type: Type, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) anyerror!void { | |
| 163 | 157 | 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}); | |
| 165 | 159 | } |
| 166 | 160 | |
| 167 | 161 | /// Prints a name suitable for `@typeName`. |
| 168 | 162 | /// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels. |
| 169 | pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!usize { | |
| 163 | pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!void { | |
| 170 | 164 | const zcu = pt.zcu; |
| 171 | 165 | const ip = &zcu.intern_pool; |
| 172 | 166 | switch (ip.indexToKey(ty.toIntern())) { |
| ... | ... | @@ -176,23 +170,22 @@ pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!u |
| 176 | 170 | .signed => 'i', |
| 177 | 171 | .unsigned => 'u', |
| 178 | 172 | }; |
| 179 | return bw.print("{c}{d}", .{ sign_char, int_type.bits }); | |
| 173 | try bw.print("{c}{d}", .{ sign_char, int_type.bits }); | |
| 180 | 174 | }, |
| 181 | 175 | .ptr_type => { |
| 182 | var n: usize = 0; | |
| 183 | 176 | const info = ty.ptrInfo(zcu); |
| 184 | 177 | |
| 185 | 178 | if (info.sentinel != .none) switch (info.flags.size) { |
| 186 | 179 | .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)}), | |
| 189 | 182 | } 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("[]"), | |
| 194 | 187 | } |
| 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 "); | |
| 196 | 189 | if (info.flags.alignment != .none or |
| 197 | 190 | info.packed_offset.host_size != 0 or |
| 198 | 191 | info.flags.vector_index != .none) |
| ... | ... | @@ -201,83 +194,72 @@ pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!u |
| 201 | 194 | info.flags.alignment |
| 202 | 195 | else |
| 203 | 196 | 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}); | |
| 205 | 198 | |
| 206 | 199 | 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}", .{ | |
| 208 | 201 | info.packed_offset.bit_offset, info.packed_offset.host_size, |
| 209 | 202 | }); |
| 210 | 203 | } |
| 211 | 204 | if (info.flags.vector_index == .runtime) { |
| 212 | n += try bw.writeAll(":?"); | |
| 205 | try bw.writeAll(":?"); | |
| 213 | 206 | } 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)}); | |
| 215 | 208 | } |
| 216 | n += try bw.writeAll(") "); | |
| 209 | try bw.writeAll(") "); | |
| 217 | 210 | } |
| 218 | 211 | 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)}); | |
| 220 | 213 | } |
| 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 "); | |
| 223 | 216 | |
| 224 | n += try print(Type.fromInterned(info.child), bw, pt); | |
| 225 | return n; | |
| 217 | try print(Type.fromInterned(info.child), bw, pt); | |
| 226 | 218 | }, |
| 227 | 219 | .array_type => |array_type| { |
| 228 | var n: usize = 0; | |
| 229 | 220 | 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); | |
| 232 | 223 | } else { |
| 233 | n += try bw.print("[{d}:{}]", .{ | |
| 224 | try bw.print("[{d}:{f}]", .{ | |
| 234 | 225 | array_type.len, |
| 235 | 226 | Value.fromInterned(array_type.sentinel).fmtValue(pt), |
| 236 | 227 | }); |
| 237 | n += try print(Type.fromInterned(array_type.child), bw, pt); | |
| 228 | try print(Type.fromInterned(array_type.child), bw, pt); | |
| 238 | 229 | } |
| 239 | return n; | |
| 240 | 230 | }, |
| 241 | 231 | .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(")"); | |
| 247 | 235 | }, |
| 248 | 236 | .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); | |
| 253 | 239 | }, |
| 254 | 240 | .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('!'); | |
| 258 | 243 | if (error_union_type.payload_type == .generic_poison_type) { |
| 259 | n += try bw.writeAll("anytype"); | |
| 244 | try bw.writeAll("anytype"); | |
| 260 | 245 | } 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); | |
| 262 | 247 | } |
| 263 | return n; | |
| 264 | 248 | }, |
| 265 | 249 | .inferred_error_set_type => |func_index| { |
| 266 | 250 | 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", .{ | |
| 268 | 252 | func_nav.fqn.fmt(ip), |
| 269 | 253 | }); |
| 270 | 254 | }, |
| 271 | 255 | .error_set_type => |error_set_type| { |
| 272 | var n: usize = 0; | |
| 273 | 256 | const names = error_set_type.names; |
| 274 | n += try bw.writeAll("error{"); | |
| 257 | try bw.writeAll("error{"); | |
| 275 | 258 | 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)}); | |
| 278 | 261 | } |
| 279 | n += try bw.writeAll("}"); | |
| 280 | return n; | |
| 262 | try bw.writeAll("}"); | |
| 281 | 263 | }, |
| 282 | 264 | .simple_type => |s| switch (s) { |
| 283 | 265 | .f16, |
| ... | ... | @@ -318,91 +300,85 @@ pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) anyerror!u |
| 318 | 300 | }, |
| 319 | 301 | .struct_type => { |
| 320 | 302 | const name = ip.loadStructType(ty.toIntern()).name; |
| 321 | return bw.print("{}", .{name.fmt(ip)}); | |
| 303 | return bw.print("{f}", .{name.fmt(ip)}); | |
| 322 | 304 | }, |
| 323 | 305 | .tuple_type => |tuple| { |
| 324 | 306 | if (tuple.types.len == 0) { |
| 325 | 307 | return bw.writeAll("@TypeOf(.{})"); |
| 326 | 308 | } |
| 327 | var n: usize = 0; | |
| 328 | n += try bw.writeAll("struct {"); | |
| 309 | try bw.writeAll("struct {"); | |
| 329 | 310 | 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)}); | |
| 334 | 315 | } |
| 335 | n += try bw.writeAll(" }"); | |
| 336 | return n; | |
| 316 | try bw.writeAll(" }"); | |
| 337 | 317 | }, |
| 338 | 318 | |
| 339 | 319 | .union_type => { |
| 340 | 320 | const name = ip.loadUnionType(ty.toIntern()).name; |
| 341 | return bw.print("{}", .{name.fmt(ip)}); | |
| 321 | return bw.print("{f}", .{name.fmt(ip)}); | |
| 342 | 322 | }, |
| 343 | 323 | .opaque_type => { |
| 344 | 324 | const name = ip.loadOpaqueType(ty.toIntern()).name; |
| 345 | return bw.print("{}", .{name.fmt(ip)}); | |
| 325 | return bw.print("{f}", .{name.fmt(ip)}); | |
| 346 | 326 | }, |
| 347 | 327 | .enum_type => { |
| 348 | 328 | const name = ip.loadEnumType(ty.toIntern()).name; |
| 349 | return bw.print("{}", .{name.fmt(ip)}); | |
| 329 | return bw.print("{f}", .{name.fmt(ip)}); | |
| 350 | 330 | }, |
| 351 | 331 | .func_type => |fn_info| { |
| 352 | var n: usize = 0; | |
| 353 | 332 | if (fn_info.is_noinline) { |
| 354 | n += try bw.writeAll("noinline "); | |
| 333 | try bw.writeAll("noinline "); | |
| 355 | 334 | } |
| 356 | n += try bw.writeAll("fn ("); | |
| 335 | try bw.writeAll("fn ("); | |
| 357 | 336 | const param_types = fn_info.param_types.get(&zcu.intern_pool); |
| 358 | 337 | for (param_types, 0..) |param_ty, i| { |
| 359 | if (i != 0) n += try bw.writeAll(", "); | |
| 338 | if (i != 0) try bw.writeAll(", "); | |
| 360 | 339 | if (std.math.cast(u5, i)) |index| { |
| 361 | 340 | if (fn_info.paramIsComptime(index)) { |
| 362 | n += try bw.writeAll("comptime "); | |
| 341 | try bw.writeAll("comptime "); | |
| 363 | 342 | } |
| 364 | 343 | if (fn_info.paramIsNoalias(index)) { |
| 365 | n += try bw.writeAll("noalias "); | |
| 344 | try bw.writeAll("noalias "); | |
| 366 | 345 | } |
| 367 | 346 | } |
| 368 | 347 | if (param_ty == .generic_poison_type) { |
| 369 | n += try bw.writeAll("anytype"); | |
| 348 | try bw.writeAll("anytype"); | |
| 370 | 349 | } else { |
| 371 | n += try print(Type.fromInterned(param_ty), bw, pt); | |
| 350 | try print(Type.fromInterned(param_ty), bw, pt); | |
| 372 | 351 | } |
| 373 | 352 | } |
| 374 | 353 | if (fn_info.is_var_args) { |
| 375 | 354 | if (param_types.len != 0) { |
| 376 | n += try bw.writeAll(", "); | |
| 355 | try bw.writeAll(", "); | |
| 377 | 356 | } |
| 378 | n += try bw.writeAll("..."); | |
| 357 | try bw.writeAll("..."); | |
| 379 | 358 | } |
| 380 | n += try bw.writeAll(") "); | |
| 359 | try bw.writeAll(") "); | |
| 381 | 360 | if (fn_info.cc != .auto) print_cc: { |
| 382 | 361 | if (zcu.getTarget().cCallingConvention()) |ccc| { |
| 383 | 362 | if (fn_info.cc.eql(ccc)) { |
| 384 | n += try bw.writeAll("callconv(.c) "); | |
| 363 | try bw.writeAll("callconv(.c) "); | |
| 385 | 364 | break :print_cc; |
| 386 | 365 | } |
| 387 | 366 | } |
| 388 | 367 | 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}), | |
| 391 | 370 | } |
| 392 | 371 | } |
| 393 | 372 | if (fn_info.return_type == .generic_poison_type) { |
| 394 | n += try bw.writeAll("anytype"); | |
| 373 | try bw.writeAll("anytype"); | |
| 395 | 374 | } else { |
| 396 | n += try print(Type.fromInterned(fn_info.return_type), bw, pt); | |
| 375 | try print(Type.fromInterned(fn_info.return_type), bw, pt); | |
| 397 | 376 | } |
| 398 | return n; | |
| 399 | 377 | }, |
| 400 | 378 | .anyframe_type => |child| { |
| 401 | 379 | 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); | |
| 406 | 382 | }, |
| 407 | 383 | |
| 408 | 384 | // values, not types |
src/Zcu.zig+60-63| ... | ... | @@ -862,7 +862,7 @@ pub const Namespace = struct { |
| 862 | 862 | try ns.fileScope(zcu).renderFullyQualifiedDebugName(writer); |
| 863 | 863 | break :sep ':'; |
| 864 | 864 | }; |
| 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) }); | |
| 866 | 866 | } |
| 867 | 867 | |
| 868 | 868 | pub fn internFullyQualifiedName( |
| ... | ... | @@ -874,7 +874,7 @@ pub const Namespace = struct { |
| 874 | 874 | ) !InternPool.NullTerminatedString { |
| 875 | 875 | const ns_name = Type.fromInterned(ns.owner_type).containerTypeName(ip); |
| 876 | 876 | 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); | |
| 878 | 878 | } |
| 879 | 879 | }; |
| 880 | 880 | |
| ... | ... | @@ -1101,11 +1101,11 @@ pub const File = struct { |
| 1101 | 1101 | const gpa = pt.zcu.gpa; |
| 1102 | 1102 | const ip = &pt.zcu.intern_pool; |
| 1103 | 1103 | 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); | |
| 1109 | 1109 | } |
| 1110 | 1110 | |
| 1111 | 1111 | pub const Index = InternPool.FileIndex; |
| ... | ... | @@ -1194,13 +1194,8 @@ pub const ErrorMsg = struct { |
| 1194 | 1194 | gpa.destroy(err_msg); |
| 1195 | 1195 | } |
| 1196 | 1196 | |
| 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 .{ | |
| 1204 | 1199 | .src_loc = src_loc, |
| 1205 | 1200 | .msg = try std.fmt.allocPrint(gpa, format, args), |
| 1206 | 1201 | }; |
| ... | ... | @@ -2822,7 +2817,9 @@ comptime { |
| 2822 | 2817 | } |
| 2823 | 2818 | |
| 2824 | 2819 | pub 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); | |
| 2826 | 2823 | } |
| 2827 | 2824 | |
| 2828 | 2825 | pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) !Zir { |
| ... | ... | @@ -3082,7 +3079,7 @@ pub fn markDependeeOutdated( |
| 3082 | 3079 | marked_po: enum { not_marked_po, marked_po }, |
| 3083 | 3080 | dependee: InternPool.Dependee, |
| 3084 | 3081 | ) !void { |
| 3085 | log.debug("outdated dependee: {}", .{zcu.fmtDependee(dependee)}); | |
| 3082 | log.debug("outdated dependee: {f}", .{zcu.fmtDependee(dependee)}); | |
| 3086 | 3083 | var it = zcu.intern_pool.dependencyIterator(dependee); |
| 3087 | 3084 | while (it.next()) |depender| { |
| 3088 | 3085 | if (zcu.outdated.getPtr(depender)) |po_dep_count| { |
| ... | ... | @@ -3090,9 +3087,9 @@ pub fn markDependeeOutdated( |
| 3090 | 3087 | .not_marked_po => {}, |
| 3091 | 3088 | .marked_po => { |
| 3092 | 3089 | 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.* }); | |
| 3094 | 3091 | if (po_dep_count.* == 0) { |
| 3095 | log.debug("outdated ready: {}", .{zcu.fmtAnalUnit(depender)}); | |
| 3092 | log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)}); | |
| 3096 | 3093 | try zcu.outdated_ready.put(zcu.gpa, depender, {}); |
| 3097 | 3094 | } |
| 3098 | 3095 | }, |
| ... | ... | @@ -3113,9 +3110,9 @@ pub fn markDependeeOutdated( |
| 3113 | 3110 | depender, |
| 3114 | 3111 | new_po_dep_count, |
| 3115 | 3112 | ); |
| 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 }); | |
| 3117 | 3114 | if (new_po_dep_count == 0) { |
| 3118 | log.debug("outdated ready: {}", .{zcu.fmtAnalUnit(depender)}); | |
| 3115 | log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)}); | |
| 3119 | 3116 | try zcu.outdated_ready.put(zcu.gpa, depender, {}); |
| 3120 | 3117 | } |
| 3121 | 3118 | // If this is a Decl and was not previously PO, we must recursively |
| ... | ... | @@ -3128,16 +3125,16 @@ pub fn markDependeeOutdated( |
| 3128 | 3125 | } |
| 3129 | 3126 | |
| 3130 | 3127 | pub 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)}); | |
| 3132 | 3129 | var it = zcu.intern_pool.dependencyIterator(dependee); |
| 3133 | 3130 | while (it.next()) |depender| { |
| 3134 | 3131 | if (zcu.outdated.getPtr(depender)) |po_dep_count| { |
| 3135 | 3132 | // This depender is already outdated, but it now has one |
| 3136 | 3133 | // less PO dependency! |
| 3137 | 3134 | 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.* }); | |
| 3139 | 3136 | if (po_dep_count.* == 0) { |
| 3140 | log.debug("outdated ready: {}", .{zcu.fmtAnalUnit(depender)}); | |
| 3137 | log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)}); | |
| 3141 | 3138 | try zcu.outdated_ready.put(zcu.gpa, depender, {}); |
| 3142 | 3139 | } |
| 3143 | 3140 | continue; |
| ... | ... | @@ -3151,11 +3148,11 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 3151 | 3148 | }; |
| 3152 | 3149 | if (ptr.* > 1) { |
| 3153 | 3150 | 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.* }); | |
| 3155 | 3152 | continue; |
| 3156 | 3153 | } |
| 3157 | 3154 | |
| 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) }); | |
| 3159 | 3156 | |
| 3160 | 3157 | // This dependency is no longer PO, i.e. is known to be up-to-date. |
| 3161 | 3158 | assert(zcu.potentially_outdated.swapRemove(depender)); |
| ... | ... | @@ -3184,7 +3181,7 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni |
| 3184 | 3181 | .func => |func_index| .{ .interned = func_index }, // IES |
| 3185 | 3182 | .memoized_state => |stage| .{ .memoized_state = stage }, |
| 3186 | 3183 | }; |
| 3187 | log.debug("potentially outdated dependee: {}", .{zcu.fmtDependee(dependee)}); | |
| 3184 | log.debug("potentially outdated dependee: {f}", .{zcu.fmtDependee(dependee)}); | |
| 3188 | 3185 | var it = ip.dependencyIterator(dependee); |
| 3189 | 3186 | while (it.next()) |po| { |
| 3190 | 3187 | if (zcu.outdated.getPtr(po)) |po_dep_count| { |
| ... | ... | @@ -3194,17 +3191,17 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni |
| 3194 | 3191 | _ = zcu.outdated_ready.swapRemove(po); |
| 3195 | 3192 | } |
| 3196 | 3193 | 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.* }); | |
| 3198 | 3195 | continue; |
| 3199 | 3196 | } |
| 3200 | 3197 | if (zcu.potentially_outdated.getPtr(po)) |n| { |
| 3201 | 3198 | // There is now one more PO dependency. |
| 3202 | 3199 | 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.* }); | |
| 3204 | 3201 | continue; |
| 3205 | 3202 | } |
| 3206 | 3203 | 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) }); | |
| 3208 | 3205 | // This AnalUnit was not already PO, so we must recursively mark its dependers as also PO. |
| 3209 | 3206 | try zcu.markTransitiveDependersPotentiallyOutdated(po); |
| 3210 | 3207 | } |
| ... | ... | @@ -3233,7 +3230,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit { |
| 3233 | 3230 | |
| 3234 | 3231 | if (zcu.outdated_ready.count() > 0) { |
| 3235 | 3232 | const unit = zcu.outdated_ready.keys()[0]; |
| 3236 | log.debug("findOutdatedToAnalyze: trivial {}", .{zcu.fmtAnalUnit(unit)}); | |
| 3233 | log.debug("findOutdatedToAnalyze: trivial {f}", .{zcu.fmtAnalUnit(unit)}); | |
| 3237 | 3234 | return unit; |
| 3238 | 3235 | } |
| 3239 | 3236 | |
| ... | ... | @@ -3284,7 +3281,7 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit { |
| 3284 | 3281 | } |
| 3285 | 3282 | } |
| 3286 | 3283 | |
| 3287 | log.debug("findOutdatedToAnalyze: heuristic returned '{}' ({d} dependers)", .{ | |
| 3284 | log.debug("findOutdatedToAnalyze: heuristic returned '{f}' ({d} dependers)", .{ | |
| 3288 | 3285 | zcu.fmtAnalUnit(chosen_unit.?), |
| 3289 | 3286 | chosen_unit_dependers, |
| 3290 | 3287 | }); |
| ... | ... | @@ -4094,7 +4091,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4094 | 4091 | const referencer = kv.value; |
| 4095 | 4092 | try checked_types.putNoClobber(gpa, ty, {}); |
| 4096 | 4093 | |
| 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)}); | |
| 4098 | 4095 | |
| 4099 | 4096 | // If this type undergoes type resolution, the corresponding `AnalUnit` is automatically referenced. |
| 4100 | 4097 | const has_resolution: bool = switch (ip.indexToKey(ty)) { |
| ... | ... | @@ -4130,7 +4127,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4130 | 4127 | // `comptime` decls are always analyzed. |
| 4131 | 4128 | const unit: AnalUnit = .wrap(.{ .@"comptime" = cu }); |
| 4132 | 4129 | if (!result.contains(unit)) { |
| 4133 | log.debug("type '{}': ref comptime %{}", .{ | |
| 4130 | log.debug("type '{f}': ref comptime %{}", .{ | |
| 4134 | 4131 | Type.fromInterned(ty).containerTypeName(ip).fmt(ip), |
| 4135 | 4132 | @intFromEnum(ip.getComptimeUnit(cu).zir_index.resolve(ip) orelse continue), |
| 4136 | 4133 | }); |
| ... | ... | @@ -4162,7 +4159,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4162 | 4159 | }, |
| 4163 | 4160 | }; |
| 4164 | 4161 | if (want_analysis) { |
| 4165 | log.debug("type '{}': ref test %{}", .{ | |
| 4162 | log.debug("type '{f}': ref test %{}", .{ | |
| 4166 | 4163 | Type.fromInterned(ty).containerTypeName(ip).fmt(ip), |
| 4167 | 4164 | @intFromEnum(inst_info.inst), |
| 4168 | 4165 | }); |
| ... | ... | @@ -4181,7 +4178,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4181 | 4178 | if (decl.linkage == .@"export") { |
| 4182 | 4179 | const unit: AnalUnit = .wrap(.{ .nav_val = nav }); |
| 4183 | 4180 | if (!result.contains(unit)) { |
| 4184 | log.debug("type '{}': ref named %{}", .{ | |
| 4181 | log.debug("type '{f}': ref named %{}", .{ | |
| 4185 | 4182 | Type.fromInterned(ty).containerTypeName(ip).fmt(ip), |
| 4186 | 4183 | @intFromEnum(inst_info.inst), |
| 4187 | 4184 | }); |
| ... | ... | @@ -4197,7 +4194,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4197 | 4194 | if (decl.linkage == .@"export") { |
| 4198 | 4195 | const unit: AnalUnit = .wrap(.{ .nav_val = nav }); |
| 4199 | 4196 | if (!result.contains(unit)) { |
| 4200 | log.debug("type '{}': ref named %{}", .{ | |
| 4197 | log.debug("type '{f}': ref named %{}", .{ | |
| 4201 | 4198 | Type.fromInterned(ty).containerTypeName(ip).fmt(ip), |
| 4202 | 4199 | @intFromEnum(inst_info.inst), |
| 4203 | 4200 | }); |
| ... | ... | @@ -4232,7 +4229,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4232 | 4229 | try unit_queue.put(gpa, other, kv.value); // same reference location |
| 4233 | 4230 | } |
| 4234 | 4231 | |
| 4235 | log.debug("handle unit '{}'", .{zcu.fmtAnalUnit(unit)}); | |
| 4232 | log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)}); | |
| 4236 | 4233 | |
| 4237 | 4234 | if (zcu.reference_table.get(unit)) |first_ref_idx| { |
| 4238 | 4235 | assert(first_ref_idx != std.math.maxInt(u32)); |
| ... | ... | @@ -4240,7 +4237,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4240 | 4237 | while (ref_idx != std.math.maxInt(u32)) { |
| 4241 | 4238 | const ref = zcu.all_references.items[ref_idx]; |
| 4242 | 4239 | if (!result.contains(ref.referenced)) { |
| 4243 | log.debug("unit '{}': ref unit '{}'", .{ | |
| 4240 | log.debug("unit '{f}': ref unit '{f}'", .{ | |
| 4244 | 4241 | zcu.fmtAnalUnit(unit), |
| 4245 | 4242 | zcu.fmtAnalUnit(ref.referenced), |
| 4246 | 4243 | }); |
| ... | ... | @@ -4259,7 +4256,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 4259 | 4256 | while (ref_idx != std.math.maxInt(u32)) { |
| 4260 | 4257 | const ref = zcu.all_type_references.items[ref_idx]; |
| 4261 | 4258 | if (!checked_types.contains(ref.referenced)) { |
| 4262 | log.debug("unit '{}': ref type '{}'", .{ | |
| 4259 | log.debug("unit '{f}': ref type '{f}'", .{ | |
| 4263 | 4260 | zcu.fmtAnalUnit(unit), |
| 4264 | 4261 | Type.fromInterned(ref.referenced).containerTypeName(ip).fmt(ip), |
| 4265 | 4262 | }); |
| ... | ... | @@ -4347,8 +4344,8 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Formatter(formatDe |
| 4347 | 4344 | return .{ .data = .{ .dependee = d, .zcu = zcu } }; |
| 4348 | 4345 | } |
| 4349 | 4346 | |
| 4350 | fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | |
| 4351 | _ = .{ fmt, options }; | |
| 4347 | fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void { | |
| 4348 | _ = fmt; | |
| 4352 | 4349 | const zcu = data.zcu; |
| 4353 | 4350 | const ip = &zcu.intern_pool; |
| 4354 | 4351 | switch (data.unit.unwrap()) { |
| ... | ... | @@ -4356,69 +4353,69 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co |
| 4356 | 4353 | const cu = ip.getComptimeUnit(cu_id); |
| 4357 | 4354 | if (cu.zir_index.resolveFull(ip)) |resolved| { |
| 4358 | 4355 | 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) }); | |
| 4360 | 4357 | } else { |
| 4361 | return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)}); | |
| 4358 | return bw.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)}); | |
| 4362 | 4359 | } |
| 4363 | 4360 | }, |
| 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) }), | |
| 4367 | 4364 | .func => |func| { |
| 4368 | 4365 | 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) }); | |
| 4370 | 4367 | }, |
| 4371 | .memoized_state => return writer.writeAll("memoized_state"), | |
| 4368 | .memoized_state => return bw.writeAll("memoized_state"), | |
| 4372 | 4369 | } |
| 4373 | 4370 | } |
| 4374 | fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | |
| 4375 | _ = .{ fmt, options }; | |
| 4371 | fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void { | |
| 4372 | _ = fmt; | |
| 4376 | 4373 | const zcu = data.zcu; |
| 4377 | 4374 | const ip = &zcu.intern_pool; |
| 4378 | 4375 | switch (data.dependee) { |
| 4379 | 4376 | .src_hash => |ti| { |
| 4380 | 4377 | const info = ti.resolveFull(ip) orelse { |
| 4381 | return writer.writeAll("inst(<lost>)"); | |
| 4378 | return bw.writeAll("inst(<lost>)"); | |
| 4382 | 4379 | }; |
| 4383 | 4380 | 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) }); | |
| 4385 | 4382 | }, |
| 4386 | 4383 | .nav_val => |nav| { |
| 4387 | 4384 | 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)}); | |
| 4389 | 4386 | }, |
| 4390 | 4387 | .nav_ty => |nav| { |
| 4391 | 4388 | 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)}); | |
| 4393 | 4390 | }, |
| 4394 | 4391 | .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)}), | |
| 4397 | 4394 | else => unreachable, |
| 4398 | 4395 | }, |
| 4399 | 4396 | .zon_file => |file| { |
| 4400 | 4397 | 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)}); | |
| 4402 | 4399 | }, |
| 4403 | 4400 | .embed_file => |ef_idx| { |
| 4404 | 4401 | 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)}); | |
| 4406 | 4403 | }, |
| 4407 | 4404 | .namespace => |ti| { |
| 4408 | 4405 | const info = ti.resolveFull(ip) orelse { |
| 4409 | return writer.writeAll("namespace(<lost>)"); | |
| 4406 | return bw.writeAll("namespace(<lost>)"); | |
| 4410 | 4407 | }; |
| 4411 | 4408 | 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) }); | |
| 4413 | 4410 | }, |
| 4414 | 4411 | .namespace_name => |k| { |
| 4415 | 4412 | 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)}); | |
| 4417 | 4414 | }; |
| 4418 | 4415 | 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) }); | |
| 4420 | 4417 | }, |
| 4421 | .memoized_state => return writer.writeAll("memoized_state"), | |
| 4418 | .memoized_state => return bw.writeAll("memoized_state"), | |
| 4422 | 4419 | } |
| 4423 | 4420 | } |
| 4424 | 4421 |
src/Zcu/PerThread.zig+21-21| ... | ... | @@ -190,7 +190,7 @@ pub fn updateFile( |
| 190 | 190 | // failure was a race, or ENOENT, indicating deletion of the |
| 191 | 191 | // directory of our open handle. |
| 192 | 192 | 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", .{ | |
| 194 | 194 | cache_directory, |
| 195 | 195 | }); |
| 196 | 196 | } |
| ... | ... | @@ -202,7 +202,7 @@ pub fn updateFile( |
| 202 | 202 | }) catch |excl_err| switch (excl_err) { |
| 203 | 203 | error.PathAlreadyExists => continue, |
| 204 | 204 | 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", .{ | |
| 206 | 206 | cache_directory, |
| 207 | 207 | }); |
| 208 | 208 | }, |
| ... | ... | @@ -646,7 +646,7 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized |
| 646 | 646 | // If this unit caused the error, it would have an entry in `failed_analysis`. |
| 647 | 647 | // Since it does not, this must be a transitive failure. |
| 648 | 648 | 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)}); | |
| 650 | 650 | } |
| 651 | 651 | break :res .{ !prev_failed, true }; |
| 652 | 652 | }, |
| ... | ... | @@ -751,7 +751,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 751 | 751 | |
| 752 | 752 | const anal_unit: AnalUnit = .wrap(.{ .@"comptime" = cu_id }); |
| 753 | 753 | |
| 754 | log.debug("ensureComptimeUnitUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 754 | log.debug("ensureComptimeUnitUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 755 | 755 | |
| 756 | 756 | assert(!zcu.analysis_in_progress.contains(anal_unit)); |
| 757 | 757 | |
| ... | ... | @@ -802,7 +802,7 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU |
| 802 | 802 | // If this unit caused the error, it would have an entry in `failed_analysis`. |
| 803 | 803 | // Since it does not, this must be a transitive failure. |
| 804 | 804 | 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)}); | |
| 806 | 806 | } |
| 807 | 807 | return error.AnalysisFail; |
| 808 | 808 | }, |
| ... | ... | @@ -832,7 +832,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu |
| 832 | 832 | const anal_unit: AnalUnit = .wrap(.{ .@"comptime" = cu_id }); |
| 833 | 833 | const comptime_unit = ip.getComptimeUnit(cu_id); |
| 834 | 834 | |
| 835 | log.debug("analyzeComptimeUnit {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 835 | log.debug("analyzeComptimeUnit {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 836 | 836 | |
| 837 | 837 | const inst_resolved = comptime_unit.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 838 | 838 | const file = zcu.fileByIndex(inst_resolved.file); |
| ... | ... | @@ -878,7 +878,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu |
| 878 | 878 | .r = .{ .simple = .comptime_keyword }, |
| 879 | 879 | } }, |
| 880 | 880 | .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", .{ | |
| 882 | 882 | Type.fromInterned(zcu.namespacePtr(comptime_unit.namespace).owner_type).containerTypeName(ip).fmt(ip), |
| 883 | 883 | }, .no_embedded_nulls), |
| 884 | 884 | }; |
| ... | ... | @@ -930,7 +930,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu |
| 930 | 930 | const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id }); |
| 931 | 931 | const nav = ip.getNav(nav_id); |
| 932 | 932 | |
| 933 | log.debug("ensureNavValUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 933 | log.debug("ensureNavValUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 934 | 934 | |
| 935 | 935 | // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the |
| 936 | 936 | // 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 |
| 988 | 988 | // If this unit caused the error, it would have an entry in `failed_analysis`. |
| 989 | 989 | // Since it does not, this must be a transitive failure. |
| 990 | 990 | 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)}); | |
| 992 | 992 | } |
| 993 | 993 | break :res .{ !prev_failed, true }; |
| 994 | 994 | }, |
| ... | ... | @@ -1059,7 +1059,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1059 | 1059 | const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id }); |
| 1060 | 1060 | const old_nav = ip.getNav(nav_id); |
| 1061 | 1061 | |
| 1062 | log.debug("analyzeNavVal {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1062 | log.debug("analyzeNavVal {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1063 | 1063 | |
| 1064 | 1064 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 1065 | 1065 | const file = zcu.fileByIndex(inst_resolved.file); |
| ... | ... | @@ -1240,10 +1240,10 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1240 | 1240 | // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`. |
| 1241 | 1241 | if (zir_decl.kind == .@"usingnamespace") { |
| 1242 | 1242 | 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)}); | |
| 1244 | 1244 | } |
| 1245 | 1245 | 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)}); | |
| 1247 | 1247 | } |
| 1248 | 1248 | ip.resolveNavValue(nav_id, .{ |
| 1249 | 1249 | .val = nav_val.toIntern(), |
| ... | ... | @@ -1339,7 +1339,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc |
| 1339 | 1339 | const anal_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id }); |
| 1340 | 1340 | const nav = ip.getNav(nav_id); |
| 1341 | 1341 | |
| 1342 | log.debug("ensureNavTypeUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1342 | log.debug("ensureNavTypeUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1343 | 1343 | |
| 1344 | 1344 | const type_resolved_by_value: bool = from_val: { |
| 1345 | 1345 | 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 |
| 1409 | 1409 | // If this unit caused the error, it would have an entry in `failed_analysis`. |
| 1410 | 1410 | // Since it does not, this must be a transitive failure. |
| 1411 | 1411 | 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)}); | |
| 1413 | 1413 | } |
| 1414 | 1414 | break :res .{ !prev_failed, true }; |
| 1415 | 1415 | }, |
| ... | ... | @@ -1451,7 +1451,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr |
| 1451 | 1451 | const anal_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id }); |
| 1452 | 1452 | const old_nav = ip.getNav(nav_id); |
| 1453 | 1453 | |
| 1454 | log.debug("analyzeNavType {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1454 | log.debug("analyzeNavType {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1455 | 1455 | |
| 1456 | 1456 | const inst_resolved = old_nav.analysis.?.zir_index.resolveFull(ip) orelse return error.AnalysisFail; |
| 1457 | 1457 | const file = zcu.fileByIndex(inst_resolved.file); |
| ... | ... | @@ -1582,7 +1582,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter |
| 1582 | 1582 | const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index); |
| 1583 | 1583 | const anal_unit: AnalUnit = .wrap(.{ .func = func_index }); |
| 1584 | 1584 | |
| 1585 | log.debug("ensureFuncBodyUpToDate {}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1585 | log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)}); | |
| 1586 | 1586 | |
| 1587 | 1587 | const func = zcu.funcInfo(maybe_coerced_func_index); |
| 1588 | 1588 | |
| ... | ... | @@ -1626,7 +1626,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, maybe_coerced_func_index: Inter |
| 1626 | 1626 | // If this function caused the error, it would have an entry in `failed_analysis`. |
| 1627 | 1627 | // Since it does not, this must be a transitive failure. |
| 1628 | 1628 | 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)}); | |
| 1630 | 1630 | } |
| 1631 | 1631 | // We consider the IES to be outdated if the function previously succeeded analysis; in this case, |
| 1632 | 1632 | // we need to re-analyze dependants to ensure they hit a transitive error here, rather than reporting |
| ... | ... | @@ -1696,7 +1696,7 @@ fn analyzeFuncBody( |
| 1696 | 1696 | else |
| 1697 | 1697 | .none; |
| 1698 | 1698 | |
| 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)}); | |
| 1700 | 1700 | |
| 1701 | 1701 | var air = try pt.analyzeFnBodyInner(func_index); |
| 1702 | 1702 | errdefer air.deinit(gpa); |
| ... | ... | @@ -2615,7 +2615,7 @@ const ScanDeclIter = struct { |
| 2615 | 2615 | var gop = try iter.seen_decls.getOrPut(gpa, name); |
| 2616 | 2616 | var next_suffix: u32 = 0; |
| 2617 | 2617 | 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); | |
| 2619 | 2619 | gop = try iter.seen_decls.getOrPut(gpa, name); |
| 2620 | 2620 | next_suffix += 1; |
| 2621 | 2621 | } |
| ... | ... | @@ -2764,7 +2764,7 @@ const ScanDeclIter = struct { |
| 2764 | 2764 | |
| 2765 | 2765 | if (existing_unit == null and (want_analysis or decl.linkage == .@"export")) { |
| 2766 | 2766 | log.debug( |
| 2767 | "scanDecl queue analyze_comptime_unit file='{s}' unit={}", | |
| 2767 | "scanDecl queue analyze_comptime_unit file='{s}' unit={f}", | |
| 2768 | 2768 | .{ namespace.fileScope(zcu).sub_file_path, zcu.fmtAnalUnit(unit) }, |
| 2769 | 2769 | ); |
| 2770 | 2770 | try comp.queueJob(.{ .analyze_comptime_unit = unit }); |
| ... | ... | @@ -3182,7 +3182,7 @@ fn processExportsInner( |
| 3182 | 3182 | if (gop.found_existing) { |
| 3183 | 3183 | new_export.status = .failed_retryable; |
| 3184 | 3184 | 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}", .{ | |
| 3186 | 3186 | new_export.opts.name.fmt(ip), |
| 3187 | 3187 | }); |
| 3188 | 3188 | errdefer msg.destroy(gpa); |
src/arch/aarch64/CodeGen.zig+3-3| ... | ... | @@ -1011,7 +1011,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1011 | 1011 | } |
| 1012 | 1012 | |
| 1013 | 1013 | 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)}); | |
| 1015 | 1015 | }; |
| 1016 | 1016 | // TODO swap this for inst.ty.ptrAlign |
| 1017 | 1017 | const abi_align = elem_ty.abiAlignment(zcu); |
| ... | ... | @@ -1022,7 +1022,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1022 | 1022 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { |
| 1023 | 1023 | const pt = self.pt; |
| 1024 | 1024 | 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)}); | |
| 1026 | 1026 | }; |
| 1027 | 1027 | const abi_align = elem_ty.abiAlignment(pt.zcu); |
| 1028 | 1028 | |
| ... | ... | @@ -4636,7 +4636,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 4636 | 4636 | const mcv = try self.resolveInst(operand); |
| 4637 | 4637 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 4638 | 4638 | |
| 4639 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); | |
| 4639 | log.debug("airDbgVar: %{f}: {f}, {}", .{ inst, ty.fmtDebug(), mcv }); | |
| 4640 | 4640 | |
| 4641 | 4641 | try self.dbg_info_relocs.append(self.gpa, .{ |
| 4642 | 4642 | .tag = tag, |
src/arch/aarch64/Emit.zig+15-18| ... | ... | @@ -70,9 +70,11 @@ const BranchType = enum { |
| 70 | 70 | } |
| 71 | 71 | }; |
| 72 | 72 | |
| 73 | pub fn emitMir( | |
| 74 | emit: *Emit, | |
| 75 | ) !void { | |
| 73 | pub fn emitMir(emit: *Emit) InnerError!void { | |
| 74 | return @errorCast(emit.emitMirInner()); | |
| 75 | } | |
| 76 | ||
| 77 | fn emitMirInner(emit: *Emit) anyerror!void { | |
| 76 | 78 | const mir_tags = emit.mir.instructions.items(.tag); |
| 77 | 79 | |
| 78 | 80 | // Find smallest lowerings for branch instructions |
| ... | ... | @@ -439,7 +441,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 439 | 441 | return error.EmitFail; |
| 440 | 442 | } |
| 441 | 443 | |
| 442 | fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void { | |
| 444 | fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) anyerror!void { | |
| 443 | 445 | const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line); |
| 444 | 446 | const delta_pc: usize = emit.code.items.len - emit.prev_di_pc; |
| 445 | 447 | 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 { |
| 454 | 456 | .plan9 => |dbg_out| { |
| 455 | 457 | if (delta_pc <= 0) return; // only do this when the pc changes |
| 456 | 458 | |
| 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 | ||
| 457 | 463 | // 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)); | |
| 459 | 465 | // increasing the pc |
| 460 | 466 | const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta; |
| 461 | 467 | if (d_pc_p9 > 0) { |
| 462 | 468 | // 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); | |
| 476 | 473 | } else if (d_pc_p9 == 0) { |
| 477 | 474 | // we don't need to do anything, because adding the pc quanta does it for us |
| 478 | 475 | } else unreachable; |
src/arch/arm/CodeGen.zig+3-3| ... | ... | @@ -997,7 +997,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 997 | 997 | } |
| 998 | 998 | |
| 999 | 999 | 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)}); | |
| 1001 | 1001 | }; |
| 1002 | 1002 | // TODO swap this for inst.ty.ptrAlign |
| 1003 | 1003 | const abi_align = elem_ty.abiAlignment(zcu); |
| ... | ... | @@ -1008,7 +1008,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1008 | 1008 | fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue { |
| 1009 | 1009 | const pt = self.pt; |
| 1010 | 1010 | 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)}); | |
| 1012 | 1012 | }; |
| 1013 | 1013 | const abi_align = elem_ty.abiAlignment(pt.zcu); |
| 1014 | 1014 | |
| ... | ... | @@ -4609,7 +4609,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4609 | 4609 | const mcv = try self.resolveInst(operand); |
| 4610 | 4610 | const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); |
| 4611 | 4611 | |
| 4612 | log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), mcv }); | |
| 4612 | log.debug("airDbgVar: %{f}: {f}, {}", .{ inst, ty.fmtDebug(), mcv }); | |
| 4613 | 4613 | |
| 4614 | 4614 | try self.dbg_info_relocs.append(self.gpa, .{ |
| 4615 | 4615 | .tag = tag, |
src/arch/arm/Emit.zig+14-8| ... | ... | @@ -67,9 +67,11 @@ const BranchType = enum { |
| 67 | 67 | } |
| 68 | 68 | }; |
| 69 | 69 | |
| 70 | pub fn emitMir( | |
| 71 | emit: *Emit, | |
| 72 | ) !void { | |
| 70 | pub fn emitMir(emit: *Emit) InnerError!void { | |
| 71 | return @errorCast(emit.emitMirInner()); | |
| 72 | } | |
| 73 | ||
| 74 | fn emitMirInner(emit: *Emit) anyerror!void { | |
| 73 | 75 | const mir_tags = emit.mir.instructions.items(.tag); |
| 74 | 76 | |
| 75 | 77 | // Find smallest lowerings for branch instructions |
| ... | ... | @@ -370,16 +372,20 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void { |
| 370 | 372 | .plan9 => |dbg_out| { |
| 371 | 373 | if (delta_pc <= 0) return; // only do this when the pc changes |
| 372 | 374 | |
| 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 | ||
| 373 | 379 | // 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); | |
| 375 | 381 | // increasing the pc |
| 376 | 382 | const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta; |
| 377 | 383 | if (d_pc_p9 > 0) { |
| 378 | 384 | // 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); | |
| 383 | 389 | } else if (d_pc_p9 == 0) { |
| 384 | 390 | // we don't need to do anything, because adding the pc quanta does it for us |
| 385 | 391 | } else unreachable; |
src/arch/riscv64/CodeGen.zig+50-75| ... | ... | @@ -401,7 +401,7 @@ const InstTracking = struct { |
| 401 | 401 | .reserved_frame => |index| inst_tracking.long = .{ .load_frame = .{ .index = index } }, |
| 402 | 402 | else => unreachable, |
| 403 | 403 | } |
| 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 }); | |
| 405 | 405 | try function.genCopy(function.typeOfIndex(inst), inst_tracking.long, inst_tracking.short); |
| 406 | 406 | } |
| 407 | 407 | |
| ... | ... | @@ -435,7 +435,7 @@ const InstTracking = struct { |
| 435 | 435 | fn trackSpill(inst_tracking: *InstTracking, function: *Func, inst: Air.Inst.Index) !void { |
| 436 | 436 | try function.freeValue(inst_tracking.short); |
| 437 | 437 | inst_tracking.reuseFrame(); |
| 438 | tracking_log.debug("%{d} => {} (spilled)", .{ inst, inst_tracking.* }); | |
| 438 | tracking_log.debug("%{f} => {f} (spilled)", .{ inst, inst_tracking.* }); | |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | 441 | fn verifyMaterialize(inst_tracking: InstTracking, target: InstTracking) void { |
| ... | ... | @@ -499,14 +499,14 @@ const InstTracking = struct { |
| 499 | 499 | else => target.long, |
| 500 | 500 | } else target.long; |
| 501 | 501 | inst_tracking.short = target.short; |
| 502 | tracking_log.debug("%{d} => {} (materialize)", .{ inst, inst_tracking.* }); | |
| 502 | tracking_log.debug("%{f} => {f} (materialize)", .{ inst, inst_tracking.* }); | |
| 503 | 503 | } |
| 504 | 504 | |
| 505 | 505 | fn resurrect(inst_tracking: *InstTracking, inst: Air.Inst.Index, scope_generation: u32) void { |
| 506 | 506 | switch (inst_tracking.short) { |
| 507 | 507 | .dead => |die_generation| if (die_generation >= scope_generation) { |
| 508 | 508 | inst_tracking.reuseFrame(); |
| 509 | tracking_log.debug("%{d} => {} (resurrect)", .{ inst, inst_tracking.* }); | |
| 509 | tracking_log.debug("%{f} => {f} (resurrect)", .{ inst, inst_tracking.* }); | |
| 510 | 510 | }, |
| 511 | 511 | else => {}, |
| 512 | 512 | } |
| ... | ... | @@ -516,7 +516,7 @@ const InstTracking = struct { |
| 516 | 516 | if (inst_tracking.short == .dead) return; |
| 517 | 517 | try function.freeValue(inst_tracking.short); |
| 518 | 518 | 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.* }); | |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | fn reuse( |
| ... | ... | @@ -527,15 +527,15 @@ const InstTracking = struct { |
| 527 | 527 | ) void { |
| 528 | 528 | inst_tracking.short = .{ .dead = function.scope_generation }; |
| 529 | 529 | 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 }) | |
| 531 | 531 | else |
| 532 | tracking_log.debug("tmp => {} (reuse %{d})", .{ inst_tracking.*, old_inst }); | |
| 532 | tracking_log.debug("tmp => {f} (reuse %{f})", .{ inst_tracking.*, old_inst }); | |
| 533 | 533 | } |
| 534 | 534 | |
| 535 | 535 | fn liveOut(inst_tracking: *InstTracking, function: *Func, inst: Air.Inst.Index) void { |
| 536 | 536 | for (inst_tracking.getRegs()) |reg| { |
| 537 | 537 | 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.* }); | |
| 539 | 539 | continue; |
| 540 | 540 | } |
| 541 | 541 | |
| ... | ... | @@ -562,18 +562,13 @@ const InstTracking = struct { |
| 562 | 562 | // Perform side-effects of freeValue manually. |
| 563 | 563 | function.register_manager.freeReg(reg); |
| 564 | 564 | |
| 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 }); | |
| 566 | 566 | } |
| 567 | 567 | } |
| 568 | 568 | |
| 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}); | |
| 577 | 572 | } |
| 578 | 573 | }; |
| 579 | 574 | |
| ... | ... | @@ -802,7 +797,7 @@ pub fn generate( |
| 802 | 797 | function.mir_instructions.deinit(gpa); |
| 803 | 798 | } |
| 804 | 799 | |
| 805 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); | |
| 800 | wip_mir_log.debug("{f}:", .{fmtNav(func.owner_nav, ip)}); | |
| 806 | 801 | |
| 807 | 802 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 808 | 803 | function.frame_allocs.set( |
| ... | ... | @@ -937,12 +932,7 @@ const FormatWipMirData = struct { |
| 937 | 932 | func: *Func, |
| 938 | 933 | inst: Mir.Inst.Index, |
| 939 | 934 | }; |
| 940 | fn formatWipMir( | |
| 941 | data: FormatWipMirData, | |
| 942 | comptime _: []const u8, | |
| 943 | _: std.fmt.FormatOptions, | |
| 944 | writer: anytype, | |
| 945 | ) @TypeOf(writer).Error!void { | |
| 935 | fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void { | |
| 946 | 936 | const pt = data.func.pt; |
| 947 | 937 | const comp = pt.zcu.comp; |
| 948 | 938 | var lower: Lower = .{ |
| ... | ... | @@ -965,11 +955,11 @@ fn formatWipMir( |
| 965 | 955 | lower.err_msg.?.deinit(data.func.gpa); |
| 966 | 956 | lower.err_msg = null; |
| 967 | 957 | } |
| 968 | try writer.writeAll(lower.err_msg.?.msg); | |
| 958 | try bw.writeAll(lower.err_msg.?.msg); | |
| 969 | 959 | return; |
| 970 | 960 | }, |
| 971 | 961 | error.OutOfMemory, error.InvalidInstruction => |e| { |
| 972 | try writer.writeAll(switch (e) { | |
| 962 | try bw.writeAll(switch (e) { | |
| 973 | 963 | error.OutOfMemory => "Out of memory", |
| 974 | 964 | error.InvalidInstruction => "CodeGen failed to find a viable instruction.", |
| 975 | 965 | }); |
| ... | ... | @@ -977,8 +967,8 @@ fn formatWipMir( |
| 977 | 967 | }, |
| 978 | 968 | else => |e| return e, |
| 979 | 969 | }).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}); | |
| 982 | 972 | first = false; |
| 983 | 973 | } |
| 984 | 974 | } |
| ... | ... | @@ -990,13 +980,8 @@ const FormatNavData = struct { |
| 990 | 980 | ip: *const InternPool, |
| 991 | 981 | nav_index: InternPool.Nav.Index, |
| 992 | 982 | }; |
| 993 | fn 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)}); | |
| 983 | fn 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)}); | |
| 1000 | 985 | } |
| 1001 | 986 | fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) { |
| 1002 | 987 | return .{ .data = .{ |
| ... | ... | @@ -1009,12 +994,7 @@ const FormatAirData = struct { |
| 1009 | 994 | func: *Func, |
| 1010 | 995 | inst: Air.Inst.Index, |
| 1011 | 996 | }; |
| 1012 | fn formatAir( | |
| 1013 | data: FormatAirData, | |
| 1014 | comptime _: []const u8, | |
| 1015 | _: std.fmt.FormatOptions, | |
| 1016 | writer: anytype, | |
| 1017 | ) @TypeOf(writer).Error!void { | |
| 997 | fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void { | |
| 1018 | 998 | data.func.air.dumpInst(data.inst, data.func.pt, data.func.liveness); |
| 1019 | 999 | } |
| 1020 | 1000 | fn 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) { |
| 1024 | 1004 | const FormatTrackingData = struct { |
| 1025 | 1005 | func: *Func, |
| 1026 | 1006 | }; |
| 1027 | fn formatTracking( | |
| 1028 | data: FormatTrackingData, | |
| 1029 | comptime _: []const u8, | |
| 1030 | _: std.fmt.FormatOptions, | |
| 1031 | writer: anytype, | |
| 1032 | ) @TypeOf(writer).Error!void { | |
| 1007 | fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void { | |
| 1033 | 1008 | 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.* }); | |
| 1035 | 1010 | } |
| 1036 | 1011 | fn fmtTracking(func: *Func) std.fmt.Formatter(formatTracking) { |
| 1037 | 1012 | return .{ .data = .{ .func = func } }; |
| ... | ... | @@ -1049,7 +1024,7 @@ fn addInst(func: *Func, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 1049 | 1024 | .pseudo_dbg_epilogue_begin, |
| 1050 | 1025 | .pseudo_dead, |
| 1051 | 1026 | => false, |
| 1052 | }) wip_mir_log.debug("{}", .{func.fmtWipMir(result_index)}); | |
| 1027 | }) wip_mir_log.debug("{f}", .{func.fmtWipMir(result_index)}); | |
| 1053 | 1028 | return result_index; |
| 1054 | 1029 | } |
| 1055 | 1030 | |
| ... | ... | @@ -1172,7 +1147,7 @@ fn gen(func: *Func) !void { |
| 1172 | 1147 | func.ret_mcv.long.address().offset(-func.ret_mcv.short.indirect.off), |
| 1173 | 1148 | ); |
| 1174 | 1149 | 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 }); | |
| 1176 | 1151 | }, |
| 1177 | 1152 | else => unreachable, |
| 1178 | 1153 | } |
| ... | ... | @@ -1303,7 +1278,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1303 | 1278 | switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) { |
| 1304 | 1279 | .@"enum" => { |
| 1305 | 1280 | 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)}); | |
| 1307 | 1282 | |
| 1308 | 1283 | const param_regs = abi.Registers.Integer.function_arg_regs; |
| 1309 | 1284 | const ret_reg = param_regs[0]; |
| ... | ... | @@ -1385,7 +1360,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1385 | 1360 | }); |
| 1386 | 1361 | }, |
| 1387 | 1362 | else => return func.fail( |
| 1388 | "TODO implement {s} for {}", | |
| 1363 | "TODO implement {s} for {f}", | |
| 1389 | 1364 | .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) }, |
| 1390 | 1365 | ), |
| 1391 | 1366 | } |
| ... | ... | @@ -1399,8 +1374,8 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1399 | 1374 | |
| 1400 | 1375 | for (body) |inst| { |
| 1401 | 1376 | 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()}); | |
| 1404 | 1379 | |
| 1405 | 1380 | const old_air_bookkeeping = func.air_bookkeeping; |
| 1406 | 1381 | try func.ensureProcessDeathCapacity(Air.Liveness.bpi); |
| ... | ... | @@ -1679,18 +1654,18 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1679 | 1654 | var it = func.register_manager.free_registers.iterator(.{ .kind = .unset }); |
| 1680 | 1655 | while (it.next()) |index| { |
| 1681 | 1656 | 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}); | |
| 1683 | 1658 | const tracking = func.getResolvedInstValue(tracked_inst); |
| 1684 | 1659 | for (tracking.getRegs()) |reg| { |
| 1685 | 1660 | if (RegisterManager.indexOfRegIntoTracked(reg).? == index) break; |
| 1686 | 1661 | } 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 | |
| 1688 | 1663 | , .{ tracked_inst, tracking.getRegs(), RegisterManager.regAtTrackedIndex(@intCast(index)) }); |
| 1689 | 1664 | } |
| 1690 | 1665 | } |
| 1691 | 1666 | } |
| 1692 | 1667 | } |
| 1693 | verbose_tracking_log.debug("{}", .{func.fmtTracking()}); | |
| 1668 | verbose_tracking_log.debug("{f}", .{func.fmtTracking()}); | |
| 1694 | 1669 | } |
| 1695 | 1670 | |
| 1696 | 1671 | fn getValue(func: *Func, value: MCValue, inst: ?Air.Inst.Index) !void { |
| ... | ... | @@ -1713,7 +1688,7 @@ fn freeValue(func: *Func, value: MCValue) !void { |
| 1713 | 1688 | |
| 1714 | 1689 | fn feed(func: *Func, bt: *Air.Liveness.BigTomb, operand: Air.Inst.Ref) !void { |
| 1715 | 1690 | if (bt.feed()) if (operand.toIndex()) |inst| { |
| 1716 | log.debug("feed inst: %{}", .{inst}); | |
| 1691 | log.debug("feed inst: %{f}", .{inst}); | |
| 1717 | 1692 | try func.processDeath(inst); |
| 1718 | 1693 | }; |
| 1719 | 1694 | } |
| ... | ... | @@ -1907,7 +1882,7 @@ fn splitType(func: *Func, ty: Type) ![2]Type { |
| 1907 | 1882 | else => return func.fail("TODO: splitType class {}", .{class}), |
| 1908 | 1883 | }; |
| 1909 | 1884 | } 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)}); | |
| 1911 | 1886 | } |
| 1912 | 1887 | |
| 1913 | 1888 | /// Truncates the value in the register in place. |
| ... | ... | @@ -2008,7 +1983,7 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex { |
| 2008 | 1983 | } |
| 2009 | 1984 | const frame_index: FrameIndex = @enumFromInt(func.frame_allocs.len); |
| 2010 | 1985 | try func.frame_allocs.append(func.gpa, alloc); |
| 2011 | log.debug("allocated frame {}", .{frame_index}); | |
| 1986 | log.debug("allocated frame {f}", .{frame_index}); | |
| 2012 | 1987 | return frame_index; |
| 2013 | 1988 | } |
| 2014 | 1989 | |
| ... | ... | @@ -2020,7 +1995,7 @@ fn allocMemPtr(func: *Func, inst: Air.Inst.Index) !FrameIndex { |
| 2020 | 1995 | const val_ty = ptr_ty.childType(zcu); |
| 2021 | 1996 | return func.allocFrameIndex(FrameAlloc.init(.{ |
| 2022 | 1997 | .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)}); | |
| 2024 | 1999 | }, |
| 2025 | 2000 | .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"), |
| 2026 | 2001 | })); |
| ... | ... | @@ -2160,7 +2135,7 @@ pub fn spillRegisters(func: *Func, comptime registers: []const Register) !void { |
| 2160 | 2135 | /// allocated. A second call to `copyToTmpRegister` may return the same register. |
| 2161 | 2136 | /// This can have a side effect of spilling instructions to the stack to free up a register. |
| 2162 | 2137 | fn 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)}); | |
| 2164 | 2139 | const reg = try func.register_manager.allocReg(null, func.regTempClassForType(ty)); |
| 2165 | 2140 | try func.genSetReg(ty, reg, mcv); |
| 2166 | 2141 | return reg; |
| ... | ... | @@ -2245,7 +2220,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void { |
| 2245 | 2220 | break :result null; // TODO |
| 2246 | 2221 | |
| 2247 | 2222 | 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}", .{ | |
| 2249 | 2224 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 2250 | 2225 | }); |
| 2251 | 2226 | |
| ... | ... | @@ -2633,7 +2608,7 @@ fn genBinOp( |
| 2633 | 2608 | .add_sat, |
| 2634 | 2609 | => { |
| 2635 | 2610 | 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)}); | |
| 2637 | 2612 | |
| 2638 | 2613 | const tmp_reg = try func.copyToTmpRegister(rhs_ty, .{ .register = rhs_reg }); |
| 2639 | 2614 | const tmp_lock = func.register_manager.lockRegAssumeUnused(tmp_reg); |
| ... | ... | @@ -4065,7 +4040,7 @@ fn airGetUnionTag(func: *Func, inst: Air.Inst.Index) !void { |
| 4065 | 4040 | ); |
| 4066 | 4041 | } else { |
| 4067 | 4042 | 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}", | |
| 4069 | 4044 | .{ frame_mcv, tag_ty.fmt(pt) }, |
| 4070 | 4045 | ); |
| 4071 | 4046 | } |
| ... | ... | @@ -4186,7 +4161,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 4186 | 4161 | |
| 4187 | 4162 | switch (scalar_ty.zigTypeTag(zcu)) { |
| 4188 | 4163 | .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)}); | |
| 4190 | 4165 | } else { |
| 4191 | 4166 | const int_info = scalar_ty.intInfo(zcu); |
| 4192 | 4167 | const int_bits = int_info.bits; |
| ... | ... | @@ -4267,7 +4242,7 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 4267 | 4242 | |
| 4268 | 4243 | break :result return_mcv; |
| 4269 | 4244 | }, |
| 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)}), | |
| 4271 | 4246 | } |
| 4272 | 4247 | |
| 4273 | 4248 | break :result .unreach; |
| ... | ... | @@ -4331,7 +4306,7 @@ fn airByteSwap(func: *Func, inst: Air.Inst.Index) !void { |
| 4331 | 4306 | |
| 4332 | 4307 | break :result dest_mcv; |
| 4333 | 4308 | }, |
| 4334 | else => return func.fail("TODO: airByteSwap {}", .{ty.fmt(pt)}), | |
| 4309 | else => return func.fail("TODO: airByteSwap {f}", .{ty.fmt(pt)}), | |
| 4335 | 4310 | } |
| 4336 | 4311 | }; |
| 4337 | 4312 | 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 { |
| 4397 | 4372 | else => return func.fail("TODO: airUnaryMath Float {s}", .{@tagName(tag)}), |
| 4398 | 4373 | } |
| 4399 | 4374 | }, |
| 4400 | else => return func.fail("TODO: airUnaryMath ty: {}", .{ty.fmt(pt)}), | |
| 4375 | else => return func.fail("TODO: airUnaryMath ty: {f}", .{ty.fmt(pt)}), | |
| 4401 | 4376 | } |
| 4402 | 4377 | |
| 4403 | 4378 | break :result MCValue{ .register = dst_reg }; |
| ... | ... | @@ -4497,7 +4472,7 @@ fn load(func: *Func, dst_mcv: MCValue, ptr_mcv: MCValue, ptr_ty: Type) InnerErro |
| 4497 | 4472 | const zcu = pt.zcu; |
| 4498 | 4473 | const dst_ty = ptr_ty.childType(zcu); |
| 4499 | 4474 | |
| 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 }); | |
| 4501 | 4476 | |
| 4502 | 4477 | switch (ptr_mcv) { |
| 4503 | 4478 | .none, |
| ... | ... | @@ -4550,7 +4525,7 @@ fn airStore(func: *Func, inst: Air.Inst.Index, safety: bool) !void { |
| 4550 | 4525 | fn store(func: *Func, ptr_mcv: MCValue, src_mcv: MCValue, ptr_ty: Type) !void { |
| 4551 | 4526 | const zcu = func.pt.zcu; |
| 4552 | 4527 | 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) }); | |
| 4554 | 4529 | |
| 4555 | 4530 | switch (ptr_mcv) { |
| 4556 | 4531 | .none => unreachable, |
| ... | ... | @@ -7305,7 +7280,7 @@ fn airBitCast(func: *Func, inst: Air.Inst.Index) !void { |
| 7305 | 7280 | const bit_size = dst_ty.bitSize(zcu); |
| 7306 | 7281 | if (abi_size * 8 <= bit_size) break :result dst_mcv; |
| 7307 | 7282 | |
| 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) }); | |
| 7309 | 7284 | }; |
| 7310 | 7285 | return func.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 7311 | 7286 | } |
| ... | ... | @@ -8121,7 +8096,7 @@ fn airAggregateInit(func: *Func, inst: Air.Inst.Index) !void { |
| 8121 | 8096 | ); |
| 8122 | 8097 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 8123 | 8098 | }, |
| 8124 | else => return func.fail("TODO: airAggregate {}", .{result_ty.fmt(pt)}), | |
| 8099 | else => return func.fail("TODO: airAggregate {f}", .{result_ty.fmt(pt)}), | |
| 8125 | 8100 | } |
| 8126 | 8101 | }; |
| 8127 | 8102 | |
| ... | ... | @@ -8322,7 +8297,7 @@ fn resolveCallingConventionValues( |
| 8322 | 8297 | }; |
| 8323 | 8298 | |
| 8324 | 8299 | 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 }), | |
| 8326 | 8301 | 1 => ret_tracking[0], |
| 8327 | 8302 | 2 => InstTracking.init(.{ .register_pair = .{ |
| 8328 | 8303 | ret_tracking[0].short.register, ret_tracking[1].short.register, |
| ... | ... | @@ -8377,7 +8352,7 @@ fn resolveCallingConventionValues( |
| 8377 | 8352 | else => return func.fail("TODO: C calling convention arg class {}", .{class}), |
| 8378 | 8353 | } else { |
| 8379 | 8354 | 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 }), | |
| 8381 | 8356 | 1 => arg_mcv[0], |
| 8382 | 8357 | 2 => .{ .register_pair = .{ arg_mcv[0].register, arg_mcv[1].register } }, |
| 8383 | 8358 | }; |
src/arch/riscv64/Emit.zig+20-11| ... | ... | @@ -18,20 +18,28 @@ pub const Error = Lower.Error || error{ |
| 18 | 18 | }; |
| 19 | 19 | |
| 20 | 20 | pub fn emitMir(emit: *Emit) Error!void { |
| 21 | return @errorCast(emit.emitMirInner()); | |
| 22 | } | |
| 23 | ||
| 24 | fn emitMirInner(emit: *Emit) anyerror!void { | |
| 21 | 25 | 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 | ||
| 22 | 30 | log.debug("mir instruction len: {}", .{emit.lower.mir.instructions.len}); |
| 23 | 31 | for (0..emit.lower.mir.instructions.len) |mir_i| { |
| 24 | 32 | const mir_index: Mir.Inst.Index = @intCast(mir_i); |
| 25 | 33 | try emit.code_offset_mapping.putNoClobber( |
| 26 | 34 | emit.lower.allocator, |
| 27 | 35 | mir_index, |
| 28 | @intCast(emit.code.items.len), | |
| 36 | @intCast(bw.count), | |
| 29 | 37 | ); |
| 30 | 38 | const lowered = try emit.lower.lowerMir(mir_index, .{ .allow_frame_locs = true }); |
| 31 | 39 | var lowered_relocs = lowered.relocs; |
| 32 | 40 | 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); | |
| 35 | 43 | |
| 36 | 44 | while (lowered_relocs.len > 0 and |
| 37 | 45 | lowered_relocs[0].lowered_inst_index == lowered_index) : ({ |
| ... | ... | @@ -123,7 +131,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 123 | 131 | log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{ |
| 124 | 132 | emit.prev_di_line, emit.prev_di_column, |
| 125 | 133 | }); |
| 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); | |
| 127 | 135 | }, |
| 128 | 136 | .plan9 => {}, |
| 129 | 137 | .none => {}, |
| ... | ... | @@ -132,6 +140,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 132 | 140 | .pseudo_dbg_line_column => try emit.dbgAdvancePCAndLine( |
| 133 | 141 | mir_inst.data.pseudo_dbg_line_column.line, |
| 134 | 142 | mir_inst.data.pseudo_dbg_line_column.column, |
| 143 | bw.count, | |
| 135 | 144 | ), |
| 136 | 145 | .pseudo_dbg_epilogue_begin => { |
| 137 | 146 | switch (emit.debug_output) { |
| ... | ... | @@ -140,7 +149,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 140 | 149 | log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{ |
| 141 | 150 | emit.prev_di_line, emit.prev_di_column, |
| 142 | 151 | }); |
| 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); | |
| 144 | 153 | }, |
| 145 | 154 | .plan9 => {}, |
| 146 | 155 | .none => {}, |
| ... | ... | @@ -150,7 +159,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 150 | 159 | } |
| 151 | 160 | } |
| 152 | 161 | } |
| 153 | try emit.fixupRelocs(); | |
| 162 | try emit.fixupRelocs(aw.getWritten()); | |
| 154 | 163 | } |
| 155 | 164 | |
| 156 | 165 | pub fn deinit(emit: *Emit) void { |
| ... | ... | @@ -170,14 +179,14 @@ const Reloc = struct { |
| 170 | 179 | fmt: encoding.Lir.Format, |
| 171 | 180 | }; |
| 172 | 181 | |
| 173 | fn fixupRelocs(emit: *Emit) Error!void { | |
| 182 | fn fixupRelocs(emit: *Emit, written: []u8) Error!void { | |
| 174 | 183 | 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)}); | |
| 176 | 185 | const target = emit.code_offset_mapping.get(reloc.target) orelse |
| 177 | 186 | return emit.fail("relocation target not found!", .{}); |
| 178 | 187 | |
| 179 | 188 | 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]; | |
| 181 | 190 | |
| 182 | 191 | switch (reloc.fmt) { |
| 183 | 192 | .J => riscv_util.writeInstJ(code, @bitCast(disp)), |
| ... | ... | @@ -187,9 +196,9 @@ fn fixupRelocs(emit: *Emit) Error!void { |
| 187 | 196 | } |
| 188 | 197 | } |
| 189 | 198 | |
| 190 | fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void { | |
| 199 | fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32, pc: usize) Error!void { | |
| 191 | 200 | 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; | |
| 193 | 202 | log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line }); |
| 194 | 203 | switch (emit.debug_output) { |
| 195 | 204 | .dwarf => |dw| { |
src/arch/riscv64/Lower.zig+1-1| ... | ... | @@ -61,7 +61,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct { |
| 61 | 61 | defer lower.result_relocs_len = undefined; |
| 62 | 62 | |
| 63 | 63 | const inst = lower.mir.instructions.get(index); |
| 64 | log.debug("lowerMir {}", .{inst}); | |
| 64 | log.debug("lowerMir {f}", .{inst}); | |
| 65 | 65 | switch (inst.tag) { |
| 66 | 66 | else => try lower.generic(inst), |
| 67 | 67 | .pseudo_dbg_line_column, |
src/arch/riscv64/Mir.zig+2-7| ... | ... | @@ -92,14 +92,9 @@ pub const Inst = struct { |
| 92 | 92 | }, |
| 93 | 93 | }; |
| 94 | 94 | |
| 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 { | |
| 101 | 96 | 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) }); | |
| 103 | 98 | } |
| 104 | 99 | }; |
| 105 | 100 |
src/arch/riscv64/bits.zig+6-15| ... | ... | @@ -256,21 +256,12 @@ pub const FrameIndex = enum(u32) { |
| 256 | 256 | return @intFromEnum(fi) < named_count; |
| 257 | 257 | } |
| 258 | 258 | |
| 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)}); | |
| 274 | 265 | } |
| 275 | 266 | }; |
| 276 | 267 |
src/arch/sparc64/CodeGen.zig+5-5| ... | ... | @@ -1001,7 +1001,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!void { |
| 1001 | 1001 | switch (self.args[arg_index]) { |
| 1002 | 1002 | .stack_offset => |off| { |
| 1003 | 1003 | 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)}); | |
| 1005 | 1005 | }; |
| 1006 | 1006 | const offset = off + abi_size; |
| 1007 | 1007 | break :blk .{ .stack_offset = offset }; |
| ... | ... | @@ -2748,7 +2748,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2748 | 2748 | } |
| 2749 | 2749 | |
| 2750 | 2750 | 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)}); | |
| 2752 | 2752 | }; |
| 2753 | 2753 | // TODO swap this for inst.ty.ptrAlign |
| 2754 | 2754 | const abi_align = elem_ty.abiAlignment(zcu); |
| ... | ... | @@ -2760,7 +2760,7 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 2760 | 2760 | const zcu = pt.zcu; |
| 2761 | 2761 | const elem_ty = self.typeOfIndex(inst); |
| 2762 | 2762 | 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)}); | |
| 2764 | 2764 | }; |
| 2765 | 2765 | const abi_align = elem_ty.abiAlignment(zcu); |
| 2766 | 2766 | self.stack_align = self.stack_align.max(abi_align); |
| ... | ... | @@ -4111,7 +4111,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 4111 | 4111 | while (true) { |
| 4112 | 4112 | i -= 1; |
| 4113 | 4113 | if (self.branch_stack.items[i].inst_table.get(inst)) |mcv| { |
| 4114 | log.debug("getResolvedInstValue %{} => {}", .{ inst, mcv }); | |
| 4114 | log.debug("getResolvedInstValue %{f} => {}", .{ inst, mcv }); | |
| 4115 | 4115 | assert(mcv != .dead); |
| 4116 | 4116 | return mcv; |
| 4117 | 4117 | } |
| ... | ... | @@ -4382,7 +4382,7 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void { |
| 4382 | 4382 | const prev_value = self.getResolvedInstValue(inst); |
| 4383 | 4383 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 4384 | 4384 | branch.inst_table.putAssumeCapacity(inst, .dead); |
| 4385 | log.debug("%{} death: {} -> .dead", .{ inst, prev_value }); | |
| 4385 | log.debug("%{f} death: {} -> .dead", .{ inst, prev_value }); | |
| 4386 | 4386 | switch (prev_value) { |
| 4387 | 4387 | .register => |reg| { |
| 4388 | 4388 | self.register_manager.freeReg(reg); |
src/arch/wasm/CodeGen.zig+16-16| ... | ... | @@ -1463,7 +1463,7 @@ fn allocStack(cg: *CodeGen, ty: Type) !WValue { |
| 1463 | 1463 | } |
| 1464 | 1464 | |
| 1465 | 1465 | 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", .{ | |
| 1467 | 1467 | ty.fmt(pt), ty.abiSize(zcu), |
| 1468 | 1468 | }); |
| 1469 | 1469 | }; |
| ... | ... | @@ -1497,7 +1497,7 @@ fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue { |
| 1497 | 1497 | |
| 1498 | 1498 | const abi_alignment = ptr_ty.ptrAlignment(zcu); |
| 1499 | 1499 | 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", .{ | |
| 1501 | 1501 | pointee_ty.fmt(pt), pointee_ty.abiSize(zcu), |
| 1502 | 1502 | }); |
| 1503 | 1503 | }; |
| ... | ... | @@ -2404,7 +2404,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr |
| 2404 | 2404 | try cg.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(zcu))) }); |
| 2405 | 2405 | }, |
| 2406 | 2406 | 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}`", .{ | |
| 2408 | 2408 | ty.fmt(pt), |
| 2409 | 2409 | abi_size, |
| 2410 | 2410 | }); |
| ... | ... | @@ -2597,7 +2597,7 @@ fn binOp(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WV |
| 2597 | 2597 | return cg.binOpBigInt(lhs, rhs, ty, op); |
| 2598 | 2598 | } else { |
| 2599 | 2599 | return cg.fail( |
| 2600 | "TODO: Implement binary operation for type: {}", | |
| 2600 | "TODO: Implement binary operation for type: {f}", | |
| 2601 | 2601 | .{ty.fmt(pt)}, |
| 2602 | 2602 | ); |
| 2603 | 2603 | } |
| ... | ... | @@ -2817,7 +2817,7 @@ fn airAbs(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2817 | 2817 | |
| 2818 | 2818 | switch (scalar_ty.zigTypeTag(zcu)) { |
| 2819 | 2819 | .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)}); | |
| 2821 | 2821 | } else { |
| 2822 | 2822 | const int_bits = ty.intInfo(zcu).bits; |
| 2823 | 2823 | const wasm_bits = toWasmBits(int_bits) orelse { |
| ... | ... | @@ -3244,7 +3244,7 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3244 | 3244 | return .{ .imm32 = @intFromBool(!val.isNull(zcu)) }; |
| 3245 | 3245 | }, |
| 3246 | 3246 | .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)}), | |
| 3248 | 3248 | .vector_type => { |
| 3249 | 3249 | assert(determineSimdStoreStrategy(ty, zcu, cg.target) == .direct); |
| 3250 | 3250 | var buf: [16]u8 = undefined; |
| ... | ... | @@ -3608,7 +3608,7 @@ fn airNot(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3608 | 3608 | } else { |
| 3609 | 3609 | const int_info = operand_ty.intInfo(zcu); |
| 3610 | 3610 | 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)}); | |
| 3612 | 3612 | }; |
| 3613 | 3613 | |
| 3614 | 3614 | switch (wasm_bits) { |
| ... | ... | @@ -3874,7 +3874,7 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3874 | 3874 | }, |
| 3875 | 3875 | else => result: { |
| 3876 | 3876 | 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)}); | |
| 3878 | 3878 | }; |
| 3879 | 3879 | if (isByRef(field_ty, zcu, cg.target)) { |
| 3880 | 3880 | switch (operand) { |
| ... | ... | @@ -4360,7 +4360,7 @@ fn isNull(cg: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.Opc |
| 4360 | 4360 | // a pointer to the stack value |
| 4361 | 4361 | if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 4362 | 4362 | 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)}); | |
| 4364 | 4364 | }; |
| 4365 | 4365 | try cg.addMemArg(.i32_load8_u, .{ .offset = operand.offset() + offset, .alignment = 1 }); |
| 4366 | 4366 | } |
| ... | ... | @@ -4430,7 +4430,7 @@ fn airOptionalPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 4430 | 4430 | } |
| 4431 | 4431 | |
| 4432 | 4432 | 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)}); | |
| 4434 | 4434 | }; |
| 4435 | 4435 | |
| 4436 | 4436 | try cg.emitWValue(operand); |
| ... | ... | @@ -4462,7 +4462,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4462 | 4462 | break :result cg.reuseOperand(ty_op.operand, operand); |
| 4463 | 4463 | } |
| 4464 | 4464 | 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)}); | |
| 4466 | 4466 | }; |
| 4467 | 4467 | |
| 4468 | 4468 | // 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 { |
| 6196 | 6196 | _ = try cg.load(overflow_ret, Type.i32, 0); |
| 6197 | 6197 | try cg.addLocal(.local_set, overflow_bit.local.value); |
| 6198 | 6198 | 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)}); | |
| 6200 | 6200 | var bin_op_local = try mul.toLocal(cg, ty); |
| 6201 | 6201 | defer bin_op_local.free(cg); |
| 6202 | 6202 | |
| ... | ... | @@ -6749,7 +6749,7 @@ fn airMod(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6749 | 6749 | const add = try cg.binOp(rem, rhs, ty, .add); |
| 6750 | 6750 | break :result try cg.binOp(add, rhs, ty, .rem); |
| 6751 | 6751 | } |
| 6752 | return cg.fail("TODO: @mod for {}", .{ty.fmt(pt)}); | |
| 6752 | return cg.fail("TODO: @mod for {f}", .{ty.fmt(pt)}); | |
| 6753 | 6753 | }; |
| 6754 | 6754 | |
| 6755 | 6755 | 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 { |
| 6767 | 6767 | const lhs = try cg.resolveInst(bin_op.lhs); |
| 6768 | 6768 | const rhs = try cg.resolveInst(bin_op.rhs); |
| 6769 | 6769 | 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)}); | |
| 6771 | 6771 | }; |
| 6772 | 6772 | |
| 6773 | 6773 | switch (wasm_bits) { |
| ... | ... | @@ -6804,7 +6804,7 @@ fn airSatMul(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6804 | 6804 | }, |
| 6805 | 6805 | 64 => { |
| 6806 | 6806 | 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)}); | |
| 6808 | 6808 | } |
| 6809 | 6809 | const overflow_ret = try cg.allocStack(Type.i32); |
| 6810 | 6810 | _ = try cg.callIntrinsic( |
| ... | ... | @@ -6822,7 +6822,7 @@ fn airSatMul(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6822 | 6822 | }, |
| 6823 | 6823 | 128 => { |
| 6824 | 6824 | 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)}); | |
| 6826 | 6826 | } |
| 6827 | 6827 | const overflow_ret = try cg.allocStack(Type.i32); |
| 6828 | 6828 | const ret = try cg.callIntrinsic( |
src/arch/wasm/Emit.zig+105-133| ... | ... | @@ -14,16 +14,20 @@ const codegen = @import("../../codegen.zig"); |
| 14 | 14 | |
| 15 | 15 | mir: Mir, |
| 16 | 16 | wasm: *Wasm, |
| 17 | /// The binary representation that will be emitted by this module. | |
| 18 | code: *std.ArrayListUnmanaged(u8), | |
| 17 | /// The binary representation of this module is written here. | |
| 18 | bw: *std.io.BufferedWriter, | |
| 19 | 19 | |
| 20 | 20 | pub const Error = error{ |
| 21 | 21 | OutOfMemory, |
| 22 | 22 | }; |
| 23 | 23 | |
| 24 | 24 | pub fn lowerToCode(emit: *Emit) Error!void { |
| 25 | return @errorCast(emit.lowerToCodeInner()); | |
| 26 | } | |
| 27 | ||
| 28 | fn lowerToCodeInner(emit: *Emit) anyerror!void { | |
| 25 | 29 | const mir = &emit.mir; |
| 26 | const code = emit.code; | |
| 30 | const bw = emit.bw; | |
| 27 | 31 | const wasm = emit.wasm; |
| 28 | 32 | const comp = wasm.base.comp; |
| 29 | 33 | const gpa = comp.gpa; |
| ... | ... | @@ -41,18 +45,19 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 41 | 45 | }, |
| 42 | 46 | .block, .loop => { |
| 43 | 47 | 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 | }); | |
| 47 | 52 | |
| 48 | 53 | inst += 1; |
| 49 | 54 | continue :loop tags[inst]; |
| 50 | 55 | }, |
| 51 | 56 | .uav_ref => { |
| 52 | 57 | 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); | |
| 54 | 59 | } 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); | |
| 56 | 61 | } |
| 57 | 62 | inst += 1; |
| 58 | 63 | continue :loop tags[inst]; |
| ... | ... | @@ -60,20 +65,20 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 60 | 65 | .uav_ref_off => { |
| 61 | 66 | const extra = mir.extraData(Mir.UavRefOff, datas[inst].payload).data; |
| 62 | 67 | 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); | |
| 64 | 69 | } else { |
| 65 | try uavRefExe(wasm, code, extra.value, extra.offset, is_wasm32); | |
| 70 | try uavRefExe(wasm, bw, extra.value, extra.offset, is_wasm32); | |
| 66 | 71 | } |
| 67 | 72 | inst += 1; |
| 68 | 73 | continue :loop tags[inst]; |
| 69 | 74 | }, |
| 70 | 75 | .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); | |
| 72 | 77 | inst += 1; |
| 73 | 78 | continue :loop tags[inst]; |
| 74 | 79 | }, |
| 75 | 80 | .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); | |
| 77 | 82 | inst += 1; |
| 78 | 83 | continue :loop tags[inst]; |
| 79 | 84 | }, |
| ... | ... | @@ -81,11 +86,11 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 81 | 86 | const indirect_func_idx: Wasm.ZcuIndirectFunctionSetIndex = @enumFromInt( |
| 82 | 87 | wasm.zcu_indirect_function_set.getIndex(datas[inst].nav_index).?, |
| 83 | 88 | ); |
| 84 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 89 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.i32_const)); | |
| 85 | 90 | if (is_obj) { |
| 86 | 91 | @panic("TODO"); |
| 87 | 92 | } else { |
| 88 | leb.writeUleb128(code.fixedWriter(), 1 + @intFromEnum(indirect_func_idx)) catch unreachable; | |
| 93 | try bw.writeLeb128(1 + @intFromEnum(indirect_func_idx)); | |
| 89 | 94 | } |
| 90 | 95 | inst += 1; |
| 91 | 96 | continue :loop tags[inst]; |
| ... | ... | @@ -95,52 +100,48 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 95 | 100 | continue :loop tags[inst]; |
| 96 | 101 | }, |
| 97 | 102 | .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)); | |
| 100 | 104 | // 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))); | |
| 103 | 107 | |
| 104 | 108 | inst += 1; |
| 105 | 109 | continue :loop tags[inst]; |
| 106 | 110 | }, |
| 107 | 111 | .error_name_table_ref => { |
| 108 | 112 | wasm.error_name_table_ref_count += 1; |
| 109 | try code.ensureUnusedCapacity(gpa, 11); | |
| 110 | 113 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 111 | code.appendAssumeCapacity(@intFromEnum(opcode)); | |
| 114 | try bw.writeByte(@intFromEnum(opcode)); | |
| 112 | 115 | if (is_obj) { |
| 113 | 116 | try wasm.out_relocs.append(gpa, .{ |
| 114 | .offset = @intCast(code.items.len), | |
| 117 | .offset = @intCast(bw.count), | |
| 115 | 118 | .pointee = .{ .symbol_index = try wasm.errorNameTableSymbolIndex() }, |
| 116 | 119 | .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64, |
| 117 | 120 | .addend = 0, |
| 118 | 121 | }); |
| 119 | code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10); | |
| 122 | try bw.splatByteAll(0, if (is_wasm32) 5 else 10); | |
| 120 | 123 | |
| 121 | 124 | inst += 1; |
| 122 | 125 | continue :loop tags[inst]; |
| 123 | 126 | } else { |
| 124 | 127 | const addr: u32 = wasm.errorNameTableAddr(); |
| 125 | leb.writeIleb128(code.fixedWriter(), addr) catch unreachable; | |
| 128 | try bw.writeLeb128(@as(i32, @bitCast(addr))); | |
| 126 | 129 | |
| 127 | 130 | inst += 1; |
| 128 | 131 | continue :loop tags[inst]; |
| 129 | 132 | } |
| 130 | 133 | }, |
| 131 | 134 | .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); | |
| 135 | 137 | |
| 136 | 138 | inst += 1; |
| 137 | 139 | continue :loop tags[inst]; |
| 138 | 140 | }, |
| 139 | 141 | |
| 140 | 142 | .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); | |
| 144 | 145 | |
| 145 | 146 | inst += 1; |
| 146 | 147 | continue :loop tags[inst]; |
| ... | ... | @@ -150,29 +151,27 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 150 | 151 | const extra_index = datas[inst].payload; |
| 151 | 152 | const extra = mir.extraData(Mir.JumpTable, extra_index); |
| 152 | 153 | 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)); | |
| 155 | 155 | // -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); | |
| 158 | 158 | |
| 159 | 159 | inst += 1; |
| 160 | 160 | continue :loop tags[inst]; |
| 161 | 161 | }, |
| 162 | 162 | |
| 163 | 163 | .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)); | |
| 166 | 165 | if (is_obj) { |
| 167 | 166 | try wasm.out_relocs.append(gpa, .{ |
| 168 | .offset = @intCast(code.items.len), | |
| 167 | .offset = @intCast(bw.count), | |
| 169 | 168 | .pointee = .{ .symbol_index = try wasm.navSymbolIndex(datas[inst].nav_index) }, |
| 170 | 169 | .tag = .function_index_leb, |
| 171 | 170 | .addend = 0, |
| 172 | 171 | }); |
| 173 | code.appendNTimesAssumeCapacity(0, 5); | |
| 172 | try bw.splatByteAll(0, 5); | |
| 174 | 173 | } else { |
| 175 | appendOutputFunctionIndex(code, .fromIpNav(wasm, datas[inst].nav_index)); | |
| 174 | try appendOutputFunctionIndex(bw, .fromIpNav(wasm, datas[inst].nav_index)); | |
| 176 | 175 | } |
| 177 | 176 | |
| 178 | 177 | inst += 1; |
| ... | ... | @@ -180,7 +179,6 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 180 | 179 | }, |
| 181 | 180 | |
| 182 | 181 | .call_indirect => { |
| 183 | try code.ensureUnusedCapacity(gpa, 11); | |
| 184 | 182 | const fn_info = comp.zcu.?.typeToFunc(.fromInterned(datas[inst].ip_index)).?; |
| 185 | 183 | const func_ty_index = wasm.getExistingFunctionType( |
| 186 | 184 | fn_info.cc, |
| ... | ... | @@ -188,38 +186,37 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 188 | 186 | .fromInterned(fn_info.return_type), |
| 189 | 187 | target, |
| 190 | 188 | ).?; |
| 191 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call_indirect)); | |
| 189 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.call_indirect)); | |
| 192 | 190 | if (is_obj) { |
| 193 | 191 | try wasm.out_relocs.append(gpa, .{ |
| 194 | .offset = @intCast(code.items.len), | |
| 192 | .offset = @intCast(bw.count), | |
| 195 | 193 | .pointee = .{ .type_index = func_ty_index }, |
| 196 | 194 | .tag = .type_index_leb, |
| 197 | 195 | .addend = 0, |
| 198 | 196 | }); |
| 199 | code.appendNTimesAssumeCapacity(0, 5); | |
| 197 | try bw.splatByteAll(0, 5); | |
| 200 | 198 | } else { |
| 201 | 199 | 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)); | |
| 203 | 201 | } |
| 204 | leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // table index | |
| 202 | try bw.writeUleb128(0); // table index | |
| 205 | 203 | |
| 206 | 204 | inst += 1; |
| 207 | 205 | continue :loop tags[inst]; |
| 208 | 206 | }, |
| 209 | 207 | |
| 210 | 208 | .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)); | |
| 213 | 210 | if (is_obj) { |
| 214 | 211 | try wasm.out_relocs.append(gpa, .{ |
| 215 | .offset = @intCast(code.items.len), | |
| 212 | .offset = @intCast(bw.count), | |
| 216 | 213 | .pointee = .{ .symbol_index = try wasm.tagNameSymbolIndex(datas[inst].ip_index) }, |
| 217 | 214 | .tag = .function_index_leb, |
| 218 | 215 | .addend = 0, |
| 219 | 216 | }); |
| 220 | code.appendNTimesAssumeCapacity(0, 5); | |
| 217 | try bw.splatByteAll(0, 5); | |
| 221 | 218 | } else { |
| 222 | appendOutputFunctionIndex(code, .fromTagNameType(wasm, datas[inst].ip_index)); | |
| 219 | try appendOutputFunctionIndex(bw, .fromTagNameType(wasm, datas[inst].ip_index)); | |
| 223 | 220 | } |
| 224 | 221 | |
| 225 | 222 | inst += 1; |
| ... | ... | @@ -232,18 +229,17 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 232 | 229 | // table initialized based on the `Mir.Intrinsic` enum. |
| 233 | 230 | const symbol_name = try wasm.internString(@tagName(datas[inst].intrinsic)); |
| 234 | 231 | |
| 235 | try code.ensureUnusedCapacity(gpa, 6); | |
| 236 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.call)); | |
| 232 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.call)); | |
| 237 | 233 | if (is_obj) { |
| 238 | 234 | try wasm.out_relocs.append(gpa, .{ |
| 239 | .offset = @intCast(code.items.len), | |
| 235 | .offset = @intCast(bw.count), | |
| 240 | 236 | .pointee = .{ .symbol_index = try wasm.symbolNameIndex(symbol_name) }, |
| 241 | 237 | .tag = .function_index_leb, |
| 242 | 238 | .addend = 0, |
| 243 | 239 | }); |
| 244 | code.appendNTimesAssumeCapacity(0, 5); | |
| 240 | try bw.splatByteAll(0, 5); | |
| 245 | 241 | } else { |
| 246 | appendOutputFunctionIndex(code, .fromSymbolName(wasm, symbol_name)); | |
| 242 | try appendOutputFunctionIndex(bw, .fromSymbolName(wasm, symbol_name)); | |
| 247 | 243 | } |
| 248 | 244 | |
| 249 | 245 | inst += 1; |
| ... | ... | @@ -251,19 +247,17 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 251 | 247 | }, |
| 252 | 248 | |
| 253 | 249 | .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)); | |
| 256 | 251 | if (is_obj) { |
| 257 | 252 | try wasm.out_relocs.append(gpa, .{ |
| 258 | .offset = @intCast(code.items.len), | |
| 253 | .offset = @intCast(bw.count), | |
| 259 | 254 | .pointee = .{ .symbol_index = try wasm.stackPointerSymbolIndex() }, |
| 260 | 255 | .tag = .global_index_leb, |
| 261 | 256 | .addend = 0, |
| 262 | 257 | }); |
| 263 | code.appendNTimesAssumeCapacity(0, 5); | |
| 258 | try bw.splatByteAll(0, 5); | |
| 264 | 259 | } 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)); | |
| 267 | 261 | } |
| 268 | 262 | |
| 269 | 263 | inst += 1; |
| ... | ... | @@ -271,36 +265,32 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 271 | 265 | }, |
| 272 | 266 | |
| 273 | 267 | .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); | |
| 277 | 270 | |
| 278 | 271 | inst += 1; |
| 279 | 272 | continue :loop tags[inst]; |
| 280 | 273 | }, |
| 281 | 274 | |
| 282 | 275 | .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)); | |
| 285 | 277 | 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); | |
| 287 | 279 | |
| 288 | 280 | inst += 1; |
| 289 | 281 | continue :loop tags[inst]; |
| 290 | 282 | }, |
| 291 | 283 | .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); | |
| 295 | 286 | |
| 296 | 287 | inst += 1; |
| 297 | 288 | continue :loop tags[inst]; |
| 298 | 289 | }, |
| 299 | 290 | .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)); | |
| 302 | 292 | 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); | |
| 304 | 294 | |
| 305 | 295 | inst += 1; |
| 306 | 296 | continue :loop tags[inst]; |
| ... | ... | @@ -330,9 +320,8 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 330 | 320 | .i64_store16, |
| 331 | 321 | .i64_store32, |
| 332 | 322 | => { |
| 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); | |
| 336 | 325 | inst += 1; |
| 337 | 326 | continue :loop tags[inst]; |
| 338 | 327 | }, |
| ... | ... | @@ -466,43 +455,42 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 466 | 455 | .i64_clz, |
| 467 | 456 | .i64_ctz, |
| 468 | 457 | => { |
| 469 | try code.append(gpa, @intFromEnum(tags[inst])); | |
| 458 | try bw.writeByte(@intFromEnum(tags[inst])); | |
| 470 | 459 | inst += 1; |
| 471 | 460 | continue :loop tags[inst]; |
| 472 | 461 | }, |
| 473 | 462 | |
| 474 | 463 | .misc_prefix => { |
| 475 | try code.ensureUnusedCapacity(gpa, 6 + 6); | |
| 476 | 464 | 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) { | |
| 481 | 469 | // bulk-memory opcodes |
| 482 | 470 | .data_drop => { |
| 483 | 471 | const segment = mir.extra[extra_index + 1]; |
| 484 | leb.writeUleb128(code.fixedWriter(), segment) catch unreachable; | |
| 472 | try bw.writeLeb128(segment); | |
| 485 | 473 | |
| 486 | 474 | inst += 1; |
| 487 | 475 | continue :loop tags[inst]; |
| 488 | 476 | }, |
| 489 | 477 | .memory_init => { |
| 490 | 478 | 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 | |
| 493 | 481 | |
| 494 | 482 | inst += 1; |
| 495 | 483 | continue :loop tags[inst]; |
| 496 | 484 | }, |
| 497 | 485 | .memory_fill => { |
| 498 | leb.writeUleb128(code.fixedWriter(), @as(u32, 0)) catch unreachable; // memory index | |
| 486 | try bw.writeByte(0); // memory index | |
| 499 | 487 | |
| 500 | 488 | inst += 1; |
| 501 | 489 | continue :loop tags[inst]; |
| 502 | 490 | }, |
| 503 | 491 | .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 | |
| 506 | 494 | |
| 507 | 495 | inst += 1; |
| 508 | 496 | continue :loop tags[inst]; |
| ... | ... | @@ -534,12 +522,11 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 534 | 522 | comptime unreachable; |
| 535 | 523 | }, |
| 536 | 524 | .simd_prefix => { |
| 537 | try code.ensureUnusedCapacity(gpa, 6 + 20); | |
| 538 | 525 | 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) { | |
| 543 | 530 | .v128_store, |
| 544 | 531 | .v128_load, |
| 545 | 532 | .v128_load8_splat, |
| ... | ... | @@ -547,12 +534,12 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 547 | 534 | .v128_load32_splat, |
| 548 | 535 | .v128_load64_splat, |
| 549 | 536 | => { |
| 550 | encodeMemArg(code, mir.extraData(Mir.MemArg, extra_index + 1).data); | |
| 537 | try encodeMemArg(bw, mir.extraData(Mir.MemArg, extra_index + 1).data); | |
| 551 | 538 | inst += 1; |
| 552 | 539 | continue :loop tags[inst]; |
| 553 | 540 | }, |
| 554 | 541 | .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])); | |
| 556 | 543 | inst += 1; |
| 557 | 544 | continue :loop tags[inst]; |
| 558 | 545 | }, |
| ... | ... | @@ -571,7 +558,7 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 571 | 558 | .f64x2_extract_lane, |
| 572 | 559 | .f64x2_replace_lane, |
| 573 | 560 | => { |
| 574 | code.appendAssumeCapacity(@intCast(mir.extra[extra_index + 1])); | |
| 561 | try bw.writeByte(@intCast(mir.extra[extra_index + 1])); | |
| 575 | 562 | inst += 1; |
| 576 | 563 | continue :loop tags[inst]; |
| 577 | 564 | }, |
| ... | ... | @@ -819,13 +806,11 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 819 | 806 | comptime unreachable; |
| 820 | 807 | }, |
| 821 | 808 | .atomics_prefix => { |
| 822 | try code.ensureUnusedCapacity(gpa, 6 + 20); | |
| 823 | ||
| 824 | 809 | 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) { | |
| 829 | 814 | .i32_atomic_load, |
| 830 | 815 | .i64_atomic_load, |
| 831 | 816 | .i32_atomic_load8_u, |
| ... | ... | @@ -892,15 +877,12 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 892 | 877 | .i64_atomic_rmw32_cmpxchg_u, |
| 893 | 878 | => { |
| 894 | 879 | const mem_arg = mir.extraData(Mir.MemArg, extra_index + 1).data; |
| 895 | encodeMemArg(code, mem_arg); | |
| 880 | try encodeMemArg(bw, mem_arg); | |
| 896 | 881 | inst += 1; |
| 897 | 882 | continue :loop tags[inst]; |
| 898 | 883 | }, |
| 899 | 884 | .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 | |
| 904 | 886 | inst += 1; |
| 905 | 887 | continue :loop tags[inst]; |
| 906 | 888 | }, |
| ... | ... | @@ -915,44 +897,36 @@ pub fn lowerToCode(emit: *Emit) Error!void { |
| 915 | 897 | } |
| 916 | 898 | |
| 917 | 899 | /// Asserts 20 unused capacity. |
| 918 | fn 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; | |
| 900 | fn 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); | |
| 924 | 903 | } |
| 925 | 904 | |
| 926 | fn uavRefObj(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), value: InternPool.Index, offset: i32, is_wasm32: bool) !void { | |
| 905 | fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void { | |
| 927 | 906 | const comp = wasm.base.comp; |
| 928 | 907 | const gpa = comp.gpa; |
| 929 | 908 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 930 | 909 | |
| 931 | try code.ensureUnusedCapacity(gpa, 11); | |
| 932 | code.appendAssumeCapacity(@intFromEnum(opcode)); | |
| 910 | try bw.writeByte(@intFromEnum(opcode)); | |
| 933 | 911 | |
| 934 | 912 | try wasm.out_relocs.append(gpa, .{ |
| 935 | .offset = @intCast(code.items.len), | |
| 913 | .offset = @intCast(bw.count), | |
| 936 | 914 | .pointee = .{ .symbol_index = try wasm.uavSymbolIndex(value) }, |
| 937 | 915 | .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64, |
| 938 | 916 | .addend = offset, |
| 939 | 917 | }); |
| 940 | code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10); | |
| 918 | try bw.splatByteAll(0, if (is_wasm32) 5 else 10); | |
| 941 | 919 | } |
| 942 | 920 | |
| 943 | fn 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; | |
| 921 | fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void { | |
| 946 | 922 | 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)); | |
| 950 | 924 | |
| 951 | 925 | 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))); | |
| 953 | 927 | } |
| 954 | 928 | |
| 955 | fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff, is_wasm32: bool) !void { | |
| 929 | fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wasm32: bool) !void { | |
| 956 | 930 | const comp = wasm.base.comp; |
| 957 | 931 | const zcu = comp.zcu.?; |
| 958 | 932 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -961,24 +935,22 @@ fn navRefOff(wasm: *Wasm, code: *std.ArrayListUnmanaged(u8), data: Mir.NavRefOff |
| 961 | 935 | const nav_ty = ip.getNav(data.nav_index).typeOf(ip); |
| 962 | 936 | assert(!ip.isFunctionType(nav_ty)); |
| 963 | 937 | |
| 964 | try code.ensureUnusedCapacity(gpa, 11); | |
| 965 | ||
| 966 | 938 | const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const; |
| 967 | code.appendAssumeCapacity(@intFromEnum(opcode)); | |
| 939 | try bw.writeByte(@intFromEnum(opcode)); | |
| 968 | 940 | if (is_obj) { |
| 969 | 941 | try wasm.out_relocs.append(gpa, .{ |
| 970 | .offset = @intCast(code.items.len), | |
| 942 | .offset = @intCast(bw.count), | |
| 971 | 943 | .pointee = .{ .symbol_index = try wasm.navSymbolIndex(data.nav_index) }, |
| 972 | 944 | .tag = if (is_wasm32) .memory_addr_leb else .memory_addr_leb64, |
| 973 | 945 | .addend = data.offset, |
| 974 | 946 | }); |
| 975 | code.appendNTimesAssumeCapacity(0, if (is_wasm32) 5 else 10); | |
| 947 | try bw.splatByteAll(0, if (is_wasm32) 5 else 10); | |
| 976 | 948 | } else { |
| 977 | 949 | 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))))); | |
| 979 | 951 | } |
| 980 | 952 | } |
| 981 | 953 | |
| 982 | fn appendOutputFunctionIndex(code: *std.ArrayListUnmanaged(u8), i: Wasm.OutputFunctionIndex) void { | |
| 983 | leb.writeUleb128(code.fixedWriter(), @intFromEnum(i)) catch unreachable; | |
| 954 | fn appendOutputFunctionIndex(bw: *std.io.BufferedWriter, i: Wasm.OutputFunctionIndex) anyerror!void { | |
| 955 | return bw.writeLeb128(@intFromEnum(i)); | |
| 984 | 956 | } |
src/arch/x86_64/CodeGen.zig+198-228| ... | ... | @@ -524,52 +524,47 @@ pub const MCValue = union(enum) { |
| 524 | 524 | }; |
| 525 | 525 | } |
| 526 | 526 | |
| 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 { | |
| 533 | 528 | 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}", .{ | |
| 540 | 535 | @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]), |
| 541 | 536 | }), |
| 542 | .register_quadruple => |pl| try writer.print("{s}:{s}:{s}:{s}", .{ | |
| 537 | .register_quadruple => |pl| try bw.print("{s}:{s}:{s}:{s}", .{ | |
| 543 | 538 | @tagName(pl[3]), @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]), |
| 544 | 539 | }), |
| 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}", .{ | |
| 547 | 542 | @tagName(pl.eflags), |
| 548 | 543 | @tagName(pl.reg), |
| 549 | 544 | }), |
| 550 | .register_mask => |pl| try writer.print("mask({s},{}):{c}{s}", .{ | |
| 545 | .register_mask => |pl| try bw.print("mask({s},{f}):{c}{s}", .{ | |
| 551 | 546 | @tagName(pl.info.kind), |
| 552 | 547 | pl.info.scalar, |
| 553 | 548 | @as(u8, if (pl.info.inverted) '!' else ' '), |
| 554 | 549 | @tagName(pl.reg), |
| 555 | 550 | }), |
| 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}]", .{ | |
| 569 | 564 | pl.regs, pl.frame_index, pl.frame_off, |
| 570 | 565 | }), |
| 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)}), | |
| 573 | 568 | } |
| 574 | 569 | } |
| 575 | 570 | }; |
| ... | ... | @@ -639,7 +634,7 @@ const InstTracking = struct { |
| 639 | 634 | .reserved_frame => |index| self.long = .{ .load_frame = .{ .index = index } }, |
| 640 | 635 | else => unreachable, |
| 641 | 636 | } |
| 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 }); | |
| 643 | 638 | try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{}); |
| 644 | 639 | for (self.short.getRegs()) |reg| if (reg.isClass(.x87)) try cg.asmRegister(.{ .f_, .free }, reg); |
| 645 | 640 | } |
| ... | ... | @@ -672,7 +667,7 @@ const InstTracking = struct { |
| 672 | 667 | else => {}, // TODO process stack allocation death |
| 673 | 668 | } |
| 674 | 669 | self.reuseFrame(); |
| 675 | tracking_log.debug("{} => {} (spilled)", .{ inst, self.* }); | |
| 670 | tracking_log.debug("{f} => {f} (spilled)", .{ inst, self.* }); | |
| 676 | 671 | } |
| 677 | 672 | |
| 678 | 673 | fn verifyMaterialize(self: InstTracking, target: InstTracking) void { |
| ... | ... | @@ -749,7 +744,7 @@ const InstTracking = struct { |
| 749 | 744 | else => target.long, |
| 750 | 745 | } else target.long; |
| 751 | 746 | self.short = target.short; |
| 752 | tracking_log.debug("{} => {} (materialize)", .{ inst, self.* }); | |
| 747 | tracking_log.debug("{f} => {f} (materialize)", .{ inst, self.* }); | |
| 753 | 748 | } |
| 754 | 749 | |
| 755 | 750 | fn resurrect(self: *InstTracking, function: *CodeGen, inst: Air.Inst.Index, scope_generation: u32) !void { |
| ... | ... | @@ -757,7 +752,7 @@ const InstTracking = struct { |
| 757 | 752 | .dead => |die_generation| if (die_generation >= scope_generation) { |
| 758 | 753 | self.reuseFrame(); |
| 759 | 754 | try function.getValue(self.short, inst); |
| 760 | tracking_log.debug("{} => {} (resurrect)", .{ inst, self.* }); | |
| 755 | tracking_log.debug("{f} => {f} (resurrect)", .{ inst, self.* }); | |
| 761 | 756 | }, |
| 762 | 757 | else => {}, |
| 763 | 758 | } |
| ... | ... | @@ -768,7 +763,7 @@ const InstTracking = struct { |
| 768 | 763 | try function.freeValue(self.short, opts); |
| 769 | 764 | if (self.long == .none) self.long = self.short; |
| 770 | 765 | self.short = .{ .dead = function.scope_generation }; |
| 771 | tracking_log.debug("{} => {} (death)", .{ inst, self.* }); | |
| 766 | tracking_log.debug("{f} => {f} (death)", .{ inst, self.* }); | |
| 772 | 767 | } |
| 773 | 768 | |
| 774 | 769 | fn reuse( |
| ... | ... | @@ -778,13 +773,13 @@ const InstTracking = struct { |
| 778 | 773 | old_inst: Air.Inst.Index, |
| 779 | 774 | ) void { |
| 780 | 775 | 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 }); | |
| 782 | 777 | } |
| 783 | 778 | |
| 784 | 779 | fn liveOut(self: *InstTracking, function: *CodeGen, inst: Air.Inst.Index) void { |
| 785 | 780 | for (self.getRegs()) |reg| { |
| 786 | 781 | if (function.register_manager.isRegFree(reg)) { |
| 787 | tracking_log.debug("{} => {} (live-out)", .{ inst, self.* }); | |
| 782 | tracking_log.debug("{f} => {f} (live-out)", .{ inst, self.* }); | |
| 788 | 783 | continue; |
| 789 | 784 | } |
| 790 | 785 | |
| ... | ... | @@ -812,18 +807,13 @@ const InstTracking = struct { |
| 812 | 807 | // Perform side-effects of freeValue manually. |
| 813 | 808 | function.register_manager.freeReg(reg); |
| 814 | 809 | |
| 815 | tracking_log.debug("{} => {} (live-out {})", .{ inst, self.*, tracked_inst }); | |
| 810 | tracking_log.debug("{f} => {f} (live-out {f})", .{ inst, self.*, tracked_inst }); | |
| 816 | 811 | } |
| 817 | 812 | } |
| 818 | 813 | |
| 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}); | |
| 827 | 817 | } |
| 828 | 818 | }; |
| 829 | 819 | |
| ... | ... | @@ -939,7 +929,7 @@ pub fn generate( |
| 939 | 929 | function.inst_tracking.putAssumeCapacityNoClobber(temp.toIndex(), .init(.none)); |
| 940 | 930 | } |
| 941 | 931 | |
| 942 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); | |
| 932 | wip_mir_log.debug("{f}:", .{fmtNav(func.owner_nav, ip)}); | |
| 943 | 933 | |
| 944 | 934 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 945 | 935 | function.frame_allocs.set( |
| ... | ... | @@ -1097,13 +1087,8 @@ const FormatNavData = struct { |
| 1097 | 1087 | ip: *const InternPool, |
| 1098 | 1088 | nav_index: InternPool.Nav.Index, |
| 1099 | 1089 | }; |
| 1100 | fn 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)}); | |
| 1090 | fn 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)}); | |
| 1107 | 1092 | } |
| 1108 | 1093 | fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) { |
| 1109 | 1094 | return .{ .data = .{ |
| ... | ... | @@ -1116,12 +1101,7 @@ const FormatAirData = struct { |
| 1116 | 1101 | self: *CodeGen, |
| 1117 | 1102 | inst: Air.Inst.Index, |
| 1118 | 1103 | }; |
| 1119 | fn formatAir( | |
| 1120 | data: FormatAirData, | |
| 1121 | comptime _: []const u8, | |
| 1122 | _: std.fmt.FormatOptions, | |
| 1123 | writer: anytype, | |
| 1124 | ) @TypeOf(writer).Error!void { | |
| 1104 | fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void { | |
| 1125 | 1105 | data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness); |
| 1126 | 1106 | } |
| 1127 | 1107 | fn fmtAir(self: *CodeGen, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) { |
| ... | ... | @@ -1132,12 +1112,7 @@ const FormatWipMirData = struct { |
| 1132 | 1112 | self: *CodeGen, |
| 1133 | 1113 | inst: Mir.Inst.Index, |
| 1134 | 1114 | }; |
| 1135 | fn formatWipMir( | |
| 1136 | data: FormatWipMirData, | |
| 1137 | comptime _: []const u8, | |
| 1138 | _: std.fmt.FormatOptions, | |
| 1139 | writer: anytype, | |
| 1140 | ) @TypeOf(writer).Error!void { | |
| 1115 | fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) !void { | |
| 1141 | 1116 | var lower: Lower = .{ |
| 1142 | 1117 | .target = data.self.target, |
| 1143 | 1118 | .allocator = data.self.gpa, |
| ... | ... | @@ -1152,11 +1127,11 @@ fn formatWipMir( |
| 1152 | 1127 | lower.err_msg.?.deinit(data.self.gpa); |
| 1153 | 1128 | lower.err_msg = null; |
| 1154 | 1129 | } |
| 1155 | try writer.writeAll(lower.err_msg.?.msg); | |
| 1130 | try bw.writeAll(lower.err_msg.?.msg); | |
| 1156 | 1131 | return; |
| 1157 | 1132 | }, |
| 1158 | 1133 | error.OutOfMemory, error.InvalidInstruction, error.CannotEncode => |e| { |
| 1159 | try writer.writeAll(switch (e) { | |
| 1134 | try bw.writeAll(switch (e) { | |
| 1160 | 1135 | error.OutOfMemory => "Out of memory", |
| 1161 | 1136 | error.InvalidInstruction => "CodeGen failed to find a viable instruction.", |
| 1162 | 1137 | error.CannotEncode => "CodeGen failed to encode the instruction.", |
| ... | ... | @@ -1165,14 +1140,14 @@ fn formatWipMir( |
| 1165 | 1140 | }, |
| 1166 | 1141 | else => |e| return e, |
| 1167 | 1142 | }).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}); | |
| 1170 | 1145 | first = false; |
| 1171 | 1146 | } |
| 1172 | 1147 | if (first) { |
| 1173 | 1148 | const ip = &data.self.pt.zcu.intern_pool; |
| 1174 | 1149 | 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)}); | |
| 1176 | 1151 | switch (mir_inst.ops) { |
| 1177 | 1152 | else => unreachable, |
| 1178 | 1153 | .pseudo_dbg_prologue_end_none, |
| ... | ... | @@ -1184,20 +1159,20 @@ fn formatWipMir( |
| 1184 | 1159 | .pseudo_dbg_var_none, |
| 1185 | 1160 | .pseudo_dead_none, |
| 1186 | 1161 | => {}, |
| 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( | |
| 1188 | 1163 | " {[line]d}, {[column]d}", |
| 1189 | 1164 | mir_inst.data.line_column, |
| 1190 | 1165 | ), |
| 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}", .{ | |
| 1192 | 1167 | ip.getNav(ip.indexToKey(mir_inst.data.ip_index).func.owner_nav).name.fmt(ip), |
| 1193 | 1168 | }), |
| 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}", .{ | |
| 1195 | 1170 | @as(i32, @bitCast(mir_inst.data.i.i)), |
| 1196 | 1171 | }), |
| 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}", .{ | |
| 1198 | 1173 | mir_inst.data.i.i, |
| 1199 | 1174 | }), |
| 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}", .{ | |
| 1201 | 1176 | mir_inst.data.i64, |
| 1202 | 1177 | }), |
| 1203 | 1178 | .pseudo_dbg_arg_ro, .pseudo_dbg_var_ro => { |
| ... | ... | @@ -1205,22 +1180,22 @@ fn formatWipMir( |
| 1205 | 1180 | .base = .{ .reg = mir_inst.data.ro.reg }, |
| 1206 | 1181 | .disp = mir_inst.data.ro.off, |
| 1207 | 1182 | }) }; |
| 1208 | try writer.print(" {}", .{mem_op.fmt(.m)}); | |
| 1183 | try bw.print(" {f}", .{mem_op.fmt(.m)}); | |
| 1209 | 1184 | }, |
| 1210 | 1185 | .pseudo_dbg_arg_fa, .pseudo_dbg_var_fa => { |
| 1211 | 1186 | const mem_op: encoder.Instruction.Operand = .{ .mem = .initSib(.qword, .{ |
| 1212 | 1187 | .base = .{ .frame = mir_inst.data.fa.index }, |
| 1213 | 1188 | .disp = mir_inst.data.fa.off, |
| 1214 | 1189 | }) }; |
| 1215 | try writer.print(" {}", .{mem_op.fmt(.m)}); | |
| 1190 | try bw.print(" {f}", .{mem_op.fmt(.m)}); | |
| 1216 | 1191 | }, |
| 1217 | 1192 | .pseudo_dbg_arg_m, .pseudo_dbg_var_m => { |
| 1218 | 1193 | const mem_op: encoder.Instruction.Operand = .{ |
| 1219 | 1194 | .mem = lower.mir.extraData(Mir.Memory, mir_inst.data.x.payload).data.decode(), |
| 1220 | 1195 | }; |
| 1221 | try writer.print(" {}", .{mem_op.fmt(.m)}); | |
| 1196 | try bw.print(" {f}", .{mem_op.fmt(.m)}); | |
| 1222 | 1197 | }, |
| 1223 | .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try writer.print(" {}", .{ | |
| 1198 | .pseudo_dbg_arg_val, .pseudo_dbg_var_val => try bw.print(" {}", .{ | |
| 1224 | 1199 | Value.fromInterned(mir_inst.data.ip_index).fmtValue(data.self.pt), |
| 1225 | 1200 | }), |
| 1226 | 1201 | } |
| ... | ... | @@ -1233,14 +1208,9 @@ fn fmtWipMir(self: *CodeGen, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMi |
| 1233 | 1208 | const FormatTrackingData = struct { |
| 1234 | 1209 | self: *CodeGen, |
| 1235 | 1210 | }; |
| 1236 | fn formatTracking( | |
| 1237 | data: FormatTrackingData, | |
| 1238 | comptime _: []const u8, | |
| 1239 | _: std.fmt.FormatOptions, | |
| 1240 | writer: anytype, | |
| 1241 | ) @TypeOf(writer).Error!void { | |
| 1211 | fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) anyerror!void { | |
| 1242 | 1212 | 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.* }); | |
| 1244 | 1214 | } |
| 1245 | 1215 | fn fmtTracking(self: *CodeGen) std.fmt.Formatter(formatTracking) { |
| 1246 | 1216 | return .{ .data = .{ .self = self } }; |
| ... | ... | @@ -1251,7 +1221,7 @@ fn addInst(self: *CodeGen, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 1251 | 1221 | try self.mir_instructions.ensureUnusedCapacity(gpa, 1); |
| 1252 | 1222 | const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len); |
| 1253 | 1223 | 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)}); | |
| 1255 | 1225 | return result_index; |
| 1256 | 1226 | } |
| 1257 | 1227 | |
| ... | ... | @@ -2056,7 +2026,7 @@ fn gen( |
| 2056 | 2026 | .{}, |
| 2057 | 2027 | ); |
| 2058 | 2028 | 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 }); | |
| 2060 | 2030 | }, |
| 2061 | 2031 | else => unreachable, |
| 2062 | 2032 | } |
| ... | ... | @@ -2334,8 +2304,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2334 | 2304 | |
| 2335 | 2305 | for (body) |inst| { |
| 2336 | 2306 | 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()}); | |
| 2339 | 2309 | |
| 2340 | 2310 | cg.reused_operands = .initEmpty(); |
| 2341 | 2311 | try cg.inst_tracking.ensureUnusedCapacity(cg.gpa, 1); |
| ... | ... | @@ -4339,7 +4309,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 4339 | 4309 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 4340 | 4310 | } }, |
| 4341 | 4311 | } }) 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}", .{ | |
| 4343 | 4313 | @tagName(air_tag), |
| 4344 | 4314 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 4345 | 4315 | ops[0].tracking(cg), |
| ... | ... | @@ -4351,7 +4321,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 4351 | 4321 | else => unreachable, |
| 4352 | 4322 | .add, .add_optimized => {}, |
| 4353 | 4323 | .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}", .{ | |
| 4355 | 4325 | @tagName(air_tag), |
| 4356 | 4326 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 4357 | 4327 | res[0].tracking(cg), |
| ... | ... | @@ -14947,7 +14917,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 14947 | 14917 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 14948 | 14918 | } }, |
| 14949 | 14919 | } }) 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}", .{ | |
| 14951 | 14921 | @tagName(air_tag), |
| 14952 | 14922 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 14953 | 14923 | ops[0].tracking(cg), |
| ... | ... | @@ -14959,7 +14929,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 14959 | 14929 | else => unreachable, |
| 14960 | 14930 | .sub, .sub_optimized => {}, |
| 14961 | 14931 | .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}", .{ | |
| 14963 | 14933 | @tagName(air_tag), |
| 14964 | 14934 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 14965 | 14935 | res[0].tracking(cg), |
| ... | ... | @@ -24587,7 +24557,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 24587 | 24557 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 24588 | 24558 | } }, |
| 24589 | 24559 | } }) 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}", .{ | |
| 24591 | 24561 | @tagName(air_tag), |
| 24592 | 24562 | ty.fmt(pt), |
| 24593 | 24563 | ops[0].tracking(cg), |
| ... | ... | @@ -27287,7 +27257,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 27287 | 27257 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 27288 | 27258 | } }, |
| 27289 | 27259 | } }) 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}", .{ | |
| 27291 | 27261 | @tagName(air_tag), |
| 27292 | 27262 | ty.fmt(pt), |
| 27293 | 27263 | ops[0].tracking(cg), |
| ... | ... | @@ -27296,7 +27266,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 27296 | 27266 | else => |e| return e, |
| 27297 | 27267 | }; |
| 27298 | 27268 | 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}", .{ | |
| 27300 | 27270 | @tagName(air_tag), |
| 27301 | 27271 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 27302 | 27272 | res[0].tracking(cg), |
| ... | ... | @@ -33606,7 +33576,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 33606 | 33576 | assert(air_tag == .div_exact); |
| 33607 | 33577 | res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err; |
| 33608 | 33578 | }) 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}", .{ | |
| 33610 | 33580 | @tagName(air_tag), |
| 33611 | 33581 | ty.fmt(pt), |
| 33612 | 33582 | ops[0].tracking(cg), |
| ... | ... | @@ -34837,7 +34807,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 34837 | 34807 | } }) else err: { |
| 34838 | 34808 | res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err; |
| 34839 | 34809 | }) 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}", .{ | |
| 34841 | 34811 | @tagName(air_tag), |
| 34842 | 34812 | ty.fmt(pt), |
| 34843 | 34813 | ops[0].tracking(cg), |
| ... | ... | @@ -36148,7 +36118,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 36148 | 36118 | } }, |
| 36149 | 36119 | } }, |
| 36150 | 36120 | }) 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}", .{ | |
| 36152 | 36122 | @tagName(air_tag), |
| 36153 | 36123 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 36154 | 36124 | ops[0].tracking(cg), |
| ... | ... | @@ -37614,7 +37584,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 37614 | 37584 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 37615 | 37585 | } }, |
| 37616 | 37586 | } })) 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}", .{ | |
| 37618 | 37588 | @tagName(air_tag), |
| 37619 | 37589 | ty.fmt(pt), |
| 37620 | 37590 | ops[0].tracking(cg), |
| ... | ... | @@ -39248,7 +39218,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 39248 | 39218 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 39249 | 39219 | } }, |
| 39250 | 39220 | } }) 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}", .{ | |
| 39252 | 39222 | @tagName(air_tag), |
| 39253 | 39223 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 39254 | 39224 | ops[0].tracking(cg), |
| ... | ... | @@ -42077,7 +42047,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42077 | 42047 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 42078 | 42048 | } }, |
| 42079 | 42049 | } }) 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}", .{ | |
| 42081 | 42051 | @tagName(air_tag), |
| 42082 | 42052 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 42083 | 42053 | ops[0].tracking(cg), |
| ... | ... | @@ -42191,7 +42161,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42191 | 42161 | .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ }, |
| 42192 | 42162 | } }, |
| 42193 | 42163 | } }) 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}", .{ | |
| 42195 | 42165 | @tagName(air_tag), |
| 42196 | 42166 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 42197 | 42167 | ops[0].tracking(cg), |
| ... | ... | @@ -42320,7 +42290,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 42320 | 42290 | .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ }, |
| 42321 | 42291 | } }, |
| 42322 | 42292 | } }) 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}", .{ | |
| 42324 | 42294 | @tagName(air_tag), |
| 42325 | 42295 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 42326 | 42296 | ops[0].tracking(cg), |
| ... | ... | @@ -46485,7 +46455,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 46485 | 46455 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 46486 | 46456 | } }, |
| 46487 | 46457 | } }) 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}", .{ | |
| 46489 | 46459 | @tagName(air_tag), |
| 46490 | 46460 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 46491 | 46461 | ops[0].tracking(cg), |
| ... | ... | @@ -50644,7 +50614,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 50644 | 50614 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 50645 | 50615 | } }, |
| 50646 | 50616 | } }) 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}", .{ | |
| 50648 | 50618 | @tagName(air_tag), |
| 50649 | 50619 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 50650 | 50620 | ops[0].tracking(cg), |
| ... | ... | @@ -51493,7 +51463,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 51493 | 51463 | .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ }, |
| 51494 | 51464 | } }, |
| 51495 | 51465 | } }) 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}", .{ | |
| 51497 | 51467 | @tagName(air_tag), |
| 51498 | 51468 | ty_pl.ty.toType().fmt(pt), |
| 51499 | 51469 | ops[0].tracking(cg), |
| ... | ... | @@ -52398,7 +52368,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 52398 | 52368 | .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ }, |
| 52399 | 52369 | } }, |
| 52400 | 52370 | } }) 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}", .{ | |
| 52402 | 52372 | @tagName(air_tag), |
| 52403 | 52373 | ty_pl.ty.toType().fmt(pt), |
| 52404 | 52374 | ops[0].tracking(cg), |
| ... | ... | @@ -55995,7 +55965,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 55995 | 55965 | .{ ._, ._, .@"or", .tmp2q, .tmp1q, ._, ._ }, |
| 55996 | 55966 | } }, |
| 55997 | 55967 | } }) 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}", .{ | |
| 55999 | 55969 | @tagName(air_tag), |
| 56000 | 55970 | ty_pl.ty.toType().fmt(pt), |
| 56001 | 55971 | ops[0].tracking(cg), |
| ... | ... | @@ -59735,7 +59705,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 59735 | 59705 | } }, |
| 59736 | 59706 | } }, |
| 59737 | 59707 | }) 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}", .{ | |
| 59739 | 59709 | @tagName(air_tag), |
| 59740 | 59710 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 59741 | 59711 | ops[0].tracking(cg), |
| ... | ... | @@ -60298,7 +60268,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 60298 | 60268 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 60299 | 60269 | } }, |
| 60300 | 60270 | } }) 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}", .{ | |
| 60302 | 60272 | @tagName(air_tag), |
| 60303 | 60273 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 60304 | 60274 | cg.typeOf(bin_op.rhs).fmt(pt), |
| ... | ... | @@ -60660,7 +60630,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 60660 | 60630 | .{ ._, ._ns, .j, .@"0b", ._, ._, ._ }, |
| 60661 | 60631 | } }, |
| 60662 | 60632 | } }) 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}", .{ | |
| 60664 | 60634 | @tagName(air_tag), |
| 60665 | 60635 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 60666 | 60636 | cg.typeOf(bin_op.rhs).fmt(pt), |
| ... | ... | @@ -60672,7 +60642,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 60672 | 60642 | switch (air_tag) { |
| 60673 | 60643 | else => unreachable, |
| 60674 | 60644 | .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}", .{ | |
| 60676 | 60646 | @tagName(air_tag), |
| 60677 | 60647 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 60678 | 60648 | res[0].tracking(cg), |
| ... | ... | @@ -65329,7 +65299,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 65329 | 65299 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 65330 | 65300 | } }, |
| 65331 | 65301 | } }) 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}", .{ | |
| 65333 | 65303 | @tagName(air_tag), |
| 65334 | 65304 | ty_op.ty.toType().fmt(pt), |
| 65335 | 65305 | ops[0].tracking(cg), |
| ... | ... | @@ -68483,7 +68453,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 68483 | 68453 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 68484 | 68454 | } }, |
| 68485 | 68455 | } }) 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}", .{ | |
| 68487 | 68457 | @tagName(air_tag), |
| 68488 | 68458 | cg.typeOf(ty_op.operand).fmt(pt), |
| 68489 | 68459 | ops[0].tracking(cg), |
| ... | ... | @@ -68880,7 +68850,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 68880 | 68850 | .{ .@"0:", ._, .lea, .dst0d, .leasia(.dst0, .@"8", .tmp0, .add_8_src0_size), ._, ._ }, |
| 68881 | 68851 | } }, |
| 68882 | 68852 | } }) 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}", .{ | |
| 68884 | 68854 | @tagName(air_tag), |
| 68885 | 68855 | cg.typeOf(ty_op.operand).fmt(pt), |
| 68886 | 68856 | ops[0].tracking(cg), |
| ... | ... | @@ -69768,7 +69738,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 69768 | 69738 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 69769 | 69739 | } }, |
| 69770 | 69740 | } }) 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}", .{ | |
| 69772 | 69742 | @tagName(air_tag), |
| 69773 | 69743 | cg.typeOf(ty_op.operand).fmt(pt), |
| 69774 | 69744 | ops[0].tracking(cg), |
| ... | ... | @@ -70417,7 +70387,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 70417 | 70387 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 70418 | 70388 | } }, |
| 70419 | 70389 | } }) 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}", .{ | |
| 70421 | 70391 | @tagName(air_tag), |
| 70422 | 70392 | ty_op.ty.toType().fmt(pt), |
| 70423 | 70393 | ops[0].tracking(cg), |
| ... | ... | @@ -73519,7 +73489,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 73519 | 73489 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 73520 | 73490 | } }, |
| 73521 | 73491 | } }) 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}", .{ | |
| 73523 | 73493 | @tagName(air_tag), |
| 73524 | 73494 | ty_op.ty.toType().fmt(pt), |
| 73525 | 73495 | ops[0].tracking(cg), |
| ... | ... | @@ -74457,7 +74427,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 74457 | 74427 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 74458 | 74428 | } }, |
| 74459 | 74429 | } }) 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}", .{ | |
| 74461 | 74431 | @tagName(air_tag), |
| 74462 | 74432 | cg.typeOf(un_op).fmt(pt), |
| 74463 | 74433 | ops[0].tracking(cg), |
| ... | ... | @@ -75183,7 +75153,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 75183 | 75153 | } }, |
| 75184 | 75154 | } }, |
| 75185 | 75155 | }) 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}", .{ | |
| 75187 | 75157 | @tagName(air_tag), |
| 75188 | 75158 | cg.typeOf(un_op).fmt(pt), |
| 75189 | 75159 | ops[0].tracking(cg), |
| ... | ... | @@ -76734,7 +76704,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 76734 | 76704 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 76735 | 76705 | } }, |
| 76736 | 76706 | } }) 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}", .{ | |
| 76738 | 76708 | @tagName(air_tag), |
| 76739 | 76709 | cg.typeOf(ty_op.operand).fmt(pt), |
| 76740 | 76710 | ops[0].tracking(cg), |
| ... | ... | @@ -77926,7 +77896,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 77926 | 77896 | } }, |
| 77927 | 77897 | } }, |
| 77928 | 77898 | }) 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}", .{ | |
| 77930 | 77900 | @tagName(air_tag), |
| 77931 | 77901 | cg.typeOf(un_op).fmt(pt), |
| 77932 | 77902 | ops[0].tracking(cg), |
| ... | ... | @@ -78466,7 +78436,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 78466 | 78436 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 78467 | 78437 | } }, |
| 78468 | 78438 | } }) 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}", .{ | |
| 78470 | 78440 | @tagName(air_tag), |
| 78471 | 78441 | cg.typeOf(un_op).fmt(pt), |
| 78472 | 78442 | ops[0].tracking(cg), |
| ... | ... | @@ -78913,7 +78883,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 78913 | 78883 | } else err: { |
| 78914 | 78884 | res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err; |
| 78915 | 78885 | }) 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}", .{ | |
| 78917 | 78887 | @tagName(air_tag), |
| 78918 | 78888 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 78919 | 78889 | ops[0].tracking(cg), |
| ... | ... | @@ -79470,7 +79440,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 79470 | 79440 | res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err; |
| 79471 | 79441 | }, |
| 79472 | 79442 | }) 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}", .{ | |
| 79474 | 79444 | @tagName(air_tag), |
| 79475 | 79445 | ty.fmt(pt), |
| 79476 | 79446 | ops[0].tracking(cg), |
| ... | ... | @@ -88546,7 +88516,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 88546 | 88516 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 88547 | 88517 | } }, |
| 88548 | 88518 | } }) 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}", .{ | |
| 88550 | 88520 | @tagName(air_tag), |
| 88551 | 88521 | ty_op.ty.toType().fmt(pt), |
| 88552 | 88522 | cg.typeOf(ty_op.operand).fmt(pt), |
| ... | ... | @@ -90221,7 +90191,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 90221 | 90191 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 90222 | 90192 | } }, |
| 90223 | 90193 | } }) 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}", .{ | |
| 90225 | 90195 | @tagName(air_tag), |
| 90226 | 90196 | ty_op.ty.toType().fmt(pt), |
| 90227 | 90197 | cg.typeOf(ty_op.operand).fmt(pt), |
| ... | ... | @@ -94899,7 +94869,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 94899 | 94869 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 94900 | 94870 | } }, |
| 94901 | 94871 | } }) 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}", .{ | |
| 94903 | 94873 | @tagName(air_tag), |
| 94904 | 94874 | dst_ty.fmt(pt), |
| 94905 | 94875 | src_ty.fmt(pt), |
| ... | ... | @@ -100565,7 +100535,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 100565 | 100535 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 100566 | 100536 | } }, |
| 100567 | 100537 | } }) 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}", .{ | |
| 100569 | 100539 | @tagName(air_tag), |
| 100570 | 100540 | ty_op.ty.toType().fmt(pt), |
| 100571 | 100541 | cg.typeOf(ty_op.operand).fmt(pt), |
| ... | ... | @@ -111427,7 +111397,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 111427 | 111397 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 111428 | 111398 | } }, |
| 111429 | 111399 | } }) 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}", .{ | |
| 111431 | 111401 | @tagName(air_tag), |
| 111432 | 111402 | ty_op.ty.toType().fmt(pt), |
| 111433 | 111403 | cg.typeOf(ty_op.operand).fmt(pt), |
| ... | ... | @@ -123446,7 +123416,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 123446 | 123416 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 123447 | 123417 | } }, |
| 123448 | 123418 | } }) 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}", .{ | |
| 123450 | 123420 | @tagName(air_tag), |
| 123451 | 123421 | ty_op.ty.toType().fmt(pt), |
| 123452 | 123422 | cg.typeOf(ty_op.operand).fmt(pt), |
| ... | ... | @@ -166464,7 +166434,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 166464 | 166434 | .{ ._, ._, .@"test", .src0p, .src0p, ._, ._ }, |
| 166465 | 166435 | } }, |
| 166466 | 166436 | } }) 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}", .{ | |
| 166468 | 166438 | @tagName(air_tag), |
| 166469 | 166439 | cg.typeOf(un_op).fmt(pt), |
| 166470 | 166440 | ops[0].tracking(cg), |
| ... | ... | @@ -166552,7 +166522,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 166552 | 166522 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, |
| 166553 | 166523 | } }, |
| 166554 | 166524 | } }) 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}", .{ | |
| 166556 | 166526 | @tagName(air_tag), |
| 166557 | 166527 | cg.typeOf(un_op).fmt(pt), |
| 166558 | 166528 | ops[0].tracking(cg), |
| ... | ... | @@ -166654,7 +166624,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 166654 | 166624 | .{ ._, ._, .lea, .dst1d, .leai(.dst1, .tmp1), ._, ._ }, |
| 166655 | 166625 | } }, |
| 166656 | 166626 | } }) 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}", .{ | |
| 166658 | 166628 | @tagName(air_tag), |
| 166659 | 166629 | cg.typeOf(un_op).fmt(pt), |
| 166660 | 166630 | ops[0].tracking(cg), |
| ... | ... | @@ -166752,7 +166722,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 166752 | 166722 | .{ ._, ._, .@"test", .src0d, .src0d, ._, ._ }, |
| 166753 | 166723 | } }, |
| 166754 | 166724 | } }) 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}", .{ | |
| 166756 | 166726 | @tagName(air_tag), |
| 166757 | 166727 | ty_op.ty.toType().fmt(pt), |
| 166758 | 166728 | ops[0].tracking(cg), |
| ... | ... | @@ -166804,7 +166774,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 166804 | 166774 | } |
| 166805 | 166775 | } |
| 166806 | 166776 | }, |
| 166807 | .@"packed" => return cg.fail("failed to select {s} {}", .{ | |
| 166777 | .@"packed" => return cg.fail("failed to select {s} {f}", .{ | |
| 166808 | 166778 | @tagName(air_tag), |
| 166809 | 166779 | agg_ty.fmt(pt), |
| 166810 | 166780 | }), |
| ... | ... | @@ -166825,7 +166795,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 166825 | 166795 | elem_disp += @intCast(field_type.abiSize(zcu)); |
| 166826 | 166796 | } |
| 166827 | 166797 | }, |
| 166828 | else => return cg.fail("failed to select {s} {}", .{ | |
| 166798 | else => return cg.fail("failed to select {s} {f}", .{ | |
| 166829 | 166799 | @tagName(air_tag), |
| 166830 | 166800 | agg_ty.fmt(pt), |
| 166831 | 166801 | }), |
| ... | ... | @@ -168123,7 +168093,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 168123 | 168093 | .{ ._, ._ae, .j, .@"0b", ._, ._, ._ }, |
| 168124 | 168094 | } }, |
| 168125 | 168095 | } }) 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}", .{ | |
| 168127 | 168097 | @tagName(air_tag), |
| 168128 | 168098 | cg.typeOf(bin_op.lhs).fmt(pt), |
| 168129 | 168099 | ops[0].tracking(cg), |
| ... | ... | @@ -168223,7 +168193,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 168223 | 168193 | .{ ._, ._, .cmp, .src0d, .lea(.tmp1d), ._, ._ }, |
| 168224 | 168194 | } }, |
| 168225 | 168195 | } }) 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}", .{ | |
| 168227 | 168197 | @tagName(air_tag), |
| 168228 | 168198 | ops[0].tracking(cg), |
| 168229 | 168199 | }), |
| ... | ... | @@ -168242,12 +168212,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 168242 | 168212 | .ref => { |
| 168243 | 168213 | const result = try cg.allocRegOrMem(err_ret_trace_index, true); |
| 168244 | 168214 | 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 }); | |
| 168246 | 168216 | cg.inst_tracking.putAssumeCapacityNoClobber(err_ret_trace_index, .init(result)); |
| 168247 | 168217 | }, |
| 168248 | 168218 | .temp => |temp_index| { |
| 168249 | 168219 | 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 }); | |
| 168251 | 168221 | cg.inst_tracking.putAssumeCapacityNoClobber(err_ret_trace_index, temp_tracking.*); |
| 168252 | 168222 | assert(cg.reuseTemp(err_ret_trace_index, temp_index.toIndex(), temp_tracking)); |
| 168253 | 168223 | }, |
| ... | ... | @@ -168917,7 +168887,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 168917 | 168887 | try cg.resetTemps(@enumFromInt(0)); |
| 168918 | 168888 | cg.checkInvariantsAfterAirInst(); |
| 168919 | 168889 | } |
| 168920 | verbose_tracking_log.debug("{}", .{cg.fmtTracking()}); | |
| 168890 | verbose_tracking_log.debug("{f}", .{cg.fmtTracking()}); | |
| 168921 | 168891 | } |
| 168922 | 168892 | |
| 168923 | 168893 | fn 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 { |
| 168927 | 168897 | switch (ip.indexToKey(lazy_sym.ty)) { |
| 168928 | 168898 | .enum_type => { |
| 168929 | 168899 | 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)}); | |
| 168931 | 168901 | |
| 168932 | 168902 | const param_regs = abi.getCAbiIntParamRegs(.auto); |
| 168933 | 168903 | 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 { |
| 168976 | 168946 | }, |
| 168977 | 168947 | .error_set_type => |error_set_type| { |
| 168978 | 168948 | 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)}); | |
| 168980 | 168950 | |
| 168981 | 168951 | const param_regs = abi.getCAbiIntParamRegs(.auto); |
| 168982 | 168952 | 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 { |
| 169016 | 168986 | try cg.asmOpOnly(.{ ._, .ret }); |
| 169017 | 168987 | }, |
| 169018 | 168988 | else => return cg.fail( |
| 169019 | "TODO implement {s} for {}", | |
| 168989 | "TODO implement {s} for {f}", | |
| 169020 | 168990 | .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) }, |
| 169021 | 168991 | ), |
| 169022 | 168992 | } |
| ... | ... | @@ -169076,7 +169046,7 @@ fn finishAirResult(self: *CodeGen, inst: Air.Inst.Index, result: MCValue) void { |
| 169076 | 169046 | .none, .dead, .unreach => {}, |
| 169077 | 169047 | else => unreachable, // Why didn't the result die? |
| 169078 | 169048 | } else { |
| 169079 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); | |
| 169049 | tracking_log.debug("{f} => {f} (birth)", .{ inst, result }); | |
| 169080 | 169050 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result)); |
| 169081 | 169051 | // In some cases, an operand may be reused as the result. |
| 169082 | 169052 | // 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 { |
| 169226 | 169196 | const val_ty = ptr_ty.childType(zcu); |
| 169227 | 169197 | return self.allocFrameIndex(.init(.{ |
| 169228 | 169198 | .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)}); | |
| 169230 | 169200 | }, |
| 169231 | 169201 | .alignment = ptr_ty.ptrAlignment(zcu).max(.@"1"), |
| 169232 | 169202 | })); |
| ... | ... | @@ -169244,7 +169214,7 @@ fn allocRegOrMemAdvanced(self: *CodeGen, ty: Type, inst: ?Air.Inst.Index, reg_ok |
| 169244 | 169214 | const pt = self.pt; |
| 169245 | 169215 | const zcu = pt.zcu; |
| 169246 | 169216 | 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)}); | |
| 169248 | 169218 | }; |
| 169249 | 169219 | |
| 169250 | 169220 | if (reg_ok) need_mem: { |
| ... | ... | @@ -169749,7 +169719,7 @@ fn airFpext(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 169749 | 169719 | ); |
| 169750 | 169720 | } |
| 169751 | 169721 | 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}", .{ | |
| 169753 | 169723 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 169754 | 169724 | }); |
| 169755 | 169725 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -170004,7 +169974,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 170004 | 169974 | ); |
| 170005 | 169975 | |
| 170006 | 169976 | 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}", .{ | |
| 170008 | 169978 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 170009 | 169979 | }); |
| 170010 | 169980 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -170076,7 +170046,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 170076 | 170046 | else => null, |
| 170077 | 170047 | }, |
| 170078 | 170048 | 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)}); | |
| 170080 | 170050 | |
| 170081 | 170051 | const dst_info = dst_elem_ty.intInfo(zcu); |
| 170082 | 170052 | const src_info = src_elem_ty.intInfo(zcu); |
| ... | ... | @@ -170497,7 +170467,7 @@ fn airAddSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 170497 | 170467 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 170498 | 170468 | const ty = self.typeOf(bin_op.lhs); |
| 170499 | 170469 | if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail( |
| 170500 | "TODO implement airAddSat for {}", | |
| 170470 | "TODO implement airAddSat for {f}", | |
| 170501 | 170471 | .{ty.fmt(pt)}, |
| 170502 | 170472 | ); |
| 170503 | 170473 | |
| ... | ... | @@ -170575,7 +170545,7 @@ fn airSubSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 170575 | 170545 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 170576 | 170546 | const ty = self.typeOf(bin_op.lhs); |
| 170577 | 170547 | if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail( |
| 170578 | "TODO implement airSubSat for {}", | |
| 170548 | "TODO implement airSubSat for {f}", | |
| 170579 | 170549 | .{ty.fmt(pt)}, |
| 170580 | 170550 | ); |
| 170581 | 170551 | |
| ... | ... | @@ -170726,7 +170696,7 @@ fn airMulSat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 170726 | 170696 | } |
| 170727 | 170697 | |
| 170728 | 170698 | if (ty.zigTypeTag(zcu) == .vector or ty.abiSize(zcu) > 8) return self.fail( |
| 170729 | "TODO implement airMulSat for {}", | |
| 170699 | "TODO implement airMulSat for {f}", | |
| 170730 | 170700 | .{ty.fmt(pt)}, |
| 170731 | 170701 | ); |
| 170732 | 170702 | |
| ... | ... | @@ -171020,7 +170990,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 171020 | 170990 | const tuple_ty = self.typeOfIndex(inst); |
| 171021 | 170991 | const dst_ty = self.typeOf(bin_op.lhs); |
| 171022 | 170992 | 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)}), | |
| 171024 | 170994 | .int => result: { |
| 171025 | 170995 | const dst_info = dst_ty.intInfo(zcu); |
| 171026 | 170996 | if (dst_info.bits > 128 and dst_info.signedness == .unsigned) { |
| ... | ... | @@ -171373,7 +171343,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 171373 | 171343 | else => { |
| 171374 | 171344 | // For now, this is the only supported multiply that doesn't fit in a register. |
| 171375 | 171345 | 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}", .{ | |
| 171377 | 171347 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 171378 | 171348 | }); |
| 171379 | 171349 | |
| ... | ... | @@ -171774,7 +171744,7 @@ fn airShlShrBinOp(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 171774 | 171744 | }, |
| 171775 | 171745 | else => {}, |
| 171776 | 171746 | } |
| 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)}); | |
| 171778 | 171748 | }; |
| 171779 | 171749 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 171780 | 171750 | } |
| ... | ... | @@ -172034,7 +172004,7 @@ fn airUnwrapErrUnionErr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172034 | 172004 | .index = frame_addr.index, |
| 172035 | 172005 | .off = frame_addr.off + @as(i32, @intCast(err_off)), |
| 172036 | 172006 | } }, |
| 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}), | |
| 172038 | 172008 | } |
| 172039 | 172009 | }; |
| 172040 | 172010 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -172196,7 +172166,7 @@ fn genUnwrapErrUnionPayloadMir( |
| 172196 | 172166 | else |
| 172197 | 172167 | .{ .register = try self.copyToTmpRegister(payload_ty, result_mcv) }; |
| 172198 | 172168 | }, |
| 172199 | else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {}", .{err_union}), | |
| 172169 | else => return self.fail("TODO implement genUnwrapErrUnionPayloadMir for {f}", .{err_union}), | |
| 172200 | 172170 | } |
| 172201 | 172171 | }; |
| 172202 | 172172 | |
| ... | ... | @@ -172362,7 +172332,7 @@ fn airSliceLen(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172362 | 172332 | .index = frame_addr.index, |
| 172363 | 172333 | .off = frame_addr.off + 8, |
| 172364 | 172334 | } }, |
| 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}), | |
| 172366 | 172336 | }; |
| 172367 | 172337 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) { |
| 172368 | 172338 | switch (src_mcv) { |
| ... | ... | @@ -172645,7 +172615,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172645 | 172615 | }.to64(), |
| 172646 | 172616 | ), |
| 172647 | 172617 | }, |
| 172648 | else => return self.fail("TODO airArrayElemVal for {s} of {}", .{ | |
| 172618 | else => return self.fail("TODO airArrayElemVal for {s} of {f}", .{ | |
| 172649 | 172619 | @tagName(array_mat_mcv), array_ty.fmt(pt), |
| 172650 | 172620 | }), |
| 172651 | 172621 | } |
| ... | ... | @@ -172688,7 +172658,7 @@ fn airArrayElemVal(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172688 | 172658 | .load_extern_func, |
| 172689 | 172659 | .lea_extern_func, |
| 172690 | 172660 | => 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}", .{ | |
| 172692 | 172662 | @tagName(array_mcv), array_ty.fmt(pt), |
| 172693 | 172663 | }), |
| 172694 | 172664 | } |
| ... | ... | @@ -172881,7 +172851,7 @@ fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172881 | 172851 | } |
| 172882 | 172852 | |
| 172883 | 172853 | 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}", | |
| 172885 | 172855 | .{operand}, |
| 172886 | 172856 | ); |
| 172887 | 172857 | }, |
| ... | ... | @@ -172893,7 +172863,7 @@ fn airGetUnionTag(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172893 | 172863 | .register = registerAlias(result.register, @intCast(layout.tag_size)), |
| 172894 | 172864 | }; |
| 172895 | 172865 | }, |
| 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}), | |
| 172897 | 172867 | } |
| 172898 | 172868 | }; |
| 172899 | 172869 | |
| ... | ... | @@ -172909,7 +172879,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 172909 | 172879 | |
| 172910 | 172880 | const dst_ty = self.typeOfIndex(inst); |
| 172911 | 172881 | 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}", .{ | |
| 172913 | 172883 | src_ty.fmt(pt), |
| 172914 | 172884 | }); |
| 172915 | 172885 | |
| ... | ... | @@ -173105,7 +173075,7 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 173105 | 173075 | |
| 173106 | 173076 | const dst_ty = self.typeOfIndex(inst); |
| 173107 | 173077 | 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}", .{ | |
| 173109 | 173079 | src_ty.fmt(pt), |
| 173110 | 173080 | }); |
| 173111 | 173081 | |
| ... | ... | @@ -173277,7 +173247,7 @@ fn airPopCount(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 173277 | 173247 | const src_ty = self.typeOf(ty_op.operand); |
| 173278 | 173248 | const src_abi_size: u32 = @intCast(src_ty.abiSize(zcu)); |
| 173279 | 173249 | 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)}); | |
| 173281 | 173251 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 173282 | 173252 | |
| 173283 | 173253 | const mat_src_mcv = switch (src_mcv) { |
| ... | ... | @@ -173430,7 +173400,7 @@ fn genByteSwap( |
| 173430 | 173400 | const has_movbe = self.hasFeature(.movbe); |
| 173431 | 173401 | |
| 173432 | 173402 | if (src_ty.zigTypeTag(zcu) == .vector) return self.fail( |
| 173433 | "TODO implement genByteSwap for {}", | |
| 173403 | "TODO implement genByteSwap for {f}", | |
| 173434 | 173404 | .{src_ty.fmt(pt)}, |
| 173435 | 173405 | ); |
| 173436 | 173406 | |
| ... | ... | @@ -173739,7 +173709,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A |
| 173739 | 173709 | const result = result: { |
| 173740 | 173710 | const scalar_bits = ty.scalarType(zcu).floatBits(self.target); |
| 173741 | 173711 | 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}", .{ | |
| 173743 | 173713 | ty.fmt(pt), |
| 173744 | 173714 | }); |
| 173745 | 173715 | |
| ... | ... | @@ -173763,7 +173733,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A |
| 173763 | 173733 | const abi_size: u32 = switch (ty.abiSize(zcu)) { |
| 173764 | 173734 | 1...16 => 16, |
| 173765 | 173735 | 17...32 => 32, |
| 173766 | else => return self.fail("TODO implement floatSign for {}", .{ | |
| 173736 | else => return self.fail("TODO implement floatSign for {f}", .{ | |
| 173767 | 173737 | ty.fmt(pt), |
| 173768 | 173738 | }), |
| 173769 | 173739 | }; |
| ... | ... | @@ -173822,7 +173792,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A |
| 173822 | 173792 | .abs => .{ .v_pd, .@"and" }, |
| 173823 | 173793 | else => unreachable, |
| 173824 | 173794 | }, |
| 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)}), | |
| 173826 | 173796 | else => unreachable, |
| 173827 | 173797 | }, |
| 173828 | 173798 | registerAlias(dst_reg, abi_size), |
| ... | ... | @@ -173848,7 +173818,7 @@ fn floatSign(self: *CodeGen, inst: Air.Inst.Index, tag: Air.Inst.Tag, operand: A |
| 173848 | 173818 | .abs => .{ ._pd, .@"and" }, |
| 173849 | 173819 | else => unreachable, |
| 173850 | 173820 | }, |
| 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)}), | |
| 173852 | 173822 | else => unreachable, |
| 173853 | 173823 | }, |
| 173854 | 173824 | registerAlias(dst_reg, abi_size), |
| ... | ... | @@ -173928,7 +173898,7 @@ fn genRoundLibcall(self: *CodeGen, ty: Type, src_mcv: MCValue, mode: bits.RoundM |
| 173928 | 173898 | if (self.getRoundTag(ty)) |_| return .none; |
| 173929 | 173899 | |
| 173930 | 173900 | 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)}); | |
| 173932 | 173902 | |
| 173933 | 173903 | var sym_buf: ["__trunc?".len]u8 = undefined; |
| 173934 | 173904 | return try self.genCall(.{ .extern_func = .{ |
| ... | ... | @@ -174164,7 +174134,7 @@ fn airAbs(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 174164 | 174134 | }, |
| 174165 | 174135 | .float => return self.floatSign(inst, .abs, ty_op.operand, ty), |
| 174166 | 174136 | }, |
| 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)}); | |
| 174168 | 174138 | |
| 174169 | 174139 | const abi_size: u32 = @intCast(ty.abiSize(zcu)); |
| 174170 | 174140 | const src_mcv = try self.resolveInst(ty_op.operand); |
| ... | ... | @@ -174323,7 +174293,7 @@ fn airSqrt(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 174323 | 174293 | else => unreachable, |
| 174324 | 174294 | }, |
| 174325 | 174295 | 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)}); | |
| 174327 | 174297 | switch (mir_tag[0]) { |
| 174328 | 174298 | .v_ss, .v_sd => if (src_mcv.isBase()) try self.asmRegisterRegisterMemory( |
| 174329 | 174299 | mir_tag, |
| ... | ... | @@ -174481,7 +174451,7 @@ fn packedLoad(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) |
| 174481 | 174451 | return; |
| 174482 | 174452 | } |
| 174483 | 174453 | |
| 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)}); | |
| 174485 | 174455 | |
| 174486 | 174456 | const limb_abi_size: u31 = @min(val_abi_size, 8); |
| 174487 | 174457 | 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) |
| 174753 | 174723 | limb_mem, |
| 174754 | 174724 | registerAlias(tmp_reg, limb_abi_size), |
| 174755 | 174725 | ); |
| 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)}); | |
| 174757 | 174727 | } |
| 174758 | 174728 | } |
| 174759 | 174729 | |
| ... | ... | @@ -174856,7 +174826,7 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a |
| 174856 | 174826 | const zcu = pt.zcu; |
| 174857 | 174827 | const src_ty = self.typeOf(src_air); |
| 174858 | 174828 | 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)}); | |
| 174860 | 174830 | |
| 174861 | 174831 | var src_mcv = try self.resolveInst(src_air); |
| 174862 | 174832 | switch (src_mcv) { |
| ... | ... | @@ -174943,7 +174913,7 @@ fn genUnOp(self: *CodeGen, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_a |
| 174943 | 174913 | fn genUnOpMir(self: *CodeGen, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void { |
| 174944 | 174914 | const pt = self.pt; |
| 174945 | 174915 | 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) }); | |
| 174947 | 174917 | switch (dst_mcv) { |
| 174948 | 174918 | .none, |
| 174949 | 174919 | .unreach, |
| ... | ... | @@ -175672,7 +175642,7 @@ fn genBinOp( |
| 175672 | 175642 | }, |
| 175673 | 175643 | floatLibcAbiSuffix(lhs_ty), |
| 175674 | 175644 | }), |
| 175675 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 175645 | else => return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 175676 | 175646 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 175677 | 175647 | }), |
| 175678 | 175648 | } catch unreachable; |
| ... | ... | @@ -175785,7 +175755,7 @@ fn genBinOp( |
| 175785 | 175755 | ); |
| 175786 | 175756 | break :adjusted .{ .register = dst_reg }; |
| 175787 | 175757 | }, |
| 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}", .{ | |
| 175789 | 175759 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 175790 | 175760 | }), |
| 175791 | 175761 | else => unreachable, |
| ... | ... | @@ -175819,7 +175789,7 @@ fn genBinOp( |
| 175819 | 175789 | if (sse_op and ((lhs_ty.scalarType(zcu).isRuntimeFloat() and |
| 175820 | 175790 | lhs_ty.scalarType(zcu).floatBits(self.target) == 80) or |
| 175821 | 175791 | 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) }); | |
| 175823 | 175793 | |
| 175824 | 175794 | const maybe_mask_reg = switch (air_tag) { |
| 175825 | 175795 | else => null, |
| ... | ... | @@ -176199,7 +176169,7 @@ fn genBinOp( |
| 176199 | 176169 | } |
| 176200 | 176170 | }, |
| 176201 | 176171 | |
| 176202 | else => return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 176172 | else => return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 176203 | 176173 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 176204 | 176174 | }), |
| 176205 | 176175 | } |
| ... | ... | @@ -176953,7 +176923,7 @@ fn genBinOp( |
| 176953 | 176923 | else => unreachable, |
| 176954 | 176924 | }, |
| 176955 | 176925 | }, |
| 176956 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 176926 | }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 176957 | 176927 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 176958 | 176928 | }); |
| 176959 | 176929 | |
| ... | ... | @@ -177086,7 +177056,7 @@ fn genBinOp( |
| 177086 | 177056 | else => unreachable, |
| 177087 | 177057 | }, |
| 177088 | 177058 | else => unreachable, |
| 177089 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 177059 | }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 177090 | 177060 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 177091 | 177061 | }), |
| 177092 | 177062 | mask_reg, |
| ... | ... | @@ -177118,7 +177088,7 @@ fn genBinOp( |
| 177118 | 177088 | else => unreachable, |
| 177119 | 177089 | }, |
| 177120 | 177090 | else => unreachable, |
| 177121 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 177091 | }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 177122 | 177092 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 177123 | 177093 | }), |
| 177124 | 177094 | dst_reg, |
| ... | ... | @@ -177154,7 +177124,7 @@ fn genBinOp( |
| 177154 | 177124 | else => unreachable, |
| 177155 | 177125 | }, |
| 177156 | 177126 | else => unreachable, |
| 177157 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 177127 | }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 177158 | 177128 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 177159 | 177129 | }), |
| 177160 | 177130 | mask_reg, |
| ... | ... | @@ -177185,7 +177155,7 @@ fn genBinOp( |
| 177185 | 177155 | else => unreachable, |
| 177186 | 177156 | }, |
| 177187 | 177157 | else => unreachable, |
| 177188 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 177158 | }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 177189 | 177159 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 177190 | 177160 | }), |
| 177191 | 177161 | dst_reg, |
| ... | ... | @@ -177215,7 +177185,7 @@ fn genBinOp( |
| 177215 | 177185 | else => unreachable, |
| 177216 | 177186 | }, |
| 177217 | 177187 | else => unreachable, |
| 177218 | }) orelse return self.fail("TODO implement genBinOp for {s} {}", .{ | |
| 177188 | }) orelse return self.fail("TODO implement genBinOp for {s} {f}", .{ | |
| 177219 | 177189 | @tagName(air_tag), lhs_ty.fmt(pt), |
| 177220 | 177190 | }); |
| 177221 | 177191 | try self.asmRegisterRegister(.{ mir_fixes, .@"and" }, dst_reg, mask_reg); |
| ... | ... | @@ -178022,7 +177992,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 178022 | 177992 | |
| 178023 | 177993 | break :result dst_mcv; |
| 178024 | 177994 | }, |
| 178025 | else => return self.fail("TODO implement arg for {}", .{src_mcv}), | |
| 177995 | else => return self.fail("TODO implement arg for {f}", .{src_mcv}), | |
| 178026 | 177996 | } |
| 178027 | 177997 | }; |
| 178028 | 177998 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| ... | ... | @@ -179079,7 +179049,7 @@ fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index { |
| 179079 | 179049 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 179080 | 179050 | return self.genCondBrMir(ty, .{ .register = reg }); |
| 179081 | 179051 | } |
| 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}); | |
| 179083 | 179053 | }, |
| 179084 | 179054 | else => return self.fail("TODO implement condbr when condition is {s}", .{@tagName(mcv)}), |
| 179085 | 179055 | } |
| ... | ... | @@ -179166,7 +179136,7 @@ fn isErr(self: *CodeGen, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCVal |
| 179166 | 179136 | } }, |
| 179167 | 179137 | .{ .immediate = 0 }, |
| 179168 | 179138 | ), |
| 179169 | else => return self.fail("TODO implement isErr for {}", .{eu_mcv}), | |
| 179139 | else => return self.fail("TODO implement isErr for {f}", .{eu_mcv}), | |
| 179170 | 179140 | } |
| 179171 | 179141 | |
| 179172 | 179142 | if (maybe_inst) |inst| self.eflags_inst = inst; |
| ... | ... | @@ -180916,7 +180886,7 @@ fn moveStrategy(cg: *CodeGen, ty: Type, class: Register.Class, aligned: bool) !M |
| 180916 | 180886 | }, |
| 180917 | 180887 | .ip, .cr, .dr => {}, |
| 180918 | 180888 | } |
| 180919 | return cg.fail("TODO moveStrategy for {}", .{ty.fmt(pt)}); | |
| 180889 | return cg.fail("TODO moveStrategy for {f}", .{ty.fmt(pt)}); | |
| 180920 | 180890 | } |
| 180921 | 180891 | |
| 180922 | 180892 | const CopyOptions = struct { |
| ... | ... | @@ -181048,7 +181018,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C |
| 181048 | 181018 | break :src_info .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock }; |
| 181049 | 181019 | }, |
| 181050 | 181020 | .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}", .{ | |
| 181052 | 181022 | @tagName(src_mcv), ty.fmt(pt), |
| 181053 | 181023 | }), |
| 181054 | 181024 | }; |
| ... | ... | @@ -181424,7 +181394,7 @@ fn genSetReg( |
| 181424 | 181394 | 80 => null, |
| 181425 | 181395 | else => unreachable, |
| 181426 | 181396 | }, |
| 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)}), | |
| 181428 | 181398 | dst_alias, |
| 181429 | 181399 | registerAlias(src_reg, abi_size), |
| 181430 | 181400 | ), |
| ... | ... | @@ -181854,7 +181824,7 @@ fn genSetMem( |
| 181854 | 181824 | opts, |
| 181855 | 181825 | ); |
| 181856 | 181826 | }, |
| 181857 | else => return self.fail("TODO implement genSetMem for {s} of {}", .{ | |
| 181827 | else => return self.fail("TODO implement genSetMem for {s} of {f}", .{ | |
| 181858 | 181828 | @tagName(src_mcv), ty.fmt(pt), |
| 181859 | 181829 | }), |
| 181860 | 181830 | }, |
| ... | ... | @@ -182167,7 +182137,7 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 182167 | 182137 | 32, 64 => src_size > 8, |
| 182168 | 182138 | else => unreachable, |
| 182169 | 182139 | }) { |
| 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}", .{ | |
| 182171 | 182141 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 182172 | 182142 | }); |
| 182173 | 182143 | |
| ... | ... | @@ -182209,7 +182179,7 @@ fn airFloatFromInt(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 182209 | 182179 | else => unreachable, |
| 182210 | 182180 | }, |
| 182211 | 182181 | else => null, |
| 182212 | }) orelse return self.fail("TODO implement airFloatFromInt from {} to {}", .{ | |
| 182182 | }) orelse return self.fail("TODO implement airFloatFromInt from {f} to {f}", .{ | |
| 182213 | 182183 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 182214 | 182184 | }); |
| 182215 | 182185 | const dst_alias = dst_reg.to128(); |
| ... | ... | @@ -182247,7 +182217,7 @@ fn airIntFromFloat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 182247 | 182217 | 32, 64 => dst_size > 8, |
| 182248 | 182218 | else => unreachable, |
| 182249 | 182219 | }) { |
| 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}", .{ | |
| 182251 | 182221 | src_ty.fmt(pt), dst_ty.fmt(pt), |
| 182252 | 182222 | }); |
| 182253 | 182223 | |
| ... | ... | @@ -182531,7 +182501,7 @@ fn atomicOp( |
| 182531 | 182501 | else => null, |
| 182532 | 182502 | }, |
| 182533 | 182503 | 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}", .{ | |
| 182535 | 182505 | @tagName(op), val_ty.fmt(pt), |
| 182536 | 182506 | }); |
| 182537 | 182507 | try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{}); |
| ... | ... | @@ -183286,7 +183256,7 @@ fn airSplat(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 183286 | 183256 | else => unreachable, |
| 183287 | 183257 | }, |
| 183288 | 183258 | } |
| 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)}); | |
| 183290 | 183260 | }; |
| 183291 | 183261 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 183292 | 183262 | } |
| ... | ... | @@ -183322,12 +183292,12 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 183322 | 183292 | else |
| 183323 | 183293 | try self.copyToTmpRegister(pred_ty, pred_mcv) |
| 183324 | 183294 | else |
| 183325 | return self.fail("TODO implement airSelect for {}", .{ty.fmt(pt)}), | |
| 183295 | return self.fail("TODO implement airSelect for {f}", .{ty.fmt(pt)}), | |
| 183326 | 183296 | else => unreachable, |
| 183327 | 183297 | }, |
| 183328 | 183298 | .register_mask => |pred_reg_mask| { |
| 183329 | 183299 | 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)}); | |
| 183331 | 183301 | |
| 183332 | 183302 | const mask_reg: Register = if (need_xmm0 and pred_reg_mask.reg.id() != comptime Register.xmm0.id()) mask_reg: { |
| 183333 | 183303 | try self.register_manager.getKnownReg(.xmm0, null); |
| ... | ... | @@ -183401,7 +183371,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 183401 | 183371 | else |
| 183402 | 183372 | null |
| 183403 | 183373 | 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)}); | |
| 183405 | 183375 | if (has_avx) { |
| 183406 | 183376 | const rhs_alias = if (reuse_mcv.isRegister()) |
| 183407 | 183377 | registerAlias(reuse_mcv.getReg().?, abi_size) |
| ... | ... | @@ -183554,7 +183524,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 183554 | 183524 | else => unreachable, |
| 183555 | 183525 | }), |
| 183556 | 183526 | ); |
| 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)}); | |
| 183558 | 183528 | const elem_bits: u16 = @intCast(elem_abi_size * 8); |
| 183559 | 183529 | if (!pred_fits_in_elem) if (self.hasFeature(.ssse3)) { |
| 183560 | 183530 | const mask_len = elem_abi_size * vec_len; |
| ... | ... | @@ -183583,7 +183553,7 @@ fn airSelect(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 183583 | 183553 | mask_alias, |
| 183584 | 183554 | mask_mem, |
| 183585 | 183555 | ); |
| 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)}); | |
| 183587 | 183557 | { |
| 183588 | 183558 | const mask_elem_ty = try pt.intType(.unsigned, elem_bits); |
| 183589 | 183559 | 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 { |
| 183706 | 183676 | else => null, |
| 183707 | 183677 | }, |
| 183708 | 183678 | }, |
| 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)}); | |
| 183710 | 183680 | if (has_avx) { |
| 183711 | 183681 | const rhs_alias = if (rhs_mcv.isRegister()) |
| 183712 | 183682 | registerAlias(rhs_mcv.getReg().?, abi_size) |
| ... | ... | @@ -184551,7 +184521,7 @@ fn airShuffle(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 184551 | 184521 | } |
| 184552 | 184522 | |
| 184553 | 184523 | 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}", .{ | |
| 184555 | 184525 | lhs_ty.fmt(pt), |
| 184556 | 184526 | rhs_ty.fmt(pt), |
| 184557 | 184527 | dst_ty.fmt(pt), |
| ... | ... | @@ -184800,7 +184770,7 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 184800 | 184770 | 32, 64 => !self.hasFeature(.fma), |
| 184801 | 184771 | else => unreachable, |
| 184802 | 184772 | }) { |
| 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}", .{ | |
| 184804 | 184774 | ty.fmt(pt), |
| 184805 | 184775 | }); |
| 184806 | 184776 | |
| ... | ... | @@ -184930,7 +184900,7 @@ fn airMulAdd(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 184930 | 184900 | else => unreachable, |
| 184931 | 184901 | } |
| 184932 | 184902 | 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)}); | |
| 184934 | 184904 | |
| 184935 | 184905 | var mops: [3]MCValue = undefined; |
| 184936 | 184906 | for (order, mcvs) |mop_index, mcv| mops[mop_index - 1] = mcv; |
| ... | ... | @@ -185130,7 +185100,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 185130 | 185100 | assert(classes.len == 1); |
| 185131 | 185101 | unreachable; |
| 185132 | 185102 | }, |
| 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)}), | |
| 185134 | 185104 | } |
| 185135 | 185105 | |
| 185136 | 185106 | if (unused) break :result .unreach; |
| ... | ... | @@ -185779,7 +185749,7 @@ fn splitType(self: *CodeGen, comptime parts_len: usize, ty: Type) ![parts_len]Ty |
| 185779 | 185749 | for (parts) |part| part_sizes += part.abiSize(zcu); |
| 185780 | 185750 | if (part_sizes == ty.abiSize(zcu)) return parts; |
| 185781 | 185751 | }; |
| 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) }); | |
| 185783 | 185753 | } |
| 185784 | 185754 | |
| 185785 | 185755 | /// Truncates the value in the register in place. |
| ... | ... | @@ -186153,7 +186123,7 @@ const Temp = struct { |
| 186153 | 186123 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| 186154 | 186124 | const mcv = temp.tracking(cg).short; |
| 186155 | 186125 | 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 }), | |
| 186157 | 186127 | .register => |reg| { |
| 186158 | 186128 | const new_reg = try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| 186159 | 186129 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| ... | ... | @@ -186227,7 +186197,7 @@ const Temp = struct { |
| 186227 | 186197 | const new_temp_index = cg.next_temp_index; |
| 186228 | 186198 | cg.temp_type[@intFromEnum(new_temp_index)] = limb_ty; |
| 186229 | 186199 | 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 }), | |
| 186231 | 186201 | .immediate => |imm| { |
| 186232 | 186202 | assert(limb_index == 0); |
| 186233 | 186203 | new_temp_index.tracking(cg).* = .init(.{ .immediate = imm }); |
| ... | ... | @@ -186568,7 +186538,7 @@ const Temp = struct { |
| 186568 | 186538 | }, |
| 186569 | 186539 | else => {}, |
| 186570 | 186540 | } |
| 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 }); | |
| 186572 | 186542 | } |
| 186573 | 186543 | |
| 186574 | 186544 | fn asMask(temp: Temp, info: MaskInfo, cg: *CodeGen) void { |
| ... | ... | @@ -186658,7 +186628,7 @@ const Temp = struct { |
| 186658 | 186628 | while (try ptr.toLea(cg)) {} |
| 186659 | 186629 | const val_mcv = val.tracking(cg).short; |
| 186660 | 186630 | 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 }), | |
| 186662 | 186632 | .register => |val_reg| try ptr.loadReg(val_ty, registerAlias( |
| 186663 | 186633 | val_reg, |
| 186664 | 186634 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| ... | ... | @@ -186698,7 +186668,7 @@ const Temp = struct { |
| 186698 | 186668 | {}) { |
| 186699 | 186669 | const val_mcv = val.tracking(cg).short; |
| 186700 | 186670 | 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 }), | |
| 186702 | 186672 | .undef => if (opts.safe) { |
| 186703 | 186673 | var pat = try cg.tempInit(.u8, .{ .immediate = 0xaa }); |
| 186704 | 186674 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| ... | ... | @@ -186772,7 +186742,7 @@ const Temp = struct { |
| 186772 | 186742 | assert(!val_ty.optionalReprIsPayload(cg.pt.zcu)); |
| 186773 | 186743 | break :first_ty opt_child; |
| 186774 | 186744 | }, |
| 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) }), | |
| 186776 | 186746 | }); |
| 186777 | 186747 | const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu)); |
| 186778 | 186748 | try ptr.storeRegs(first_ty, &.{registerAlias(val_reg_ov.reg, first_size)}, cg); |
| ... | ... | @@ -186804,7 +186774,7 @@ const Temp = struct { |
| 186804 | 186774 | |
| 186805 | 186775 | fn readTo(src: *Temp, val_ty: Type, val_mcv: MCValue, opts: AccessOptions, cg: *CodeGen) InnerError!void { |
| 186806 | 186776 | 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 }), | |
| 186808 | 186778 | .register => |val_reg| try src.readReg(opts.disp, val_ty, registerAlias( |
| 186809 | 186779 | val_reg, |
| 186810 | 186780 | @intCast(cg.unalignedSize(val_ty)), |
| ... | ... | @@ -186844,7 +186814,7 @@ const Temp = struct { |
| 186844 | 186814 | {}) { |
| 186845 | 186815 | const val_mcv = val.tracking(cg).short; |
| 186846 | 186816 | 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 }), | |
| 186848 | 186818 | .none => {}, |
| 186849 | 186819 | .undef => if (opts.safe) { |
| 186850 | 186820 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp)); |
| ... | ... | @@ -186905,7 +186875,7 @@ const Temp = struct { |
| 186905 | 186875 | assert(!val_ty.optionalReprIsPayload(cg.pt.zcu)); |
| 186906 | 186876 | break :first_ty opt_child; |
| 186907 | 186877 | }, |
| 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) }), | |
| 186909 | 186879 | }); |
| 186910 | 186880 | const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu)); |
| 186911 | 186881 | try dst.writeReg(opts.disp, first_ty, registerAlias(val_reg_ov.reg, first_size), cg); |
| ... | ... | @@ -191677,12 +191647,12 @@ const Temp = struct { |
| 191677 | 191647 | break :result result; |
| 191678 | 191648 | }, |
| 191679 | 191649 | }; |
| 191680 | tracking_log.debug("{} => {} (birth)", .{ inst, result }); | |
| 191650 | tracking_log.debug("{f} => {f} (birth)", .{ inst, result }); | |
| 191681 | 191651 | cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(result)); |
| 191682 | 191652 | }, |
| 191683 | 191653 | .temp => |temp_index| { |
| 191684 | 191654 | 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 }); | |
| 191686 | 191656 | cg.inst_tracking.putAssumeCapacityNoClobber(inst, .init(temp_tracking.short)); |
| 191687 | 191657 | assert(cg.reuseTemp(inst, temp_index.toIndex(), temp_tracking)); |
| 191688 | 191658 | }, |
| ... | ... | @@ -191757,7 +191727,7 @@ fn resetTemps(cg: *CodeGen, from_index: Temp.Index) InnerError!void { |
| 191757 | 191727 | const temp: Temp.Index = @enumFromInt(temp_index); |
| 191758 | 191728 | if (temp.isValid(cg)) { |
| 191759 | 191729 | any_valid = true; |
| 191760 | tracking_log.err("failed to kill {}: {}", .{ | |
| 191730 | tracking_log.err("failed to kill {f}: {f}", .{ | |
| 191761 | 191731 | temp.toIndex(), |
| 191762 | 191732 | cg.temp_type[temp_index].fmt(cg.pt), |
| 191763 | 191733 | }); |
src/arch/x86_64/Disassembler.zig+73-92| ... | ... | @@ -31,10 +31,11 @@ pub fn init(code: []const u8) Disassembler { |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | pub 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 | ||
| 37 | fn nextInner(dis: *Disassembler) anyerror!?Instruction { | |
| 38 | const prefixes = try dis.parsePrefixes(); | |
| 38 | 39 | |
| 39 | 40 | const enc = try dis.parseEncoding(prefixes) orelse return error.UnknownOpcode; |
| 40 | 41 | switch (enc.data.op_en) { |
| ... | ... | @@ -283,66 +284,53 @@ const Prefixes = struct { |
| 283 | 284 | |
| 284 | 285 | fn parsePrefixes(dis: *Disassembler) !Prefixes { |
| 285 | 286 | const rex_prefix_mask: u4 = 0b0100; |
| 286 | var stream = std.io.fixedBufferStream(dis.code[dis.pos..]); | |
| 287 | const reader = stream.reader(); | |
| 288 | ||
| 289 | 287 | 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 | } | |
| 290 | 317 | |
| 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 | |
| 332 | 319 | |
| 320 | dis.pos = pos; | |
| 321 | break; | |
| 322 | }, | |
| 323 | }; | |
| 333 | 324 | return res; |
| 334 | 325 | } |
| 335 | 326 | |
| 336 | 327 | fn parseEncoding(dis: *Disassembler, prefixes: Prefixes) !?Encoding { |
| 337 | 328 | const o_mask: u8 = 0b1111_1000; |
| 338 | ||
| 339 | 329 | var opcode: [3]u8 = .{ 0, 0, 0 }; |
| 340 | var stream = std.io.fixedBufferStream(dis.code[dis.pos..]); | |
| 341 | const reader = stream.reader(); | |
| 342 | 330 | |
| 343 | 331 | comptime var opc_count = 0; |
| 344 | 332 | inline while (opc_count < 3) : (opc_count += 1) { |
| 345 | const byte = try reader.readByte(); | |
| 333 | const byte = dis.code[dis.pos]; | |
| 346 | 334 | opcode[opc_count] = byte; |
| 347 | 335 | dis.pos += 1; |
| 348 | 336 | |
| ... | ... | @@ -387,30 +375,27 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi |
| 387 | 375 | }; |
| 388 | 376 | } |
| 389 | 377 | |
| 390 | fn 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)), | |
| 378 | fn 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)), | |
| 402 | 390 | else => unreachable, |
| 403 | 391 | }; |
| 404 | dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow; | |
| 405 | return imm; | |
| 406 | 392 | } |
| 407 | 393 | |
| 408 | fn 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; | |
| 394 | fn 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); | |
| 414 | 399 | } |
| 415 | 400 | |
| 416 | 401 | const ModRm = packed struct { |
| ... | ... | @@ -482,26 +467,22 @@ fn parseSibByte(dis: *Disassembler) !Sib { |
| 482 | 467 | return Sib{ .scale = scale, .index = index, .base = base }; |
| 483 | 468 | } |
| 484 | 469 | |
| 485 | fn 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); | |
| 470 | fn 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); | |
| 497 | 477 | } |
| 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, | |
| 504 | 487 | }; |
| 505 | dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow; | |
| 506 | return disp; | |
| 507 | 488 | } |
src/arch/x86_64/Emit.zig+16-21| ... | ... | @@ -424,19 +424,19 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 424 | 424 | .line = mir_inst.data.line_column.line, |
| 425 | 425 | .column = mir_inst.data.line_column.column, |
| 426 | 426 | .is_stmt = true, |
| 427 | }), | |
| 427 | }, emit.code.items.len), | |
| 428 | 428 | .pseudo_dbg_line_line_column => try emit.dbgAdvancePCAndLine(.{ |
| 429 | 429 | .line = mir_inst.data.line_column.line, |
| 430 | 430 | .column = mir_inst.data.line_column.column, |
| 431 | 431 | .is_stmt = false, |
| 432 | }), | |
| 432 | }, emit.code.items.len), | |
| 433 | 433 | .pseudo_dbg_epilogue_begin_none => switch (emit.debug_output) { |
| 434 | 434 | .dwarf => |dwarf| { |
| 435 | 435 | try dwarf.setEpilogueBegin(); |
| 436 | 436 | log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{ |
| 437 | 437 | emit.prev_di_loc.line, emit.prev_di_loc.column, |
| 438 | 438 | }); |
| 439 | try emit.dbgAdvancePCAndLine(emit.prev_di_loc); | |
| 439 | try emit.dbgAdvancePCAndLine(emit.prev_di_loc, emit.code.items.len); | |
| 440 | 440 | }, |
| 441 | 441 | .plan9 => {}, |
| 442 | 442 | .none => {}, |
| ... | ... | @@ -909,9 +909,9 @@ const Loc = struct { |
| 909 | 909 | is_stmt: bool, |
| 910 | 910 | }; |
| 911 | 911 | |
| 912 | fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void { | |
| 912 | fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc, pc: usize) anyerror!void { | |
| 913 | 913 | 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; | |
| 915 | 915 | log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line }); |
| 916 | 916 | switch (emit.debug_output) { |
| 917 | 917 | .dwarf => |dwarf| { |
| ... | ... | @@ -919,30 +919,25 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void { |
| 919 | 919 | if (loc.column != emit.prev_di_loc.column) try dwarf.setColumn(loc.column); |
| 920 | 920 | try dwarf.advancePCAndLine(delta_line, delta_pc); |
| 921 | 921 | emit.prev_di_loc = loc; |
| 922 | emit.prev_di_pc = emit.code.items.len; | |
| 922 | emit.prev_di_pc = pc; | |
| 923 | 923 | }, |
| 924 | 924 | .plan9 => |dbg_out| { |
| 925 | 925 | if (delta_pc <= 0) return; // only do this when the pc changes |
| 926 | 926 | |
| 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 | ||
| 927 | 931 | // 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)); | |
| 929 | 933 | // increasing the pc |
| 930 | 934 | const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta; |
| 931 | 935 | if (d_pc_p9 > 0) { |
| 932 | 936 | // 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); | |
| 946 | 941 | } else if (d_pc_p9 == 0) { |
| 947 | 942 | // we don't need to do anything, because adding the pc quanta does it for us |
| 948 | 943 | } else unreachable; |
| ... | ... | @@ -951,7 +946,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void { |
| 951 | 946 | dbg_out.end_line = loc.line; |
| 952 | 947 | // only do this if the pc changed |
| 953 | 948 | emit.prev_di_loc = loc; |
| 954 | emit.prev_di_pc = emit.code.items.len; | |
| 949 | emit.prev_di_pc = pc; | |
| 955 | 950 | }, |
| 956 | 951 | .none => {}, |
| 957 | 952 | } |
src/arch/x86_64/Encoding.zig+25-29| ... | ... | @@ -158,20 +158,14 @@ pub fn modRmExt(encoding: Encoding) u3 { |
| 158 | 158 | }; |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | pub fn format( | |
| 162 | encoding: Encoding, | |
| 163 | comptime fmt: []const u8, | |
| 164 | options: std.fmt.FormatOptions, | |
| 165 | writer: anytype, | |
| 166 | ) !void { | |
| 167 | _ = options; | |
| 161 | pub fn format(encoding: Encoding, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void { | |
| 168 | 162 | _ = fmt; |
| 169 | 163 | |
| 170 | 164 | var opc = encoding.opcode(); |
| 171 | 165 | if (encoding.data.mode.isVex()) { |
| 172 | try writer.writeAll("VEX."); | |
| 166 | try bw.writeAll("VEX."); | |
| 173 | 167 | |
| 174 | try writer.writeAll(switch (encoding.data.mode) { | |
| 168 | try bw.writeAll(switch (encoding.data.mode) { | |
| 175 | 169 | .vex_128_w0, .vex_128_w1, .vex_128_wig => "128", |
| 176 | 170 | .vex_256_w0, .vex_256_w1, .vex_256_wig => "256", |
| 177 | 171 | .vex_lig_w0, .vex_lig_w1, .vex_lig_wig => "LIG", |
| ... | ... | @@ -182,25 +176,25 @@ pub fn format( |
| 182 | 176 | switch (opc[0]) { |
| 183 | 177 | else => {}, |
| 184 | 178 | 0x66, 0xf3, 0xf2 => { |
| 185 | try writer.print(".{X:0>2}", .{opc[0]}); | |
| 179 | try bw.print(".{X:0>2}", .{opc[0]}); | |
| 186 | 180 | opc = opc[1..]; |
| 187 | 181 | }, |
| 188 | 182 | } |
| 189 | 183 | |
| 190 | try writer.print(".{}", .{std.fmt.fmtSliceHexUpper(opc[0 .. opc.len - 1])}); | |
| 184 | try bw.print(".{X}", .{opc[0 .. opc.len - 1]}); | |
| 191 | 185 | opc = opc[opc.len - 1 ..]; |
| 192 | 186 | |
| 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) { | |
| 195 | 189 | .vex_128_w0, .vex_256_w0, .vex_lig_w0, .vex_lz_w0 => "0", |
| 196 | 190 | .vex_128_w1, .vex_256_w1, .vex_lig_w1, .vex_lz_w1 => "1", |
| 197 | 191 | .vex_128_wig, .vex_256_wig, .vex_lig_wig, .vex_lz_wig => "IG", |
| 198 | 192 | else => unreachable, |
| 199 | 193 | }); |
| 200 | 194 | |
| 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}); | |
| 204 | 198 | |
| 205 | 199 | switch (encoding.data.op_en) { |
| 206 | 200 | .z, .fd, .td, .i, .zi, .ii, .d => {}, |
| ... | ... | @@ -217,10 +211,10 @@ pub fn format( |
| 217 | 211 | .r64 => "rd", |
| 218 | 212 | else => unreachable, |
| 219 | 213 | }; |
| 220 | try writer.print("+{s} ", .{tag}); | |
| 214 | try bw.print("+{s} ", .{tag}); | |
| 221 | 215 | }, |
| 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 "), | |
| 224 | 218 | } |
| 225 | 219 | |
| 226 | 220 | switch (encoding.data.op_en) { |
| ... | ... | @@ -249,24 +243,24 @@ pub fn format( |
| 249 | 243 | .rel32 => "cd", |
| 250 | 244 | else => unreachable, |
| 251 | 245 | }; |
| 252 | try writer.print("{s} ", .{tag}); | |
| 246 | try bw.print("{s} ", .{tag}); | |
| 253 | 247 | }, |
| 254 | .rvmr => try writer.writeAll("/is4 "), | |
| 248 | .rvmr => try bw.writeAll("/is4 "), | |
| 255 | 249 | .z, .fd, .td, .o, .zo, .oz, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .vm, .rvm, .mvr, .rmv => {}, |
| 256 | 250 | } |
| 257 | 251 | |
| 258 | try writer.print("{s} ", .{@tagName(encoding.mnemonic)}); | |
| 252 | try bw.print("{s} ", .{@tagName(encoding.mnemonic)}); | |
| 259 | 253 | |
| 260 | 254 | for (encoding.data.ops) |op| switch (op) { |
| 261 | 255 | .none => break, |
| 262 | else => try writer.print("{s} ", .{@tagName(op)}), | |
| 256 | else => try bw.print("{s} ", .{@tagName(op)}), | |
| 263 | 257 | }; |
| 264 | 258 | |
| 265 | 259 | const op_en = switch (encoding.data.op_en) { |
| 266 | 260 | .zi => .i, |
| 267 | 261 | else => |op_en| op_en, |
| 268 | 262 | }; |
| 269 | try writer.print("{s}", .{@tagName(op_en)}); | |
| 263 | try bw.print("{s}", .{@tagName(op_en)}); | |
| 270 | 264 | } |
| 271 | 265 | |
| 272 | 266 | pub const Mnemonic = enum { |
| ... | ... | @@ -1014,19 +1008,21 @@ pub const Feature = enum { |
| 1014 | 1008 | }; |
| 1015 | 1009 | |
| 1016 | 1010 | fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Operand) usize { |
| 1017 | var inst = Instruction{ | |
| 1011 | var inst: Instruction = .{ | |
| 1018 | 1012 | .prefix = prefix, |
| 1019 | 1013 | .encoding = encoding, |
| 1020 | 1014 | .ops = @splat(.none), |
| 1021 | 1015 | }; |
| 1022 | 1016 | @memcpy(inst.ops[0..ops.len], ops); |
| 1023 | 1017 | |
| 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, .{ | |
| 1026 | 1022 | .allow_frame_locs = true, |
| 1027 | 1023 | .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); | |
| 1030 | 1026 | } |
| 1031 | 1027 | |
| 1032 | 1028 | const mnemonic_to_encodings_map = init: { |
src/arch/x86_64/bits.zig+9-26| ... | ... | @@ -728,21 +728,12 @@ pub const FrameIndex = enum(u32) { |
| 728 | 728 | return @intFromEnum(fi) < named_count; |
| 729 | 729 | } |
| 730 | 730 | |
| 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)}); | |
| 746 | 737 | } |
| 747 | 738 | }; |
| 748 | 739 | |
| ... | ... | @@ -844,21 +835,13 @@ pub const Memory = struct { |
| 844 | 835 | }; |
| 845 | 836 | } |
| 846 | 837 | |
| 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 { | |
| 853 | 839 | if (s == .none) return; |
| 854 | try writer.writeAll(@tagName(s)); | |
| 840 | try bw.writeAll(@tagName(s)); | |
| 855 | 841 | switch (s) { |
| 856 | 842 | .none => unreachable, |
| 857 | 843 | .ptr, .gpr => {}, |
| 858 | else => { | |
| 859 | try writer.writeByte(' '); | |
| 860 | try writer.writeAll("ptr"); | |
| 861 | }, | |
| 844 | else => try bw.writeAll(" ptr"), | |
| 862 | 845 | } |
| 863 | 846 | } |
| 864 | 847 | }; |
src/arch/x86_64/encoder.zig+102-121| ... | ... | @@ -226,16 +226,10 @@ pub const Instruction = struct { |
| 226 | 226 | }; |
| 227 | 227 | } |
| 228 | 228 | |
| 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 { | |
| 235 | 230 | _ = op; |
| 231 | _ = bw; | |
| 236 | 232 | _ = unused_format_string; |
| 237 | _ = options; | |
| 238 | _ = writer; | |
| 239 | 233 | @compileError("do not format Operand directly; use fmt() instead"); |
| 240 | 234 | } |
| 241 | 235 | |
| ... | ... | @@ -244,78 +238,72 @@ pub const Instruction = struct { |
| 244 | 238 | enc_op: Encoding.Op, |
| 245 | 239 | }; |
| 246 | 240 | |
| 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 { | |
| 253 | 242 | _ = unused_format_string; |
| 254 | _ = options; | |
| 255 | 243 | const op = ctx.op; |
| 256 | 244 | const enc_op = ctx.enc_op; |
| 257 | 245 | switch (op) { |
| 258 | 246 | .none => {}, |
| 259 | .reg => |reg| try writer.writeAll(@tagName(reg)), | |
| 247 | .reg => |reg| try bw.writeAll(@tagName(reg)), | |
| 260 | 248 | .mem => |mem| switch (mem) { |
| 261 | 249 | .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}", .{ | |
| 264 | 252 | @as(u8, if (rip.disp < 0) '-' else '+'), |
| 265 | 253 | @abs(rip.disp), |
| 266 | 254 | }); |
| 267 | try writer.writeByte(']'); | |
| 255 | try bw.writeByte(']'); | |
| 268 | 256 | }, |
| 269 | 257 | .sib => |sib| { |
| 270 | try writer.print("{} ", .{sib.ptr_size}); | |
| 258 | try bw.print("{f} ", .{sib.ptr_size}); | |
| 271 | 259 | |
| 272 | 260 | 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 }); | |
| 274 | 262 | } |
| 275 | 263 | |
| 276 | try writer.writeByte('['); | |
| 264 | try bw.writeByte('['); | |
| 277 | 265 | |
| 278 | 266 | var any = true; |
| 279 | 267 | switch (sib.base) { |
| 280 | 268 | .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})", .{ | |
| 288 | 276 | @tagName(lazy_sym.kind), |
| 289 | 277 | @intFromEnum(lazy_sym.ty), |
| 290 | 278 | }), |
| 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)}), | |
| 292 | 280 | } |
| 293 | 281 | 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 }); | |
| 296 | 284 | any = true; |
| 297 | 285 | } |
| 298 | 286 | if (sib.disp != 0 or !any) { |
| 299 | 287 | 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 '+')}) | |
| 301 | 289 | 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)}); | |
| 304 | 292 | any = true; |
| 305 | 293 | } |
| 306 | 294 | |
| 307 | try writer.writeByte(']'); | |
| 295 | try bw.writeByte(']'); | |
| 308 | 296 | }, |
| 309 | .moffs => |moffs| try writer.print("{s}:0x{x}", .{ | |
| 297 | .moffs => |moffs| try bw.print("{s}:0x{x}", .{ | |
| 310 | 298 | @tagName(moffs.seg), |
| 311 | 299 | moffs.offset, |
| 312 | 300 | }), |
| 313 | 301 | }, |
| 314 | 302 | .imm => |imm| if (enc_op.isSigned()) { |
| 315 | 303 | 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())}), | |
| 319 | 307 | .bytes => unreachable, |
| 320 | 308 | } |
| 321 | 309 | } |
| ... | ... | @@ -361,7 +349,7 @@ pub const Instruction = struct { |
| 361 | 349 | }, |
| 362 | 350 | }, |
| 363 | 351 | }; |
| 364 | log.debug("selected encoding: {}", .{encoding}); | |
| 352 | log.debug("selected encoding: {f}", .{encoding}); | |
| 365 | 353 | |
| 366 | 354 | var inst: Instruction = .{ |
| 367 | 355 | .prefix = prefix, |
| ... | ... | @@ -372,30 +360,23 @@ pub const Instruction = struct { |
| 372 | 360 | return inst; |
| 373 | 361 | } |
| 374 | 362 | |
| 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 { | |
| 381 | 364 | _ = unused_format_string; |
| 382 | _ = options; | |
| 383 | 365 | switch (inst.prefix) { |
| 384 | 366 | .none, .directive => {}, |
| 385 | else => try writer.print("{s} ", .{@tagName(inst.prefix)}), | |
| 367 | else => try bw.print("{s} ", .{@tagName(inst.prefix)}), | |
| 386 | 368 | } |
| 387 | try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)}); | |
| 369 | try bw.print("{s}", .{@tagName(inst.encoding.mnemonic)}); | |
| 388 | 370 | for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| { |
| 389 | 371 | 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)}); | |
| 393 | 374 | } |
| 394 | 375 | } |
| 395 | 376 | |
| 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 { | |
| 397 | 378 | assert(inst.prefix != .directive); |
| 398 | const encoder = Encoder(@TypeOf(writer), opts){ .writer = writer }; | |
| 379 | const encoder: Encoder(opts) = .{ .bw = bw }; | |
| 399 | 380 | const enc = inst.encoding; |
| 400 | 381 | const data = enc.data; |
| 401 | 382 | |
| ... | ... | @@ -801,9 +782,9 @@ pub const LegacyPrefixes = packed struct { |
| 801 | 782 | |
| 802 | 783 | pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool = false }; |
| 803 | 784 | |
| 804 | fn Encoder(comptime T: type, comptime opts: Options) type { | |
| 785 | fn Encoder(comptime opts: Options) type { | |
| 805 | 786 | return struct { |
| 806 | writer: T, | |
| 787 | bw: *std.io.BufferedWriter, | |
| 807 | 788 | |
| 808 | 789 | const Self = @This(); |
| 809 | 790 | pub const options = opts; |
| ... | ... | @@ -813,44 +794,44 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 813 | 794 | // -------- |
| 814 | 795 | |
| 815 | 796 | /// Encodes legacy prefixes |
| 816 | pub fn legacyPrefixes(self: Self, prefixes: LegacyPrefixes) !void { | |
| 797 | pub fn legacyPrefixes(self: Self, prefixes: LegacyPrefixes) anyerror!void { | |
| 817 | 798 | if (@as(u16, @bitCast(prefixes)) != 0) { |
| 818 | 799 | // Hopefully this path isn't taken very often, so we'll do it the slow way for now |
| 819 | 800 | |
| 820 | 801 | // LOCK |
| 821 | if (prefixes.prefix_f0) try self.writer.writeByte(0xf0); | |
| 802 | if (prefixes.prefix_f0) try self.bw.writeByte(0xf0); | |
| 822 | 803 | // 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); | |
| 824 | 805 | // 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); | |
| 826 | 807 | |
| 827 | 808 | // 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); | |
| 829 | 810 | // DS segment override |
| 830 | if (prefixes.prefix_36) try self.writer.writeByte(0x36); | |
| 811 | if (prefixes.prefix_36) try self.bw.writeByte(0x36); | |
| 831 | 812 | // ES segment override |
| 832 | if (prefixes.prefix_26) try self.writer.writeByte(0x26); | |
| 813 | if (prefixes.prefix_26) try self.bw.writeByte(0x26); | |
| 833 | 814 | // FS segment override |
| 834 | if (prefixes.prefix_64) try self.writer.writeByte(0x64); | |
| 815 | if (prefixes.prefix_64) try self.bw.writeByte(0x64); | |
| 835 | 816 | // GS segment override |
| 836 | if (prefixes.prefix_65) try self.writer.writeByte(0x65); | |
| 817 | if (prefixes.prefix_65) try self.bw.writeByte(0x65); | |
| 837 | 818 | |
| 838 | 819 | // Branch taken |
| 839 | if (prefixes.prefix_3e) try self.writer.writeByte(0x3e); | |
| 820 | if (prefixes.prefix_3e) try self.bw.writeByte(0x3e); | |
| 840 | 821 | |
| 841 | 822 | // Operand size override |
| 842 | if (prefixes.prefix_66) try self.writer.writeByte(0x66); | |
| 823 | if (prefixes.prefix_66) try self.bw.writeByte(0x66); | |
| 843 | 824 | |
| 844 | 825 | // Address size override |
| 845 | if (prefixes.prefix_67) try self.writer.writeByte(0x67); | |
| 826 | if (prefixes.prefix_67) try self.bw.writeByte(0x67); | |
| 846 | 827 | } |
| 847 | 828 | } |
| 848 | 829 | |
| 849 | 830 | /// Use 16 bit operand size |
| 850 | 831 | /// |
| 851 | 832 | /// 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); | |
| 854 | 835 | } |
| 855 | 836 | |
| 856 | 837 | /// Encodes a REX prefix byte given all the fields |
| ... | ... | @@ -859,7 +840,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 859 | 840 | /// or one of reg, index, r/m, base, or opcode-reg might be extended. |
| 860 | 841 | /// |
| 861 | 842 | /// 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 { | |
| 863 | 844 | if (!fields.present and !fields.isSet()) return; |
| 864 | 845 | |
| 865 | 846 | var byte: u8 = 0b0100_0000; |
| ... | ... | @@ -869,32 +850,32 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 869 | 850 | if (fields.x) byte |= 0b0010; |
| 870 | 851 | if (fields.b) byte |= 0b0001; |
| 871 | 852 | |
| 872 | try self.writer.writeByte(byte); | |
| 853 | try self.bw.writeByte(byte); | |
| 873 | 854 | } |
| 874 | 855 | |
| 875 | 856 | /// Encodes a VEX prefix given all the fields |
| 876 | 857 | /// |
| 877 | 858 | /// 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 { | |
| 879 | 860 | if (fields.is3Byte()) { |
| 880 | try self.writer.writeByte(0b1100_0100); | |
| 861 | try self.bw.writeByte(0b1100_0100); | |
| 881 | 862 | |
| 882 | try self.writer.writeByte( | |
| 863 | try self.bw.writeByte( | |
| 883 | 864 | @as(u8, ~@intFromBool(fields.r)) << 7 | |
| 884 | 865 | @as(u8, ~@intFromBool(fields.x)) << 6 | |
| 885 | 866 | @as(u8, ~@intFromBool(fields.b)) << 5 | |
| 886 | 867 | @as(u8, @intFromEnum(fields.m)) << 0, |
| 887 | 868 | ); |
| 888 | 869 | |
| 889 | try self.writer.writeByte( | |
| 870 | try self.bw.writeByte( | |
| 890 | 871 | @as(u8, @intFromBool(fields.w)) << 7 | |
| 891 | 872 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | |
| 892 | 873 | @as(u8, @intFromBool(fields.l)) << 2 | |
| 893 | 874 | @as(u8, @intFromEnum(fields.p)) << 0, |
| 894 | 875 | ); |
| 895 | 876 | } 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( | |
| 898 | 879 | @as(u8, ~@intFromBool(fields.r)) << 7 | |
| 899 | 880 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | |
| 900 | 881 | @as(u8, @intFromBool(fields.l)) << 2 | |
| ... | ... | @@ -908,8 +889,8 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 908 | 889 | // ------ |
| 909 | 890 | |
| 910 | 891 | /// 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); | |
| 913 | 894 | } |
| 914 | 895 | |
| 915 | 896 | /// Encodes a 2 byte opcode |
| ... | ... | @@ -917,8 +898,8 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 917 | 898 | /// e.g. IMUL has the opcode 0x0f 0xaf, so you use |
| 918 | 899 | /// |
| 919 | 900 | /// 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 }); | |
| 922 | 903 | } |
| 923 | 904 | |
| 924 | 905 | /// Encodes a 3 byte opcode |
| ... | ... | @@ -926,16 +907,16 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 926 | 907 | /// e.g. MOVSD has the opcode 0xf2 0x0f 0x10 |
| 927 | 908 | /// |
| 928 | 909 | /// 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 }); | |
| 931 | 912 | } |
| 932 | 913 | |
| 933 | 914 | /// Encodes a 1 byte opcode with a reg field |
| 934 | 915 | /// |
| 935 | 916 | /// 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 { | |
| 937 | 918 | assert(opcode & 0b111 == 0); |
| 938 | try self.writer.writeByte(opcode | reg); | |
| 919 | try self.bw.writeByte(opcode | reg); | |
| 939 | 920 | } |
| 940 | 921 | |
| 941 | 922 | // ------ |
| ... | ... | @@ -945,8 +926,8 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 945 | 926 | /// Construct a ModR/M byte given all the fields |
| 946 | 927 | /// |
| 947 | 928 | /// 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); | |
| 950 | 931 | } |
| 951 | 932 | |
| 952 | 933 | /// Construct a ModR/M byte using direct r/m addressing |
| ... | ... | @@ -954,7 +935,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 954 | 935 | /// |
| 955 | 936 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 956 | 937 | /// 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 { | |
| 958 | 939 | try self.modRm(0b11, reg_or_opx, rm); |
| 959 | 940 | } |
| 960 | 941 | |
| ... | ... | @@ -963,7 +944,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 963 | 944 | /// |
| 964 | 945 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 965 | 946 | /// 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 { | |
| 967 | 948 | assert(rm != 4 and rm != 5); |
| 968 | 949 | try self.modRm(0b00, reg_or_opx, rm); |
| 969 | 950 | } |
| ... | ... | @@ -973,7 +954,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 973 | 954 | /// |
| 974 | 955 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 975 | 956 | /// 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 { | |
| 977 | 958 | try self.modRm(0b00, reg_or_opx, 0b100); |
| 978 | 959 | } |
| 979 | 960 | |
| ... | ... | @@ -982,7 +963,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 982 | 963 | /// |
| 983 | 964 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 984 | 965 | /// 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 { | |
| 986 | 967 | try self.modRm(0b00, reg_or_opx, 0b101); |
| 987 | 968 | } |
| 988 | 969 | |
| ... | ... | @@ -991,7 +972,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 991 | 972 | /// |
| 992 | 973 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 993 | 974 | /// 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 { | |
| 995 | 976 | assert(rm != 4); |
| 996 | 977 | try self.modRm(0b01, reg_or_opx, rm); |
| 997 | 978 | } |
| ... | ... | @@ -1001,7 +982,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1001 | 982 | /// |
| 1002 | 983 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 1003 | 984 | /// 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 { | |
| 1005 | 986 | try self.modRm(0b01, reg_or_opx, 0b100); |
| 1006 | 987 | } |
| 1007 | 988 | |
| ... | ... | @@ -1010,7 +991,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1010 | 991 | /// |
| 1011 | 992 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 1012 | 993 | /// 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 { | |
| 1014 | 995 | assert(rm != 4); |
| 1015 | 996 | try self.modRm(0b10, reg_or_opx, rm); |
| 1016 | 997 | } |
| ... | ... | @@ -1020,7 +1001,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1020 | 1001 | /// |
| 1021 | 1002 | /// Note reg's effective address is always just reg for the ModR/M byte. |
| 1022 | 1003 | /// 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 { | |
| 1024 | 1005 | try self.modRm(0b10, reg_or_opx, 0b100); |
| 1025 | 1006 | } |
| 1026 | 1007 | |
| ... | ... | @@ -1031,15 +1012,15 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1031 | 1012 | /// Construct a SIB byte given all the fields |
| 1032 | 1013 | /// |
| 1033 | 1014 | /// 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); | |
| 1036 | 1017 | } |
| 1037 | 1018 | |
| 1038 | 1019 | /// Construct a SIB byte with scale * index + base, no frills. |
| 1039 | 1020 | /// r/m effective address: [base + scale * index] |
| 1040 | 1021 | /// |
| 1041 | 1022 | /// 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 { | |
| 1043 | 1024 | assert(base != 5); |
| 1044 | 1025 | |
| 1045 | 1026 | try self.sib(scale, index, base); |
| ... | ... | @@ -1049,7 +1030,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1049 | 1030 | /// r/m effective address: [scale * index + disp32] |
| 1050 | 1031 | /// |
| 1051 | 1032 | /// 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 { | |
| 1053 | 1034 | // scale is actually ignored |
| 1054 | 1035 | // index = 4 means no index if and only if we haven't extended the register |
| 1055 | 1036 | // TODO enforce this |
| ... | ... | @@ -1061,7 +1042,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1061 | 1042 | /// r/m effective address: [base] |
| 1062 | 1043 | /// |
| 1063 | 1044 | /// 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 { | |
| 1065 | 1046 | assert(base != 5); |
| 1066 | 1047 | |
| 1067 | 1048 | // scale is actually ignored |
| ... | ... | @@ -1073,7 +1054,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1073 | 1054 | /// r/m effective address: [disp32] |
| 1074 | 1055 | /// |
| 1075 | 1056 | /// 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 { | |
| 1077 | 1058 | // scale is actually ignored |
| 1078 | 1059 | // index = 4 means no index |
| 1079 | 1060 | // base = 5 means no base, if mod == 0. |
| ... | ... | @@ -1084,7 +1065,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1084 | 1065 | /// r/m effective address: [base + scale * index + disp8] |
| 1085 | 1066 | /// |
| 1086 | 1067 | /// 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 { | |
| 1088 | 1069 | try self.sib(scale, index, base); |
| 1089 | 1070 | } |
| 1090 | 1071 | |
| ... | ... | @@ -1092,7 +1073,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1092 | 1073 | /// r/m effective address: [base + disp8] |
| 1093 | 1074 | /// |
| 1094 | 1075 | /// 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 { | |
| 1096 | 1077 | // scale is ignored |
| 1097 | 1078 | // index = 4 means no index |
| 1098 | 1079 | try self.sib(0, 4, base); |
| ... | ... | @@ -1102,7 +1083,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1102 | 1083 | /// r/m effective address: [base + scale * index + disp32] |
| 1103 | 1084 | /// |
| 1104 | 1085 | /// 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 { | |
| 1106 | 1087 | try self.sib(scale, index, base); |
| 1107 | 1088 | } |
| 1108 | 1089 | |
| ... | ... | @@ -1110,7 +1091,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1110 | 1091 | /// r/m effective address: [base + disp32] |
| 1111 | 1092 | /// |
| 1112 | 1093 | /// 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 { | |
| 1114 | 1095 | // scale is ignored |
| 1115 | 1096 | // index = 4 means no index |
| 1116 | 1097 | try self.sib(0, 4, base); |
| ... | ... | @@ -1123,43 +1104,43 @@ fn Encoder(comptime T: type, comptime opts: Options) type { |
| 1123 | 1104 | /// Encode an 8 bit displacement |
| 1124 | 1105 | /// |
| 1125 | 1106 | /// 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))); | |
| 1128 | 1109 | } |
| 1129 | 1110 | |
| 1130 | 1111 | /// Encode an 32 bit displacement |
| 1131 | 1112 | /// |
| 1132 | 1113 | /// 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); | |
| 1135 | 1116 | } |
| 1136 | 1117 | |
| 1137 | 1118 | /// Encode an 8 bit immediate |
| 1138 | 1119 | /// |
| 1139 | 1120 | /// 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); | |
| 1142 | 1123 | } |
| 1143 | 1124 | |
| 1144 | 1125 | /// Encode an 16 bit immediate |
| 1145 | 1126 | /// |
| 1146 | 1127 | /// 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); | |
| 1149 | 1130 | } |
| 1150 | 1131 | |
| 1151 | 1132 | /// Encode an 32 bit immediate |
| 1152 | 1133 | /// |
| 1153 | 1134 | /// 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); | |
| 1156 | 1137 | } |
| 1157 | 1138 | |
| 1158 | 1139 | /// Encode an 64 bit immediate |
| 1159 | 1140 | /// |
| 1160 | 1141 | /// 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); | |
| 1163 | 1144 | } |
| 1164 | 1145 | }; |
| 1165 | 1146 | } |
| ... | ... | @@ -2217,10 +2198,10 @@ const Assembler = struct { |
| 2217 | 2198 | }; |
| 2218 | 2199 | } |
| 2219 | 2200 | |
| 2220 | pub fn assemble(as: *Assembler, writer: anytype) !void { | |
| 2201 | pub fn assemble(as: *Assembler, bw: *std.io.BufferedWriter) !void { | |
| 2221 | 2202 | while (try as.next()) |parsed_inst| { |
| 2222 | 2203 | const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops); |
| 2223 | try inst.encode(writer, .{}); | |
| 2204 | try inst.encode(bw, .{}); | |
| 2224 | 2205 | } |
| 2225 | 2206 | } |
| 2226 | 2207 |
src/codegen.zig+127-149| ... | ... | @@ -225,14 +225,6 @@ pub fn generateLazyFunction( |
| 225 | 225 | } |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | fn 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 | ||
| 236 | 228 | pub fn generateLazySymbol( |
| 237 | 229 | bin_file: *link.File, |
| 238 | 230 | pt: Zcu.PerThread, |
| ... | ... | @@ -256,7 +248,7 @@ pub fn generateLazySymbol( |
| 256 | 248 | const target = &comp.root_mod.resolved_target.result; |
| 257 | 249 | const endian = target.cpu.arch.endian(); |
| 258 | 250 | |
| 259 | log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ | |
| 251 | log.debug("generateLazySymbol: kind = {s}, ty = {f}", .{ | |
| 260 | 252 | @tagName(lazy_sym.kind), |
| 261 | 253 | Type.fromInterned(lazy_sym.ty).fmt(pt), |
| 262 | 254 | }); |
| ... | ... | @@ -296,7 +288,7 @@ pub fn generateLazySymbol( |
| 296 | 288 | code.appendAssumeCapacity(0); |
| 297 | 289 | } |
| 298 | 290 | } 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}", .{ | |
| 300 | 292 | @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt), |
| 301 | 293 | }); |
| 302 | 294 | } |
| ... | ... | @@ -321,19 +313,31 @@ pub fn generateSymbol( |
| 321 | 313 | const tracy = trace(@src()); |
| 322 | 314 | defer tracy.end(); |
| 323 | 315 | |
| 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 | } | |
| 321 | pub 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 { | |
| 324 | 329 | const zcu = pt.zcu; |
| 325 | const gpa = zcu.gpa; | |
| 326 | 330 | const ip = &zcu.intern_pool; |
| 327 | 331 | const ty = val.typeOf(zcu); |
| 328 | 332 | |
| 329 | 333 | const target = zcu.getTarget(); |
| 330 | 334 | const endian = target.cpu.arch.endian(); |
| 331 | 335 | |
| 332 | log.debug("generateSymbol: val = {}", .{val.fmtValue(pt)}); | |
| 336 | log.debug("generateSymbol: val = {f}", .{val.fmtValue(pt)}); | |
| 333 | 337 | |
| 334 | 338 | if (val.isUndefDeep(zcu)) { |
| 335 | 339 | 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); | |
| 337 | 341 | return; |
| 338 | 342 | } |
| 339 | 343 | |
| ... | ... | @@ -363,7 +367,7 @@ pub fn generateSymbol( |
| 363 | 367 | .null => unreachable, // non-runtime value |
| 364 | 368 | .@"unreachable" => unreachable, // non-runtime value |
| 365 | 369 | .empty_tuple => return, |
| 366 | .false, .true => try code.append(gpa, switch (simple_value) { | |
| 370 | .false, .true => try bw.writeByte(switch (simple_value) { | |
| 367 | 371 | .false => 0, |
| 368 | 372 | .true => 1, |
| 369 | 373 | else => unreachable, |
| ... | ... | @@ -379,11 +383,12 @@ pub fn generateSymbol( |
| 379 | 383 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; |
| 380 | 384 | var space: Value.BigIntSpace = undefined; |
| 381 | 385 | 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); | |
| 383 | 388 | }, |
| 384 | 389 | .err => |err| { |
| 385 | 390 | 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); | |
| 387 | 392 | }, |
| 388 | 393 | .error_union => |error_union| { |
| 389 | 394 | const payload_ty = ty.errorUnionPayload(zcu); |
| ... | ... | @@ -393,7 +398,7 @@ pub fn generateSymbol( |
| 393 | 398 | }; |
| 394 | 399 | |
| 395 | 400 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 396 | try code.writer(gpa).writeInt(u16, err_val, endian); | |
| 401 | try bw.writeInt(u16, err_val, endian); | |
| 397 | 402 | return; |
| 398 | 403 | } |
| 399 | 404 | |
| ... | ... | @@ -403,57 +408,49 @@ pub fn generateSymbol( |
| 403 | 408 | |
| 404 | 409 | // error value first when its type is larger than the error union's payload |
| 405 | 410 | 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); | |
| 407 | 412 | } |
| 408 | 413 | |
| 409 | 414 | // emit payload part of the error union |
| 410 | 415 | { |
| 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) { | |
| 413 | 418 | .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), |
| 414 | 419 | .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; | |
| 417 | 422 | 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); | |
| 423 | 424 | } |
| 424 | 425 | |
| 425 | 426 | // Payload size is larger than error set, so emit our error set last |
| 426 | 427 | 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; | |
| 430 | 431 | 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); | |
| 436 | 433 | } |
| 437 | 434 | }, |
| 438 | 435 | .enum_tag => |enum_tag| { |
| 439 | 436 | 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); | |
| 441 | 438 | }, |
| 442 | 439 | .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), | |
| 446 | 443 | .f80 => |f80_val| { |
| 447 | writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(gpa, 10)); | |
| 444 | try bw.writeInt(u80, @bitCast(f80_val), endian); | |
| 448 | 445 | 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); | |
| 450 | 447 | }, |
| 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), | |
| 452 | 449 | }, |
| 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), | |
| 454 | 451 | .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); | |
| 457 | 454 | }, |
| 458 | 455 | .opt => { |
| 459 | 456 | const payload_type = ty.optionalChild(zcu); |
| ... | ... | @@ -462,44 +459,44 @@ pub fn generateSymbol( |
| 462 | 459 | |
| 463 | 460 | if (ty.optionalReprIsPayload(zcu)) { |
| 464 | 461 | 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); | |
| 466 | 463 | } else { |
| 467 | try code.appendNTimes(gpa, 0, abi_size); | |
| 464 | try bw.splatByteAll(0, abi_size); | |
| 468 | 465 | } |
| 469 | 466 | } else { |
| 470 | 467 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(zcu)) orelse return error.Overflow) - 1; |
| 471 | 468 | 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(.{ | |
| 473 | 470 | .undef = payload_type.toIntern(), |
| 474 | 471 | })); |
| 475 | try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent); | |
| 472 | try generateSymbolInner(bin_file, pt, src_loc, value, bw, reloc_parent); | |
| 476 | 473 | } |
| 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); | |
| 479 | 476 | } |
| 480 | 477 | }, |
| 481 | 478 | .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) { |
| 482 | 479 | .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)), | |
| 484 | 481 | .elems, .repeated_elem => { |
| 485 | 482 | var index: u64 = 0; |
| 486 | 483 | 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) { | |
| 488 | 485 | .bytes => unreachable, |
| 489 | 486 | .elems => |elems| elems[@intCast(index)], |
| 490 | 487 | .repeated_elem => |elem| if (index < array_type.len) |
| 491 | 488 | elem |
| 492 | 489 | else |
| 493 | 490 | array_type.sentinel, |
| 494 | }), code, reloc_parent); | |
| 491 | }), bw, reloc_parent); | |
| 495 | 492 | } |
| 496 | 493 | }, |
| 497 | 494 | }, |
| 498 | 495 | .vector_type => |vector_type| { |
| 499 | 496 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; |
| 500 | 497 | 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); | |
| 503 | 500 | var index: usize = 0; |
| 504 | 501 | const len = math.cast(usize, vector_type.len) orelse return error.Overflow; |
| 505 | 502 | while (index < len) : (index += 1) { |
| ... | ... | @@ -507,7 +504,7 @@ pub fn generateSymbol( |
| 507 | 504 | .big => len - 1 - index, |
| 508 | 505 | .little => index, |
| 509 | 506 | }; |
| 510 | const byte = &bytes[bit_index / 8]; | |
| 507 | const byte = &buffer[bit_index / 8]; | |
| 511 | 508 | const mask = @as(u8, 1) << @truncate(bit_index); |
| 512 | 509 | if (switch (switch (aggregate.storage) { |
| 513 | 510 | .bytes => unreachable, |
| ... | ... | @@ -535,31 +532,31 @@ pub fn generateSymbol( |
| 535 | 532 | }, |
| 536 | 533 | }) byte.* |= mask else byte.* &= ~mask; |
| 537 | 534 | } |
| 535 | bw.advance(abi_size); | |
| 538 | 536 | } else { |
| 539 | 537 | 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)), | |
| 541 | 539 | .elems, .repeated_elem => { |
| 542 | 540 | var index: u64 = 0; |
| 543 | 541 | 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) { | |
| 545 | 543 | .bytes => unreachable, |
| 546 | 544 | .elems => |elems| elems[ |
| 547 | 545 | math.cast(usize, index) orelse return error.Overflow |
| 548 | 546 | ], |
| 549 | 547 | .repeated_elem => |elem| elem, |
| 550 | }), code, reloc_parent); | |
| 548 | }), bw, reloc_parent); | |
| 551 | 549 | } |
| 552 | 550 | }, |
| 553 | 551 | } |
| 554 | 552 | |
| 555 | const padding = abi_size - | |
| 553 | try bw.splatByteAll(0, abi_size - | |
| 556 | 554 | (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)); | |
| 559 | 556 | } |
| 560 | 557 | }, |
| 561 | 558 | .tuple_type => |tuple| { |
| 562 | const struct_begin = code.items.len; | |
| 559 | const struct_begin = bw.count; | |
| 563 | 560 | for ( |
| 564 | 561 | tuple.types.get(ip), |
| 565 | 562 | tuple.values.get(ip), |
| ... | ... | @@ -577,17 +574,13 @@ pub fn generateSymbol( |
| 577 | 574 | .repeated_elem => |elem| elem, |
| 578 | 575 | }; |
| 579 | 576 | |
| 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; | |
| 582 | 579 | |
| 583 | 580 | // Pad struct members if required |
| 584 | 581 | 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); | |
| 591 | 584 | } |
| 592 | 585 | }, |
| 593 | 586 | .struct_type => { |
| ... | ... | @@ -595,8 +588,9 @@ pub fn generateSymbol( |
| 595 | 588 | switch (struct_type.layout) { |
| 596 | 589 | .@"packed" => { |
| 597 | 590 | 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); | |
| 600 | 594 | var bits: u16 = 0; |
| 601 | 595 | |
| 602 | 596 | for (struct_type.field_types.get(ip), 0..) |field_ty, index| { |
| ... | ... | @@ -616,22 +610,25 @@ pub fn generateSymbol( |
| 616 | 610 | error.DivisionByZero => unreachable, |
| 617 | 611 | error.UnexpectedRemainder => return error.RelocationNotByteAligned, |
| 618 | 612 | }; |
| 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; | |
| 621 | 615 | 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; | |
| 625 | 621 | } |
| 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); | |
| 627 | 623 | } 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; | |
| 629 | 625 | } |
| 630 | 626 | bits += @intCast(Type.fromInterned(field_ty).bitSize(zcu)); |
| 631 | 627 | } |
| 628 | bw.advance(abi_size); | |
| 632 | 629 | }, |
| 633 | 630 | .auto, .@"extern" => { |
| 634 | const struct_begin = code.items.len; | |
| 631 | const struct_begin = bw.count; | |
| 635 | 632 | const field_types = struct_type.field_types.get(ip); |
| 636 | 633 | const offsets = struct_type.offsets.get(ip); |
| 637 | 634 | |
| ... | ... | @@ -649,24 +646,22 @@ pub fn generateSymbol( |
| 649 | 646 | .repeated_elem => |elem| elem, |
| 650 | 647 | }; |
| 651 | 648 | |
| 652 | const padding = math.cast( | |
| 649 | try bw.splatByteAll(0, math.cast( | |
| 653 | 650 | 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); | |
| 657 | 653 | |
| 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); | |
| 659 | 655 | } |
| 660 | 656 | |
| 661 | 657 | const size = struct_type.sizeUnordered(ip); |
| 662 | 658 | const alignment = struct_type.flagsUnordered(ip).alignment.toByteUnits().?; |
| 663 | 659 | |
| 664 | const padding = math.cast( | |
| 660 | try bw.splatByteAll(0, math.cast( | |
| 665 | 661 | usize, |
| 666 | 662 | 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); | |
| 670 | 665 | }, |
| 671 | 666 | } |
| 672 | 667 | }, |
| ... | ... | @@ -676,38 +671,31 @@ pub fn generateSymbol( |
| 676 | 671 | const layout = ty.unionGetLayout(zcu); |
| 677 | 672 | |
| 678 | 673 | 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); | |
| 680 | 675 | } |
| 681 | 676 | |
| 682 | 677 | // Check if we should store the tag first. |
| 683 | 678 | 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); | |
| 685 | 680 | } |
| 686 | 681 | |
| 687 | 682 | const union_obj = zcu.typeToUnion(ty).?; |
| 688 | 683 | 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).?; | |
| 690 | 685 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 691 | 686 | 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); | |
| 693 | 688 | } 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); | |
| 700 | 691 | } |
| 701 | 692 | } 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); | |
| 703 | 694 | } |
| 704 | 695 | |
| 705 | 696 | 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); | |
| 711 | 699 | } |
| 712 | 700 | }, |
| 713 | 701 | .memoized_call => unreachable, |
| ... | ... | @@ -719,32 +707,32 @@ fn lowerPtr( |
| 719 | 707 | pt: Zcu.PerThread, |
| 720 | 708 | src_loc: Zcu.LazySrcLoc, |
| 721 | 709 | ptr_val: InternPool.Index, |
| 722 | code: *std.ArrayListUnmanaged(u8), | |
| 710 | bw: *std.io.BufferedWriter, | |
| 723 | 711 | reloc_parent: link.File.RelocInfo.Parent, |
| 724 | 712 | prev_offset: u64, |
| 725 | ) GenerateSymbolError!void { | |
| 713 | ) anyerror!void { | |
| 726 | 714 | const zcu = pt.zcu; |
| 727 | 715 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 728 | 716 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 729 | 717 | 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), | |
| 733 | 721 | .eu_payload => |eu_ptr| try lowerPtr( |
| 734 | 722 | bin_file, |
| 735 | 723 | pt, |
| 736 | 724 | src_loc, |
| 737 | 725 | eu_ptr, |
| 738 | code, | |
| 726 | bw, | |
| 739 | 727 | reloc_parent, |
| 740 | 728 | offset + errUnionPayloadOffset( |
| 741 | 729 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu), |
| 742 | 730 | zcu, |
| 743 | 731 | ), |
| 744 | 732 | ), |
| 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), | |
| 746 | 734 | .field => |field| { |
| 747 | const base_ptr = Value.fromInterned(field.base); | |
| 735 | const base_ptr: Value = .fromInterned(field.base); | |
| 748 | 736 | const base_ty = base_ptr.typeOf(zcu).childType(zcu); |
| 749 | 737 | const field_off: u64 = switch (base_ty.zigTypeTag(zcu)) { |
| 750 | 738 | .pointer => off: { |
| ... | ... | @@ -761,7 +749,7 @@ fn lowerPtr( |
| 761 | 749 | }, |
| 762 | 750 | else => unreachable, |
| 763 | 751 | }; |
| 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); | |
| 765 | 753 | }, |
| 766 | 754 | .arr_elem, .comptime_field, .comptime_alloc => unreachable, |
| 767 | 755 | }; |
| ... | ... | @@ -772,12 +760,11 @@ fn lowerUavRef( |
| 772 | 760 | pt: Zcu.PerThread, |
| 773 | 761 | src_loc: Zcu.LazySrcLoc, |
| 774 | 762 | uav: InternPool.Key.Ptr.BaseAddr.Uav, |
| 775 | code: *std.ArrayListUnmanaged(u8), | |
| 763 | bw: *std.io.BufferedWriter, | |
| 776 | 764 | reloc_parent: link.File.RelocInfo.Parent, |
| 777 | 765 | offset: u64, |
| 778 | ) GenerateSymbolError!void { | |
| 766 | ) anyerror!void { | |
| 779 | 767 | const zcu = pt.zcu; |
| 780 | const gpa = zcu.gpa; | |
| 781 | 768 | const ip = &zcu.intern_pool; |
| 782 | 769 | const comp = lf.comp; |
| 783 | 770 | const target = &comp.root_mod.resolved_target.result; |
| ... | ... | @@ -786,13 +773,9 @@ fn lowerUavRef( |
| 786 | 773 | const uav_ty = Type.fromInterned(ip.typeOf(uav_val)); |
| 787 | 774 | const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn"; |
| 788 | 775 | |
| 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)}); | |
| 791 | 777 | |
| 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); | |
| 796 | 779 | |
| 797 | 780 | switch (lf.tag) { |
| 798 | 781 | .c => unreachable, |
| ... | ... | @@ -801,9 +784,8 @@ fn lowerUavRef( |
| 801 | 784 | dev.check(link.File.Tag.wasm.devFeature()); |
| 802 | 785 | const wasm = lf.cast(.wasm).?; |
| 803 | 786 | 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); | |
| 807 | 789 | }, |
| 808 | 790 | else => {}, |
| 809 | 791 | } |
| ... | ... | @@ -816,14 +798,14 @@ fn lowerUavRef( |
| 816 | 798 | |
| 817 | 799 | const vaddr = try lf.getUavVAddr(uav_val, .{ |
| 818 | 800 | .parent = reloc_parent, |
| 819 | .offset = code.items.len, | |
| 801 | .offset = bw.count, | |
| 820 | 802 | .addend = @intCast(offset), |
| 821 | 803 | }); |
| 822 | 804 | const endian = target.cpu.arch.endian(); |
| 823 | 805 | 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), | |
| 827 | 809 | else => unreachable, |
| 828 | 810 | } |
| 829 | 811 | } |
| ... | ... | @@ -832,10 +814,10 @@ fn lowerNavRef( |
| 832 | 814 | lf: *link.File, |
| 833 | 815 | pt: Zcu.PerThread, |
| 834 | 816 | nav_index: InternPool.Nav.Index, |
| 835 | code: *std.ArrayListUnmanaged(u8), | |
| 817 | bw: *std.io.BufferedWriter, | |
| 836 | 818 | reloc_parent: link.File.RelocInfo.Parent, |
| 837 | 819 | offset: u64, |
| 838 | ) GenerateSymbolError!void { | |
| 820 | ) anyerror!void { | |
| 839 | 821 | const zcu = pt.zcu; |
| 840 | 822 | const gpa = zcu.gpa; |
| 841 | 823 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -845,12 +827,9 @@ fn lowerNavRef( |
| 845 | 827 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); |
| 846 | 828 | const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn"; |
| 847 | 829 | |
| 848 | try code.ensureUnusedCapacity(gpa, ptr_width_bytes); | |
| 830 | log.debug("lowerNavRef: ty = {f}", .{nav_ty.fmt(pt)}); | |
| 849 | 831 | |
| 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); | |
| 854 | 833 | |
| 855 | 834 | switch (lf.tag) { |
| 856 | 835 | .c => unreachable, |
| ... | ... | @@ -867,13 +846,13 @@ fn lowerNavRef( |
| 867 | 846 | } else { |
| 868 | 847 | try wasm.func_table_fixups.append(gpa, .{ |
| 869 | 848 | .table_index = @enumFromInt(gop.index), |
| 870 | .offset = @intCast(code.items.len), | |
| 849 | .offset = @intCast(bw.count), | |
| 871 | 850 | }); |
| 872 | 851 | } |
| 873 | 852 | } else { |
| 874 | 853 | if (is_obj) { |
| 875 | 854 | try wasm.out_relocs.append(gpa, .{ |
| 876 | .offset = @intCast(code.items.len), | |
| 855 | .offset = @intCast(bw.count), | |
| 877 | 856 | .pointee = .{ .symbol_index = try wasm.navSymbolIndex(nav_index) }, |
| 878 | 857 | .tag = if (ptr_width_bytes == 4) .memory_addr_i32 else .memory_addr_i64, |
| 879 | 858 | .addend = @intCast(offset), |
| ... | ... | @@ -882,27 +861,26 @@ fn lowerNavRef( |
| 882 | 861 | try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1); |
| 883 | 862 | wasm.nav_fixups.appendAssumeCapacity(.{ |
| 884 | 863 | .navs_exe_index = try wasm.refNavExe(nav_index), |
| 885 | .offset = @intCast(code.items.len), | |
| 864 | .offset = @intCast(bw.count), | |
| 886 | 865 | .addend = @intCast(offset), |
| 887 | 866 | }); |
| 888 | 867 | } |
| 889 | 868 | } |
| 890 | code.appendNTimesAssumeCapacity(0, ptr_width_bytes); | |
| 891 | return; | |
| 869 | return bw.splatByteAll(0, ptr_width_bytes); | |
| 892 | 870 | }, |
| 893 | 871 | else => {}, |
| 894 | 872 | } |
| 895 | 873 | |
| 896 | 874 | const vaddr = lf.getNavVAddr(pt, nav_index, .{ |
| 897 | 875 | .parent = reloc_parent, |
| 898 | .offset = code.items.len, | |
| 876 | .offset = bw.count, | |
| 899 | 877 | .addend = @intCast(offset), |
| 900 | 878 | }) catch @panic("TODO rework getNavVAddr"); |
| 901 | 879 | const endian = target.cpu.arch.endian(); |
| 902 | 880 | 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), | |
| 906 | 884 | else => unreachable, |
| 907 | 885 | } |
| 908 | 886 | } |
| ... | ... | @@ -1084,7 +1062,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo |
| 1084 | 1062 | const ip = &zcu.intern_pool; |
| 1085 | 1063 | const ty = val.typeOf(zcu); |
| 1086 | 1064 | |
| 1087 | log.debug("lowerValue(@as({}, {}))", .{ ty.fmt(pt), val.fmtValue(pt) }); | |
| 1065 | log.debug("lowerValue(@as({f}, {f}))", .{ ty.fmt(pt), val.fmtValue(pt) }); | |
| 1088 | 1066 | |
| 1089 | 1067 | if (val.isUndef(zcu)) return .undef; |
| 1090 | 1068 |
src/codegen/llvm.zig+14-12| ... | ... | @@ -746,12 +746,14 @@ pub const Object = struct { |
| 746 | 746 | try wip.finish(); |
| 747 | 747 | } |
| 748 | 748 | |
| 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(); | |
| 751 | 753 | 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); | |
| 753 | 755 | } |
| 754 | try object.builder.finishModuleAsm(); | |
| 756 | try object.builder.finishModuleAsm(&aw); | |
| 755 | 757 | } |
| 756 | 758 | |
| 757 | 759 | pub const EmitOptions = struct { |
| ... | ... | @@ -939,7 +941,7 @@ pub const Object = struct { |
| 939 | 941 | if (std.mem.eql(u8, path, "-")) { |
| 940 | 942 | o.builder.dump(); |
| 941 | 943 | } else { |
| 942 | _ = try o.builder.printToFile(path); | |
| 944 | _ = o.builder.printToFile(path); | |
| 943 | 945 | } |
| 944 | 946 | } |
| 945 | 947 | |
| ... | ... | @@ -2677,9 +2679,9 @@ pub const Object = struct { |
| 2677 | 2679 | |
| 2678 | 2680 | fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 { |
| 2679 | 2681 | var aw: std.io.AllocatingWriter = undefined; |
| 2680 | const bw = aw.init(o.gpa); | |
| 2682 | aw.init(o.gpa); | |
| 2681 | 2683 | defer aw.deinit(); |
| 2682 | try ty.print(bw, o.pt); | |
| 2684 | ty.print(&aw.buffered_writer, o.pt) catch |err| return @errorCast(err); | |
| 2683 | 2685 | return aw.toOwnedSliceSentinel(0); |
| 2684 | 2686 | } |
| 2685 | 2687 | |
| ... | ... | @@ -4479,7 +4481,7 @@ pub const Object = struct { |
| 4479 | 4481 | const target = &zcu.root_mod.resolved_target.result; |
| 4480 | 4482 | const function_index = try o.builder.addFunction( |
| 4481 | 4483 | 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)}), | |
| 4483 | 4485 | toLlvmAddressSpace(.generic, target), |
| 4484 | 4486 | ); |
| 4485 | 4487 | |
| ... | ... | @@ -4630,7 +4632,7 @@ pub const NavGen = struct { |
| 4630 | 4632 | if (zcu.getTarget().cpu.arch.isWasm() and ty.zigTypeTag(zcu) == .@"fn") { |
| 4631 | 4633 | if (lib_name.toSlice(ip)) |lib_name_slice| { |
| 4632 | 4634 | 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 }); | |
| 4634 | 4636 | } |
| 4635 | 4637 | } |
| 4636 | 4638 | } |
| ... | ... | @@ -7469,7 +7471,7 @@ pub const FuncGen = struct { |
| 7469 | 7471 | llvm_param_types[llvm_param_i] = llvm_elem_ty; |
| 7470 | 7472 | } |
| 7471 | 7473 | |
| 7472 | try llvm_constraints.writer(self.gpa).print(",{d}", .{output_index}); | |
| 7474 | try llvm_constraints.print(self.gpa, ",{d}", .{output_index}); | |
| 7473 | 7475 | |
| 7474 | 7476 | // In the case of indirect inputs, LLVM requires the callsite to have |
| 7475 | 7477 | // an elementtype(<ty>) attribute. |
| ... | ... | @@ -7570,7 +7572,7 @@ pub const FuncGen = struct { |
| 7570 | 7572 | // we should validate the assembly in Sema; by now it is too late |
| 7571 | 7573 | return self.todo("unknown input or output name: '{s}'", .{name}); |
| 7572 | 7574 | }; |
| 7573 | try rendered_template.writer().print("{d}", .{index}); | |
| 7575 | try rendered_template.print("{d}", .{index}); | |
| 7574 | 7576 | if (byte == ':') { |
| 7575 | 7577 | try rendered_template.append(':'); |
| 7576 | 7578 | modifier_start = i + 1; |
| ... | ... | @@ -10377,7 +10379,7 @@ pub const FuncGen = struct { |
| 10377 | 10379 | const target = &zcu.root_mod.resolved_target.result; |
| 10378 | 10380 | const function_index = try o.builder.addFunction( |
| 10379 | 10381 | 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)}), | |
| 10381 | 10383 | toLlvmAddressSpace(.generic, target), |
| 10382 | 10384 | ); |
| 10383 | 10385 |
src/codegen/spirv.zig+9-9| ... | ... | @@ -817,7 +817,7 @@ const NavGen = struct { |
| 817 | 817 | const result_ty_id = try self.resolveType(ty, repr); |
| 818 | 818 | const ip = &zcu.intern_pool; |
| 819 | 819 | |
| 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())) }); | |
| 821 | 821 | if (val.isUndefDeep(zcu)) { |
| 822 | 822 | return self.spv.constUndef(result_ty_id); |
| 823 | 823 | } |
| ... | ... | @@ -1147,7 +1147,7 @@ const NavGen = struct { |
| 1147 | 1147 | return result_ptr_id; |
| 1148 | 1148 | } |
| 1149 | 1149 | |
| 1150 | return self.fail("cannot perform pointer cast: '{}' to '{}'", .{ | |
| 1150 | return self.fail("cannot perform pointer cast: '{f}' to '{f}'", .{ | |
| 1151 | 1151 | parent_ptr_ty.fmt(pt), |
| 1152 | 1152 | oac.new_ptr_ty.fmt(pt), |
| 1153 | 1153 | }); |
| ... | ... | @@ -1259,11 +1259,11 @@ const NavGen = struct { |
| 1259 | 1259 | } |
| 1260 | 1260 | |
| 1261 | 1261 | // 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(); | |
| 1267 | 1267 | } |
| 1268 | 1268 | |
| 1269 | 1269 | /// Create an integer type suitable for storing at least 'bits' bits. |
| ... | ... | @@ -1462,7 +1462,7 @@ const NavGen = struct { |
| 1462 | 1462 | const pt = self.pt; |
| 1463 | 1463 | const zcu = pt.zcu; |
| 1464 | 1464 | const ip = &zcu.intern_pool; |
| 1465 | log.debug("resolveType: ty = {}", .{ty.fmt(pt)}); | |
| 1465 | log.debug("resolveType: ty = {f}", .{ty.fmt(pt)}); | |
| 1466 | 1466 | const target = self.spv.target; |
| 1467 | 1467 | |
| 1468 | 1468 | const section = &self.spv.sections.types_globals_constants; |
| ... | ... | @@ -3068,7 +3068,7 @@ const NavGen = struct { |
| 3068 | 3068 | try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); |
| 3069 | 3069 | try self.spv.addFunction(spv_decl_index, self.func); |
| 3070 | 3070 | |
| 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)}); | |
| 3072 | 3072 | |
| 3073 | 3073 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{ |
| 3074 | 3074 | .id_result_type = ptr_ty_id, |
src/codegen/spirv/spec.zig+3-8| ... | ... | @@ -18,15 +18,10 @@ pub const IdResult = enum(Word) { |
| 18 | 18 | none, |
| 19 | 19 | _, |
| 20 | 20 | |
| 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 { | |
| 27 | 22 | 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)}), | |
| 30 | 25 | } |
| 31 | 26 | } |
| 32 | 27 | }; |
src/crash_report.zig+13-12| ... | ... | @@ -80,18 +80,18 @@ fn dumpStatusReport() !void { |
| 80 | 80 | var fba = std.heap.FixedBufferAllocator.init(&crash_heap); |
| 81 | 81 | const allocator = fba.allocator(); |
| 82 | 82 | |
| 83 | const stderr = std.fs.File.stderr.writer().unbuffered(); | |
| 83 | var stderr = std.fs.File.stderr().writer().unbuffered(); | |
| 84 | 84 | const block: *Sema.Block = anal.block; |
| 85 | 85 | const zcu = anal.sema.pt.zcu; |
| 86 | 86 | |
| 87 | 87 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse { |
| 88 | 88 | 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)}); | |
| 90 | 90 | return; |
| 91 | 91 | }; |
| 92 | 92 | |
| 93 | 93 | 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)}); | |
| 95 | 95 | |
| 96 | 96 | print_zir.renderInstructionContext( |
| 97 | 97 | allocator, |
| ... | ... | @@ -100,14 +100,14 @@ fn dumpStatusReport() !void { |
| 100 | 100 | file, |
| 101 | 101 | src_base_node, |
| 102 | 102 | 6, // indent |
| 103 | stderr, | |
| 103 | &stderr, | |
| 104 | 104 | ) catch |err| switch (err) { |
| 105 | 105 | error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"), |
| 106 | 106 | else => |e| return e, |
| 107 | 107 | }; |
| 108 | 108 | try stderr.print( |
| 109 | 109 | \\ For full context, use the command |
| 110 | \\ zig ast-check -t {} | |
| 110 | \\ zig ast-check -t {f} | |
| 111 | 111 | \\ |
| 112 | 112 | \\ |
| 113 | 113 | , .{file.path.fmt(zcu.comp)}); |
| ... | ... | @@ -116,7 +116,7 @@ fn dumpStatusReport() !void { |
| 116 | 116 | while (parent) |curr| { |
| 117 | 117 | fba.reset(); |
| 118 | 118 | 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)}); | |
| 120 | 120 | _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse { |
| 121 | 121 | try stderr.writeAll(" > [lost instruction; this should not happen]\n"); |
| 122 | 122 | parent = curr.parent; |
| ... | ... | @@ -129,7 +129,7 @@ fn dumpStatusReport() !void { |
| 129 | 129 | cur_block_file, |
| 130 | 130 | cur_block_src_base_node, |
| 131 | 131 | 6, // indent |
| 132 | stderr, | |
| 132 | &stderr, | |
| 133 | 133 | ) catch |err| switch (err) { |
| 134 | 134 | error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"), |
| 135 | 135 | else => |e| return e, |
| ... | ... | @@ -139,7 +139,7 @@ fn dumpStatusReport() !void { |
| 139 | 139 | parent = curr.parent; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | try stderr.writeAll("\n"); | |
| 142 | try stderr.writeByte('\n'); | |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | var crash_heap: [16 * 4096]u8 = undefined; |
| ... | ... | @@ -268,7 +268,8 @@ const StackContext = union(enum) { |
| 268 | 268 | debug.dumpCurrentStackTrace(ct.ret_addr); |
| 269 | 269 | }, |
| 270 | 270 | .exception => |context| { |
| 271 | debug.dumpStackTraceFromBase(context); | |
| 271 | var stderr = std.fs.File.stderr().writer().unbuffered(); | |
| 272 | debug.dumpStackTraceFromBase(context, &stderr); | |
| 272 | 273 | }, |
| 273 | 274 | .not_supported => { |
| 274 | 275 | std.fs.File.stderr().writeAll("Stack trace not supported on this platform.\n") catch {}; |
| ... | ... | @@ -378,7 +379,7 @@ const PanicSwitch = struct { |
| 378 | 379 | |
| 379 | 380 | state.recover_stage = .release_mutex; |
| 380 | 381 | |
| 381 | const stderr = std.fs.File.stderr().writer().unbuffered(); | |
| 382 | var stderr = std.fs.File.stderr().writer().unbuffered(); | |
| 382 | 383 | if (builtin.single_threaded) { |
| 383 | 384 | stderr.print("panic: ", .{}) catch goTo(releaseMutex, .{state}); |
| 384 | 385 | } else { |
| ... | ... | @@ -405,7 +406,7 @@ const PanicSwitch = struct { |
| 405 | 406 | recover(state, trace, stack, msg); |
| 406 | 407 | |
| 407 | 408 | state.recover_stage = .release_mutex; |
| 408 | const stderr = std.fs.File.stderr().writer().unbuffered(); | |
| 409 | var stderr = std.fs.File.stderr().writer().unbuffered(); | |
| 409 | 410 | stderr.writeAll("\nOriginal Error:\n") catch {}; |
| 410 | 411 | goTo(reportStack, .{state}); |
| 411 | 412 | } |
| ... | ... | @@ -521,7 +522,7 @@ const PanicSwitch = struct { |
| 521 | 522 | var stderr = std.fs.File.stderr().writer().unbuffered(); |
| 522 | 523 | stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {}; |
| 523 | 524 | stderr.writeAll(msg) catch {}; |
| 524 | stderr.writeAll("\n") catch {}; | |
| 525 | stderr.writeByte('\n') catch {}; | |
| 525 | 526 | |
| 526 | 527 | // If we succeed, restore all the way to dumping the stack. |
| 527 | 528 | 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 { |
| 89 | 89 | fatal("cannot use --stdin with positional arguments", .{}); |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | const source_code = std.zig.readSourceFileToEndAlloc(gpa, .stdin(), null) catch |err| { | |
| 92 | const source_code = std.zig.readSourceFileToEndAlloc(gpa, .stdin(), 0) catch |err| { | |
| 93 | 93 | fatal("unable to read stdin: {}", .{err}); |
| 94 | 94 | }; |
| 95 | 95 | defer gpa.free(source_code); |
| ... | ... | @@ -134,9 +134,9 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 134 | 134 | process.exit(2); |
| 135 | 135 | } |
| 136 | 136 | var aw: std.io.AllocatingWriter = undefined; |
| 137 | const bw = aw.init(gpa); | |
| 137 | aw.init(gpa); | |
| 138 | 138 | defer aw.deinit(); |
| 139 | try tree.render(gpa, bw, .{}); | |
| 139 | try tree.render(gpa, &aw.buffered_writer, .{}); | |
| 140 | 140 | const formatted = aw.getWritten(); |
| 141 | 141 | |
| 142 | 142 | if (check_flag) { |
src/libs/glibc.zig+24-33| ... | ... | @@ -736,13 +736,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 736 | 736 | .lt => continue, |
| 737 | 737 | .gt => { |
| 738 | 738 | // 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}); | |
| 740 | 740 | return error.InvalidTargetGLibCVersion; |
| 741 | 741 | }, |
| 742 | 742 | } |
| 743 | 743 | } else blk: { |
| 744 | 744 | 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}", .{ | |
| 746 | 746 | target_version, metadata.all_versions[latest_index], |
| 747 | 747 | }); |
| 748 | 748 | break :blk latest_index; |
| ... | ... | @@ -752,9 +752,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 752 | 752 | var map_contents = std.ArrayList(u8).init(arena); |
| 753 | 753 | for (metadata.all_versions[0 .. target_ver_index + 1]) |ver| { |
| 754 | 754 | 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 }); | |
| 756 | 756 | } 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 }); | |
| 758 | 758 | } |
| 759 | 759 | } |
| 760 | 760 | 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 |
| 773 | 773 | try stubs_asm.appendSlice(".text\n"); |
| 774 | 774 | |
| 775 | 775 | var sym_i: usize = 0; |
| 776 | var sym_name_buf = std.ArrayList(u8).init(arena); | |
| 777 | 776 | var opt_symbol_name: ?[]const u8 = null; |
| 778 | 777 | var versions_buffer: [32]u8 = undefined; |
| 779 | 778 | var versions_len: usize = undefined; |
| ... | ... | @@ -794,24 +793,20 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 794 | 793 | // twice, which causes a "duplicate symbol" assembler error. |
| 795 | 794 | var versions_written = std.AutoArrayHashMap(Version, void).init(arena); |
| 796 | 795 | |
| 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); | |
| 799 | 798 | |
| 800 | const fn_inclusions_len = try inc_reader.readInt(u16, .little); | |
| 799 | const fn_inclusions_len = try inc_br.takeInt(u16, .little); | |
| 801 | 800 | |
| 802 | 801 | while (sym_i < fn_inclusions_len) : (sym_i += 1) { |
| 803 | 802 | 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); | |
| 808 | 804 | versions_buffer = undefined; |
| 809 | 805 | versions_len = 0; |
| 810 | ||
| 811 | break :n sym_name_buf.items; | |
| 806 | break :n opt_symbol_name.?; | |
| 812 | 807 | }; |
| 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(); | |
| 815 | 810 | |
| 816 | 811 | const is_terminal = (lib_index & (1 << 7)) != 0; |
| 817 | 812 | if (is_terminal) { |
| ... | ... | @@ -825,7 +820,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 825 | 820 | ((targets & (@as(u64, 1) << @as(u6, @intCast(target_targ_index)))) != 0); |
| 826 | 821 | |
| 827 | 822 | while (true) { |
| 828 | const byte = try inc_reader.readByte(); | |
| 823 | const byte = try inc_br.takeByte(); | |
| 829 | 824 | const last = (byte & 0b1000_0000) != 0; |
| 830 | 825 | const ver_i = @as(u7, @truncate(byte)); |
| 831 | 826 | 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 |
| 880 | 875 | "{s}_{d}_{d}", |
| 881 | 876 | .{ sym_name, ver.major, ver.minor }, |
| 882 | 877 | ); |
| 883 | try stubs_asm.writer().print( | |
| 878 | try stubs_asm.print( | |
| 884 | 879 | \\.balign {d} |
| 885 | 880 | \\.globl {s} |
| 886 | 881 | \\.type {s}, %function |
| ... | ... | @@ -905,7 +900,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 905 | 900 | "{s}_{d}_{d}_{d}", |
| 906 | 901 | .{ sym_name, ver.major, ver.minor, ver.patch }, |
| 907 | 902 | ); |
| 908 | try stubs_asm.writer().print( | |
| 903 | try stubs_asm.print( | |
| 909 | 904 | \\.balign {d} |
| 910 | 905 | \\.globl {s} |
| 911 | 906 | \\.type {s}, %function |
| ... | ... | @@ -950,7 +945,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 950 | 945 | // versions where the symbol didn't exist. We only care about modern glibc versions, so use |
| 951 | 946 | // a strong reference. |
| 952 | 947 | if (std.mem.eql(u8, lib.name, "c")) { |
| 953 | try stubs_asm.writer().print( | |
| 948 | try stubs_asm.print( | |
| 954 | 949 | \\.balign {d} |
| 955 | 950 | \\.globl _IO_stdin_used |
| 956 | 951 | \\{s} _IO_stdin_used |
| ... | ... | @@ -963,7 +958,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 963 | 958 | |
| 964 | 959 | try stubs_asm.appendSlice(".data\n"); |
| 965 | 960 | |
| 966 | const obj_inclusions_len = try inc_reader.readInt(u16, .little); | |
| 961 | const obj_inclusions_len = try inc_br.takeInt(u16, .little); | |
| 967 | 962 | |
| 968 | 963 | var sizes = try arena.alloc(u16, metadata.all_versions.len); |
| 969 | 964 | |
| ... | ... | @@ -973,18 +968,14 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 973 | 968 | versions_len = undefined; |
| 974 | 969 | while (sym_i < obj_inclusions_len) : (sym_i += 1) { |
| 975 | 970 | 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); | |
| 980 | 972 | versions_buffer = undefined; |
| 981 | 973 | versions_len = 0; |
| 982 | ||
| 983 | break :n sym_name_buf.items; | |
| 974 | break :n opt_symbol_name.?; | |
| 984 | 975 | }; |
| 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(); | |
| 988 | 979 | |
| 989 | 980 | const is_terminal = (lib_index & (1 << 7)) != 0; |
| 990 | 981 | if (is_terminal) { |
| ... | ... | @@ -998,7 +989,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 998 | 989 | ((targets & (@as(u64, 1) << @as(u6, @intCast(target_targ_index)))) != 0); |
| 999 | 990 | |
| 1000 | 991 | while (true) { |
| 1001 | const byte = try inc_reader.readByte(); | |
| 992 | const byte = try inc_br.takeByte(); | |
| 1002 | 993 | const last = (byte & 0b1000_0000) != 0; |
| 1003 | 994 | const ver_i = @as(u7, @truncate(byte)); |
| 1004 | 995 | 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 |
| 1055 | 1046 | "{s}_{d}_{d}", |
| 1056 | 1047 | .{ sym_name, ver.major, ver.minor }, |
| 1057 | 1048 | ); |
| 1058 | try stubs_asm.writer().print( | |
| 1049 | try stubs_asm.print( | |
| 1059 | 1050 | \\.balign {d} |
| 1060 | 1051 | \\.globl {s} |
| 1061 | 1052 | \\.type {s}, %object |
| ... | ... | @@ -1083,7 +1074,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 1083 | 1074 | "{s}_{d}_{d}_{d}", |
| 1084 | 1075 | .{ sym_name, ver.major, ver.minor, ver.patch }, |
| 1085 | 1076 | ); |
| 1086 | try stubs_asm.writer().print( | |
| 1077 | try stubs_asm.print( | |
| 1087 | 1078 | \\.balign {d} |
| 1088 | 1079 | \\.globl {s} |
| 1089 | 1080 | \\.type {s}, %object |
src/libs/mingw.zig+7-7| ... | ... | @@ -401,7 +401,7 @@ fn findDef( |
| 401 | 401 | }; |
| 402 | 402 | |
| 403 | 403 | var override_path: std.io.AllocatingWriter = undefined; |
| 404 | const override_path_writer = override_path.init(gpa); | |
| 404 | override_path.init(gpa); | |
| 405 | 405 | defer override_path.deinit(); |
| 406 | 406 | |
| 407 | 407 | const s = path.sep_str; |
| ... | ... | @@ -410,9 +410,9 @@ fn findDef( |
| 410 | 410 | // Try the archtecture-specific path first. |
| 411 | 411 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "{s}" ++ s ++ "{s}.def"; |
| 412 | 412 | 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 }); | |
| 414 | 414 | } 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 }); | |
| 416 | 416 | } |
| 417 | 417 | if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| { |
| 418 | 418 | return override_path.toOwnedSlice(); |
| ... | ... | @@ -427,9 +427,9 @@ fn findDef( |
| 427 | 427 | override_path.clearRetainingCapacity(); |
| 428 | 428 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def"; |
| 429 | 429 | 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 }); | |
| 431 | 431 | } else { |
| 432 | try override_path_writer.print(fmt_path, .{lib_name}); | |
| 432 | try override_path.buffered_writer.print(fmt_path, .{lib_name}); | |
| 433 | 433 | } |
| 434 | 434 | if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| { |
| 435 | 435 | return override_path.toOwnedSlice(); |
| ... | ... | @@ -444,9 +444,9 @@ fn findDef( |
| 444 | 444 | override_path.clearRetainingCapacity(); |
| 445 | 445 | const fmt_path = "libc" ++ s ++ "mingw" ++ s ++ "lib-common" ++ s ++ "{s}.def.in"; |
| 446 | 446 | 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 }); | |
| 448 | 448 | } else { |
| 449 | try override_path_writer.print(fmt_path, .{lib_name}); | |
| 449 | try override_path.buffered_writer.print(fmt_path, .{lib_name}); | |
| 450 | 450 | } |
| 451 | 451 | if (std.fs.cwd().access(override_path.getWritten(), .{})) |_| { |
| 452 | 452 | 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 |
| 115 | 115 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(comp.gpa); |
| 116 | 116 | defer c_source_files.deinit(); |
| 117 | 117 | |
| 118 | var override_path = std.ArrayList(u8).init(comp.gpa); | |
| 118 | var override_path: std.io.AllocatingWriter = undefined; | |
| 119 | override_path.init(comp.gpa); | |
| 119 | 120 | defer override_path.deinit(); |
| 120 | 121 | |
| 121 | 122 | const s = path.sep_str; |
| ... | ... | @@ -139,26 +140,23 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 139 | 140 | } |
| 140 | 141 | if (!is_arch_specific) { |
| 141 | 142 | // 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", .{ | |
| 144 | 145 | dirname, arch_name, noextbasename, |
| 145 | 146 | }); |
| 146 | if (source_table.contains(override_path.items)) | |
| 147 | continue; | |
| 147 | if (source_table.contains(override_path.getWritten())) continue; | |
| 148 | 148 | |
| 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", .{ | |
| 151 | 151 | dirname, arch_name, noextbasename, |
| 152 | 152 | }); |
| 153 | if (source_table.contains(override_path.items)) | |
| 154 | continue; | |
| 153 | if (source_table.contains(override_path.getWritten())) continue; | |
| 155 | 154 | |
| 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", .{ | |
| 158 | 157 | dirname, arch_name, noextbasename, |
| 159 | 158 | }); |
| 160 | if (source_table.contains(override_path.items)) | |
| 161 | continue; | |
| 159 | if (source_table.contains(override_path.getWritten())) continue; | |
| 162 | 160 | } |
| 163 | 161 | |
| 164 | 162 | var args = std.ArrayList([]const u8).init(arena); |
src/link.zig+25-25| ... | ... | @@ -323,7 +323,7 @@ pub const Diags = struct { |
| 323 | 323 | const main_msg = try m; |
| 324 | 324 | errdefer gpa.free(main_msg); |
| 325 | 325 | 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}); | |
| 327 | 327 | errdefer gpa.free(note); |
| 328 | 328 | const notes = try gpa.create([1]Msg); |
| 329 | 329 | errdefer gpa.destroy(notes); |
| ... | ... | @@ -838,7 +838,7 @@ pub const File = struct { |
| 838 | 838 | const cached_pp_file_path = the_key.status.success.object_path; |
| 839 | 839 | cached_pp_file_path.root_dir.handle.copyFile(cached_pp_file_path.sub_path, emit.root_dir.handle, emit.sub_path, .{}) catch |err| { |
| 840 | 840 | 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}", .{ | |
| 842 | 842 | @as(Path, cached_pp_file_path), @as(Path, emit), @errorName(err), |
| 843 | 843 | }); |
| 844 | 844 | }; |
| ... | ... | @@ -1351,7 +1351,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1351 | 1351 | .search_strategy = .paths_first, |
| 1352 | 1352 | }) catch |archive_err| switch (archive_err) { |
| 1353 | 1353 | 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) }), | |
| 1355 | 1355 | }; |
| 1356 | 1356 | }, |
| 1357 | 1357 | error.LinkFailure => return, // error reported via diags |
| ... | ... | @@ -1874,7 +1874,7 @@ pub fn resolveInputs( |
| 1874 | 1874 | )) |lib_result| { |
| 1875 | 1875 | switch (lib_result) { |
| 1876 | 1876 | .ok => {}, |
| 1877 | .no_match => fatal("{}: file not found", .{pq.path}), | |
| 1877 | .no_match => fatal("{f}: file not found", .{pq.path}), | |
| 1878 | 1878 | } |
| 1879 | 1879 | } |
| 1880 | 1880 | continue; |
| ... | ... | @@ -1928,10 +1928,10 @@ fn resolveLibInput( |
| 1928 | 1928 | .root_dir = lib_directory, |
| 1929 | 1929 | .sub_path = try std.fmt.allocPrint(arena, "lib{s}.tbd", .{lib_name}), |
| 1930 | 1930 | }; |
| 1931 | try checked_paths.print(gpa, "\n {}", .{test_path}); | |
| 1931 | try checked_paths.print(gpa, "\n {f}", .{test_path}); | |
| 1932 | 1932 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { |
| 1933 | 1933 | 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) }), | |
| 1935 | 1935 | }; |
| 1936 | 1936 | errdefer file.close(); |
| 1937 | 1937 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); |
| ... | ... | @@ -1947,7 +1947,7 @@ fn resolveLibInput( |
| 1947 | 1947 | }, |
| 1948 | 1948 | }), |
| 1949 | 1949 | }; |
| 1950 | try checked_paths.print(gpa, "\n {}", .{test_path}); | |
| 1950 | try checked_paths.print(gpa, "\n {f}", .{test_path}); | |
| 1951 | 1951 | switch (try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, .{ |
| 1952 | 1952 | .path = test_path, |
| 1953 | 1953 | .query = name_query.query, |
| ... | ... | @@ -1964,10 +1964,10 @@ fn resolveLibInput( |
| 1964 | 1964 | .root_dir = lib_directory, |
| 1965 | 1965 | .sub_path = try std.fmt.allocPrint(arena, "lib{s}.so", .{lib_name}), |
| 1966 | 1966 | }; |
| 1967 | try checked_paths.print(gpa, "\n {}", .{test_path}); | |
| 1967 | try checked_paths.print(gpa, "\n {f}", .{test_path}); | |
| 1968 | 1968 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { |
| 1969 | 1969 | 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}", .{ | |
| 1971 | 1971 | test_path, @errorName(e), |
| 1972 | 1972 | }), |
| 1973 | 1973 | }; |
| ... | ... | @@ -1982,10 +1982,10 @@ fn resolveLibInput( |
| 1982 | 1982 | .root_dir = lib_directory, |
| 1983 | 1983 | .sub_path = try std.fmt.allocPrint(arena, "lib{s}.a", .{lib_name}), |
| 1984 | 1984 | }; |
| 1985 | try checked_paths.print(gpa, "\n {}", .{test_path}); | |
| 1985 | try checked_paths.print(gpa, "\n {f}", .{test_path}); | |
| 1986 | 1986 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { |
| 1987 | 1987 | 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) }), | |
| 1989 | 1989 | }; |
| 1990 | 1990 | errdefer file.close(); |
| 1991 | 1991 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, name_query.query); |
| ... | ... | @@ -2037,7 +2037,7 @@ fn resolvePathInput( |
| 2037 | 2037 | .shared_library => return try resolvePathInputLib(gpa, arena, unresolved_inputs, resolved_inputs, ld_script_bytes, target, pq, .dynamic, color), |
| 2038 | 2038 | .object => { |
| 2039 | 2039 | 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) }); | |
| 2041 | 2041 | errdefer file.close(); |
| 2042 | 2042 | try resolved_inputs.append(gpa, .{ .object = .{ |
| 2043 | 2043 | .path = pq.path, |
| ... | ... | @@ -2049,7 +2049,7 @@ fn resolvePathInput( |
| 2049 | 2049 | }, |
| 2050 | 2050 | .res => { |
| 2051 | 2051 | 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) }); | |
| 2053 | 2053 | errdefer file.close(); |
| 2054 | 2054 | try resolved_inputs.append(gpa, .{ .res = .{ |
| 2055 | 2055 | .path = pq.path, |
| ... | ... | @@ -2057,7 +2057,7 @@ fn resolvePathInput( |
| 2057 | 2057 | } }); |
| 2058 | 2058 | return null; |
| 2059 | 2059 | }, |
| 2060 | else => fatal("{}: unrecognized file extension", .{pq.path}), | |
| 2060 | else => fatal("{f}: unrecognized file extension", .{pq.path}), | |
| 2061 | 2061 | } |
| 2062 | 2062 | } |
| 2063 | 2063 | |
| ... | ... | @@ -2086,13 +2086,13 @@ fn resolvePathInputLib( |
| 2086 | 2086 | }) { |
| 2087 | 2087 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { |
| 2088 | 2088 | 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}", .{ | |
| 2090 | 2090 | @tagName(link_mode), test_path, @errorName(e), |
| 2091 | 2091 | }), |
| 2092 | 2092 | }; |
| 2093 | 2093 | errdefer file.close(); |
| 2094 | 2094 | 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}", .{ | |
| 2096 | 2096 | test_path, @errorName(err), |
| 2097 | 2097 | }); |
| 2098 | 2098 | const buf = ld_script_bytes.items[0..n]; |
| ... | ... | @@ -2101,14 +2101,14 @@ fn resolvePathInputLib( |
| 2101 | 2101 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); |
| 2102 | 2102 | } |
| 2103 | 2103 | 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) }); | |
| 2105 | 2105 | 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}); | |
| 2107 | 2107 | try ld_script_bytes.resize(gpa, size); |
| 2108 | 2108 | const buf2 = ld_script_bytes.items[n..]; |
| 2109 | 2109 | 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}); | |
| 2112 | 2112 | var diags = Diags.init(gpa); |
| 2113 | 2113 | defer diags.deinit(); |
| 2114 | 2114 | const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items); |
| ... | ... | @@ -2128,7 +2128,7 @@ fn resolvePathInputLib( |
| 2128 | 2128 | } |
| 2129 | 2129 | |
| 2130 | 2130 | 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) }); | |
| 2132 | 2132 | defer ld_script.deinit(gpa); |
| 2133 | 2133 | |
| 2134 | 2134 | try unresolved_inputs.ensureUnusedCapacity(gpa, ld_script.args.len); |
| ... | ... | @@ -2159,7 +2159,7 @@ fn resolvePathInputLib( |
| 2159 | 2159 | |
| 2160 | 2160 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { |
| 2161 | 2161 | 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}", .{ | |
| 2163 | 2163 | @tagName(link_mode), test_path, @errorName(e), |
| 2164 | 2164 | }), |
| 2165 | 2165 | }; |
| ... | ... | @@ -2192,19 +2192,19 @@ pub fn openDso(path: Path, needed: bool, weak: bool, reexport: bool) !Input.Dso |
| 2192 | 2192 | |
| 2193 | 2193 | pub fn openObjectInput(diags: *Diags, path: Path) error{LinkFailure}!Input { |
| 2194 | 2194 | 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) }); | |
| 2196 | 2196 | } }; |
| 2197 | 2197 | } |
| 2198 | 2198 | |
| 2199 | 2199 | pub fn openArchiveInput(diags: *Diags, path: Path, must_link: bool, hidden: bool) error{LinkFailure}!Input { |
| 2200 | 2200 | 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) }); | |
| 2202 | 2202 | } }; |
| 2203 | 2203 | } |
| 2204 | 2204 | |
| 2205 | 2205 | pub fn openDsoInput(diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{LinkFailure}!Input { |
| 2206 | 2206 | 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) }); | |
| 2208 | 2208 | } }; |
| 2209 | 2209 | } |
| 2210 | 2210 |
src/link/Coff.zig+25-32| ... | ... | @@ -1213,7 +1213,7 @@ fn updateLazySymbolAtom( |
| 1213 | 1213 | var code_buffer: std.ArrayListUnmanaged(u8) = .empty; |
| 1214 | 1214 | defer code_buffer.deinit(gpa); |
| 1215 | 1215 | |
| 1216 | const name = try allocPrint(gpa, "__lazy_{s}_{}", .{ | |
| 1216 | const name = try allocPrint(gpa, "__lazy_{s}_{f}", .{ | |
| 1217 | 1217 | @tagName(sym.kind), |
| 1218 | 1218 | Type.fromInterned(sym.ty).fmt(pt), |
| 1219 | 1219 | }); |
| ... | ... | @@ -1333,7 +1333,7 @@ fn updateNavCode( |
| 1333 | 1333 | const ip = &zcu.intern_pool; |
| 1334 | 1334 | const nav = ip.getNav(nav_index); |
| 1335 | 1335 | |
| 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 }); | |
| 1337 | 1337 | |
| 1338 | 1338 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 1339 | 1339 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| ... | ... | @@ -1361,7 +1361,7 @@ fn updateNavCode( |
| 1361 | 1361 | error.OutOfMemory => return error.OutOfMemory, |
| 1362 | 1362 | else => |e| return coff.base.cgFail(nav_index, "failed to grow atom: {s}", .{@errorName(e)}), |
| 1363 | 1363 | }; |
| 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 }); | |
| 1365 | 1365 | log.debug(" (required alignment 0x{x}", .{required_alignment}); |
| 1366 | 1366 | |
| 1367 | 1367 | if (vaddr != sym.value) { |
| ... | ... | @@ -1389,7 +1389,7 @@ fn updateNavCode( |
| 1389 | 1389 | else => |e| return coff.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(e)}), |
| 1390 | 1390 | }; |
| 1391 | 1391 | 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 }); | |
| 1393 | 1393 | coff.getAtomPtr(atom_index).size = code_len; |
| 1394 | 1394 | sym.value = vaddr; |
| 1395 | 1395 | |
| ... | ... | @@ -1454,7 +1454,7 @@ pub fn updateExports( |
| 1454 | 1454 | |
| 1455 | 1455 | for (export_indices) |export_idx| { |
| 1456 | 1456 | 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)}); | |
| 1458 | 1458 | |
| 1459 | 1459 | if (exp.opts.section.toSlice(&zcu.intern_pool)) |section_name| { |
| 1460 | 1460 | if (!mem.eql(u8, section_name, ".text")) { |
| ... | ... | @@ -1530,7 +1530,7 @@ pub fn deleteExport( |
| 1530 | 1530 | const gpa = coff.base.comp.gpa; |
| 1531 | 1531 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null }; |
| 1532 | 1532 | 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)}); | |
| 1534 | 1534 | assert(sym.storage_class == .EXTERNAL and sym.section_number != .UNDEFINED); |
| 1535 | 1535 | sym.* = .{ |
| 1536 | 1536 | .name = [_]u8{0} ** 8, |
| ... | ... | @@ -1748,7 +1748,7 @@ pub fn getNavVAddr( |
| 1748 | 1748 | const zcu = pt.zcu; |
| 1749 | 1749 | const ip = &zcu.intern_pool; |
| 1750 | 1750 | 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 }); | |
| 1752 | 1752 | const sym_index = if (nav.getExtern(ip)) |e| |
| 1753 | 1753 | try coff.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip)) |
| 1754 | 1754 | else |
| ... | ... | @@ -2175,15 +2175,14 @@ fn writeDataDirectoriesHeaders(coff: *Coff) !void { |
| 2175 | 2175 | fn writeHeader(coff: *Coff) !void { |
| 2176 | 2176 | const target = &coff.base.comp.root_mod.resolved_target.result; |
| 2177 | 2177 | 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); | |
| 2181 | 2181 | |
| 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); | |
| 2185 | 2184 | |
| 2186 | writer.writeAll("PE\x00\x00") catch unreachable; | |
| 2185 | bw.writeAll("PE\x00\x00") catch unreachable; | |
| 2187 | 2186 | var flags = coff_util.CoffHeaderFlags{ |
| 2188 | 2187 | .EXECUTABLE_IMAGE = 1, |
| 2189 | 2188 | .DEBUG_STRIPPED = 1, // TODO |
| ... | ... | @@ -2208,7 +2207,7 @@ fn writeHeader(coff: *Coff) !void { |
| 2208 | 2207 | .flags = flags, |
| 2209 | 2208 | }; |
| 2210 | 2209 | |
| 2211 | writer.writeAll(mem.asBytes(&coff_header)) catch unreachable; | |
| 2210 | bw.writeAll(mem.asBytes(&coff_header)) catch unreachable; | |
| 2212 | 2211 | |
| 2213 | 2212 | const dll_flags: coff_util.DllFlags = .{ |
| 2214 | 2213 | .HIGH_ENTROPY_VA = 1, // TODO do we want to permit non-PIE builds at all? |
| ... | ... | @@ -2271,7 +2270,7 @@ fn writeHeader(coff: *Coff) !void { |
| 2271 | 2270 | .loader_flags = 0, |
| 2272 | 2271 | .number_of_rva_and_sizes = @intCast(coff.data_directories.len), |
| 2273 | 2272 | }; |
| 2274 | writer.writeAll(mem.asBytes(&opt_header)) catch unreachable; | |
| 2273 | bw.writeAll(mem.asBytes(&opt_header)) catch unreachable; | |
| 2275 | 2274 | }, |
| 2276 | 2275 | .p64 => { |
| 2277 | 2276 | var opt_header = coff_util.OptionalHeaderPE64{ |
| ... | ... | @@ -2305,11 +2304,12 @@ fn writeHeader(coff: *Coff) !void { |
| 2305 | 2304 | .loader_flags = 0, |
| 2306 | 2305 | .number_of_rva_and_sizes = @intCast(coff.data_directories.len), |
| 2307 | 2306 | }; |
| 2308 | writer.writeAll(mem.asBytes(&opt_header)) catch unreachable; | |
| 2307 | bw.writeAll(mem.asBytes(&opt_header)) catch unreachable; | |
| 2309 | 2308 | }, |
| 2310 | 2309 | } |
| 2311 | 2310 | |
| 2312 | try coff.pwriteAll(buffer.items, 0); | |
| 2311 | assert(bw.end == bw.buffer.len); | |
| 2312 | try coff.pwriteAll(bw.buffer, 0); | |
| 2313 | 2313 | } |
| 2314 | 2314 | |
| 2315 | 2315 | pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| ... | ... | @@ -2605,7 +2605,7 @@ fn logSymtab(coff: *Coff) void { |
| 2605 | 2605 | } |
| 2606 | 2606 | |
| 2607 | 2607 | log.debug("GOT entries:", .{}); |
| 2608 | log.debug("{}", .{coff.got_table}); | |
| 2608 | log.debug("{f}", .{coff.got_table}); | |
| 2609 | 2609 | } |
| 2610 | 2610 | |
| 2611 | 2611 | fn logSections(coff: *Coff) void { |
| ... | ... | @@ -2625,7 +2625,7 @@ fn logImportTables(coff: *const Coff) void { |
| 2625 | 2625 | log.debug("import tables:", .{}); |
| 2626 | 2626 | for (coff.import_tables.keys(), 0..) |off, i| { |
| 2627 | 2627 | const itable = coff.import_tables.values()[i]; |
| 2628 | log.debug("{}", .{itable.fmtDebug(.{ | |
| 2628 | log.debug("{f}", .{itable.fmtDebug(.{ | |
| 2629 | 2629 | .coff = coff, |
| 2630 | 2630 | .index = i, |
| 2631 | 2631 | .name_off = off, |
| ... | ... | @@ -3066,27 +3066,20 @@ const ImportTable = struct { |
| 3066 | 3066 | ctx: Context, |
| 3067 | 3067 | }; |
| 3068 | 3068 | |
| 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 { | |
| 3070 | 3070 | _ = itab; |
| 3071 | _ = bw; | |
| 3071 | 3072 | _ = unused_format_string; |
| 3072 | _ = options; | |
| 3073 | _ = writer; | |
| 3074 | 3073 | @compileError("do not format ImportTable directly; use itab.fmtDebug()"); |
| 3075 | 3074 | } |
| 3076 | 3075 | |
| 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 { | |
| 3084 | 3077 | comptime assert(unused_format_string.len == 0); |
| 3085 | 3078 | const lib_name = fmt_ctx.ctx.coff.temp_strtab.getAssumeExists(fmt_ctx.ctx.name_off); |
| 3086 | 3079 | 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 }); | |
| 3088 | 3081 | 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}", .{ | |
| 3090 | 3083 | i, |
| 3091 | 3084 | fmt_ctx.itab.getImportAddress(entry, fmt_ctx.ctx), |
| 3092 | 3085 | fmt_ctx.ctx.coff.getSymbolName(entry), |
src/link/Dwarf.zig+797-697| ... | ... | @@ -132,7 +132,7 @@ const DebugInfo = struct { |
| 132 | 132 | return AbbrevCode.decl_bytes + dwarf.sectionOffsetBytes(); |
| 133 | 133 | } |
| 134 | 134 | |
| 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 { | |
| 136 | 136 | const dwarf: *Dwarf = @fieldParentPtr("debug_info", debug_info); |
| 137 | 137 | const unit_ptr = debug_info.section.getUnit(unit); |
| 138 | 138 | const entry_ptr = unit_ptr.getEntry(entry); |
| ... | ... | @@ -142,8 +142,9 @@ const DebugInfo = struct { |
| 142 | 142 | &abbrev_code_buf, |
| 143 | 143 | debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off, |
| 144 | 144 | ) != 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); | |
| 147 | 148 | } |
| 148 | 149 | |
| 149 | 150 | const trailer_bytes = 1 + 1; |
| ... | ... | @@ -226,7 +227,7 @@ const StringSection = struct { |
| 226 | 227 | str_sec.section.deinit(gpa); |
| 227 | 228 | } |
| 228 | 229 | |
| 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 { | |
| 230 | 231 | const gop = try str_sec.map.getOrPutAdapted(dwarf.gpa, str, Adapter{ .str_sec = str_sec }); |
| 231 | 232 | const entry: Entry.Index = @enumFromInt(gop.index); |
| 232 | 233 | if (!gop.found_existing) { |
| ... | ... | @@ -368,7 +369,7 @@ pub const Section = struct { |
| 368 | 369 | return &sec.units.items[@intFromEnum(unit)]; |
| 369 | 370 | } |
| 370 | 371 | |
| 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 { | |
| 372 | 373 | const unit_ptr = sec.getUnit(unit); |
| 373 | 374 | const entry_ptr = unit_ptr.getEntry(entry); |
| 374 | 375 | if (len > 0) { |
| ... | ... | @@ -389,13 +390,13 @@ pub const Section = struct { |
| 389 | 390 | assert(entry_ptr.len == len); |
| 390 | 391 | } |
| 391 | 392 | |
| 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 { | |
| 393 | 394 | try sec.resizeEntry(unit, entry, dwarf, @intCast(contents.len)); |
| 394 | 395 | const unit_ptr = sec.getUnit(unit); |
| 395 | 396 | try unit_ptr.getEntry(entry).replace(unit_ptr, sec, dwarf, contents); |
| 396 | 397 | } |
| 397 | 398 | |
| 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 { | |
| 399 | 400 | const unit_ptr = sec.getUnit(unit); |
| 400 | 401 | const entry_ptr = unit_ptr.getEntry(entry); |
| 401 | 402 | if (entry_ptr.len > 0) { |
| ... | ... | @@ -648,35 +649,36 @@ const Unit = struct { |
| 648 | 649 | assert(len >= unit.trailer_len); |
| 649 | 650 | if (sec == &dwarf.debug_line.section) { |
| 650 | 651 | 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; | |
| 655 | 656 | var op_len_bytes: u5 = 1; |
| 656 | 657 | 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, | |
| 658 | 659 | .eq => { |
| 659 | 660 | // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte |
| 660 | 661 | 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); | |
| 663 | 664 | break; |
| 664 | 665 | }, |
| 665 | 666 | .gt => op_len_bytes += 1, |
| 666 | 667 | }; |
| 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); | |
| 671 | 672 | } |
| 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); | |
| 674 | 676 | const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: { |
| 675 | 677 | assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1); |
| 676 | trailer.appendAssumeCapacity(@intFromEnum(AbbrevCode.null)); | |
| 678 | trailer_bw.writeByte(@intFromEnum(AbbrevCode.null)) catch unreachable; | |
| 677 | 679 | break :fill @intFromEnum(AbbrevCode.null); |
| 678 | 680 | } 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; | |
| 680 | 682 | break :fill 0; |
| 681 | 683 | } else if (sec == &dwarf.debug_frame.section) fill: { |
| 682 | 684 | switch (dwarf.debug_frame.header.format) { |
| ... | ... | @@ -684,49 +686,49 @@ const Unit = struct { |
| 684 | 686 | .debug_frame, .eh_frame => |format| { |
| 685 | 687 | const unit_len = len - dwarf.unitLengthBytes(); |
| 686 | 688 | 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, | |
| 688 | 690 | .@"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; | |
| 691 | 693 | }, |
| 692 | 694 | } |
| 693 | 695 | switch (format) { |
| 694 | 696 | .none => unreachable, |
| 695 | 697 | .debug_frame => { |
| 696 | 698 | 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, | |
| 699 | 701 | } |
| 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; | |
| 704 | 706 | }, |
| 705 | 707 | .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; | |
| 709 | 711 | }, |
| 710 | 712 | } |
| 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; | |
| 714 | 716 | }, |
| 715 | 717 | } |
| 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; | |
| 717 | 719 | break :fill DW.CFA.nop; |
| 718 | 720 | } else if (sec == &dwarf.debug_info.section) fill: { |
| 719 | 721 | assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1); |
| 720 | trailer.appendNTimesAssumeCapacity(@intFromEnum(AbbrevCode.null), 2); | |
| 722 | trailer_bw.splatByteAll(@intFromEnum(AbbrevCode.null), 2) catch unreachable; | |
| 721 | 723 | break :fill @intFromEnum(AbbrevCode.null); |
| 722 | 724 | } 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; | |
| 724 | 726 | break :fill DW.RLE.end_of_list; |
| 725 | 727 | } 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); | |
| 730 | 732 | } |
| 731 | 733 | |
| 732 | 734 | fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void { |
| ... | ... | @@ -805,7 +807,7 @@ const Entry = struct { |
| 805 | 807 | } |
| 806 | 808 | }; |
| 807 | 809 | |
| 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 { | |
| 809 | 811 | assert(entry.len > 0); |
| 810 | 812 | const start = entry.off + entry.len; |
| 811 | 813 | if (sec == &dwarf.debug_frame.section) { |
| ... | ... | @@ -833,55 +835,58 @@ const Entry = struct { |
| 833 | 835 | 1 + uleb128Bytes(std.math.maxInt(u32)) + 1, |
| 834 | 836 | ) |
| 835 | 837 | ]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); | |
| 838 | 840 | if (sec == &dwarf.debug_info.section) switch (len) { |
| 839 | 841 | 0 => {}, |
| 840 | 1 => uleb128(writer, try dwarf.refAbbrevCode(.pad_1)) catch unreachable, | |
| 842 | 1 => bw.writeLeb128(try dwarf.refAbbrevCode(.pad_1)) catch unreachable, | |
| 841 | 843 | 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; | |
| 844 | 846 | var block_len_bytes: u5 = 1; |
| 845 | 847 | 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, | |
| 847 | 849 | .eq => { |
| 848 | 850 | // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte |
| 849 | 851 | 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); | |
| 852 | 854 | break; |
| 853 | 855 | }, |
| 854 | 856 | .gt => block_len_bytes += 1, |
| 855 | 857 | }; |
| 856 | assert(fbs.pos == abbrev_code_bytes + block_len_bytes); | |
| 858 | assert(bw.end == abbrev_code_bytes + block_len_bytes); | |
| 857 | 859 | }, |
| 858 | 860 | } else if (sec == &dwarf.debug_line.section) switch (len) { |
| 859 | 861 | 0 => {}, |
| 860 | 1 => writer.writeByte(DW.LNS.const_add_pc) catch unreachable, | |
| 862 | 1 => bw.writeByte(DW.LNS.const_add_pc) catch unreachable, | |
| 861 | 863 | 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; | |
| 864 | 866 | var op_len_bytes: u5 = 1; |
| 865 | 867 | 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, | |
| 867 | 869 | .eq => { |
| 868 | 870 | // no length will ever work, so undercount and futz with the leb encoding to make up the missing byte |
| 869 | 871 | 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); | |
| 872 | 877 | break; |
| 873 | 878 | }, |
| 874 | 879 | .gt => op_len_bytes += 1, |
| 875 | 880 | }; |
| 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; | |
| 878 | 883 | }, |
| 879 | 884 | } 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); | |
| 882 | 887 | } |
| 883 | 888 | |
| 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 { | |
| 885 | 890 | assert(len > 0); |
| 886 | 891 | assert(sec.alignment.check(len)); |
| 887 | 892 | if (entry_ptr.len == len) return; |
| ... | ... | @@ -973,7 +978,7 @@ const Entry = struct { |
| 973 | 978 | else |
| 974 | 979 | .main; |
| 975 | 980 | 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}))", .{ | |
| 977 | 982 | Type.fromInterned(ty).fmt(.{ .tid = .main, .zcu = zcu }), |
| 978 | 983 | @intFromEnum(ty), |
| 979 | 984 | }); |
| ... | ... | @@ -981,7 +986,7 @@ const Entry = struct { |
| 981 | 986 | for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| { |
| 982 | 987 | const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod.?) catch unreachable; |
| 983 | 988 | 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) }); | |
| 985 | 990 | } |
| 986 | 991 | } |
| 987 | 992 | @panic("missing dwarf relocation target"); |
| ... | ... | @@ -1133,150 +1138,149 @@ pub const Loc = union(enum) { |
| 1133 | 1138 | }; |
| 1134 | 1139 | } |
| 1135 | 1140 | |
| 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 { | |
| 1137 | 1142 | if (std.math.cast(u5, reg)) |small_reg| { |
| 1138 | try writer.writeByte(op0 + small_reg); | |
| 1143 | try bw.writeByte(op0 + small_reg); | |
| 1139 | 1144 | } else { |
| 1140 | try writer.writeByte(opx); | |
| 1141 | try uleb128(writer, reg); | |
| 1145 | try bw.writeByte(opx); | |
| 1146 | try bw.writeLeb128(reg); | |
| 1142 | 1147 | } |
| 1143 | 1148 | } |
| 1144 | 1149 | |
| 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 { | |
| 1147 | 1151 | switch (loc) { |
| 1148 | 1152 | .empty => {}, |
| 1149 | 1153 | .addr_reloc => |sym_index| { |
| 1150 | try writer.writeByte(DW.OP.addr); | |
| 1154 | try bw.writeByte(DW.OP.addr); | |
| 1151 | 1155 | try adapter.addrSym(sym_index); |
| 1152 | 1156 | }, |
| 1153 | 1157 | .deref => |addr| { |
| 1154 | 1158 | try addr.write(adapter); |
| 1155 | try writer.writeByte(DW.OP.deref); | |
| 1159 | try bw.writeByte(DW.OP.deref); | |
| 1156 | 1160 | }, |
| 1157 | 1161 | .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); | |
| 1159 | 1163 | } else if (std.math.cast(u8, constu)) |const1u| { |
| 1160 | try writer.writeAll(&.{ DW.OP.const1u, const1u }); | |
| 1164 | try bw.writeAll(&.{ DW.OP.const1u, const1u }); | |
| 1161 | 1165 | } 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()); | |
| 1164 | 1168 | } 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); | |
| 1167 | 1171 | } 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()); | |
| 1170 | 1174 | } 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); | |
| 1173 | 1177 | } 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()); | |
| 1176 | 1180 | }, |
| 1177 | 1181 | .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) }); | |
| 1179 | 1183 | } 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()); | |
| 1182 | 1186 | } 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); | |
| 1185 | 1189 | } 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()); | |
| 1188 | 1192 | } 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); | |
| 1191 | 1195 | } 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()); | |
| 1194 | 1198 | }, |
| 1195 | 1199 | .plus => |plus| done: { |
| 1196 | 1200 | if (plus[0].getConst(u0)) |_| { |
| 1197 | try plus[1].write(adapter); | |
| 1201 | try plus[1].write(bw, adapter); | |
| 1198 | 1202 | break :done; |
| 1199 | 1203 | } |
| 1200 | 1204 | if (plus[1].getConst(u0)) |_| { |
| 1201 | try plus[0].write(adapter); | |
| 1205 | try plus[0].write(bw, adapter); | |
| 1202 | 1206 | break :done; |
| 1203 | 1207 | } |
| 1204 | 1208 | if (plus[0].getBaseReg()) |breg| { |
| 1205 | 1209 | 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); | |
| 1208 | 1212 | break :done; |
| 1209 | 1213 | } |
| 1210 | 1214 | } |
| 1211 | 1215 | if (plus[1].getBaseReg()) |breg| { |
| 1212 | 1216 | 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); | |
| 1215 | 1219 | break :done; |
| 1216 | 1220 | } |
| 1217 | 1221 | } |
| 1218 | 1222 | 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); | |
| 1222 | 1226 | break :done; |
| 1223 | 1227 | } |
| 1224 | 1228 | 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); | |
| 1228 | 1232 | break :done; |
| 1229 | 1233 | } |
| 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); | |
| 1233 | 1237 | }, |
| 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), | |
| 1235 | 1239 | .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); | |
| 1238 | 1242 | }, |
| 1239 | .push_object_address => try writer.writeByte(DW.OP.push_object_address), | |
| 1243 | .push_object_address => try bw.writeByte(DW.OP.push_object_address), | |
| 1240 | 1244 | .call => |call| { |
| 1241 | 1245 | for (call.args) |arg| try arg.write(adapter); |
| 1242 | try writer.writeByte(DW.OP.call_ref); | |
| 1246 | try bw.writeByte(DW.OP.call_ref); | |
| 1243 | 1247 | try adapter.infoEntry(call.unit, call.entry); |
| 1244 | 1248 | }, |
| 1245 | 1249 | .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); | |
| 1248 | 1252 | }, |
| 1249 | 1253 | .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); | |
| 1253 | 1257 | }, |
| 1254 | 1258 | .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); | |
| 1257 | 1261 | }, |
| 1258 | 1262 | .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); | |
| 1262 | 1266 | }, |
| 1263 | 1267 | .wasm_ext => |wasm_ext| { |
| 1264 | try writer.writeByte(DW.OP.WASM_location); | |
| 1268 | try bw.writeByte(DW.OP.WASM_location); | |
| 1265 | 1269 | switch (wasm_ext) { |
| 1266 | 1270 | .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); | |
| 1269 | 1273 | }, |
| 1270 | 1274 | .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); | |
| 1273 | 1277 | } 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()); | |
| 1276 | 1280 | }, |
| 1277 | 1281 | .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); | |
| 1280 | 1284 | }, |
| 1281 | 1285 | } |
| 1282 | 1286 | }, |
| ... | ... | @@ -1308,22 +1312,22 @@ pub const Cfa = union(enum) { |
| 1308 | 1312 | const RegOff = struct { reg: u32, off: i64 }; |
| 1309 | 1313 | const RegExpr = struct { reg: u32, expr: Loc }; |
| 1310 | 1314 | |
| 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; | |
| 1313 | 1317 | switch (cfa) { |
| 1314 | .nop => try writer.writeByte(DW.CFA.nop), | |
| 1318 | .nop => try bw.writeByte(DW.CFA.nop), | |
| 1315 | 1319 | .advance_loc => |loc| { |
| 1316 | 1320 | const delta = @divExact(loc - wip_nav.cfi.loc, wip_nav.dwarf.debug_frame.header.code_alignment_factor); |
| 1317 | 1321 | 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) | |
| 1319 | 1323 | 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 }) | |
| 1321 | 1325 | 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); | |
| 1324 | 1328 | } 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); | |
| 1327 | 1331 | } |
| 1328 | 1332 | wip_nav.cfi.loc = loc; |
| 1329 | 1333 | }, |
| ... | ... | @@ -1335,41 +1339,41 @@ pub const Cfa = union(enum) { |
| 1335 | 1339 | }, wip_nav.dwarf.debug_frame.header.data_alignment_factor); |
| 1336 | 1340 | if (std.math.cast(u63, factored_off)) |unsigned_off| { |
| 1337 | 1341 | 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); | |
| 1339 | 1343 | } 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); | |
| 1342 | 1346 | } |
| 1343 | try uleb128(writer, unsigned_off); | |
| 1347 | try bw.writeLeb128(unsigned_off); | |
| 1344 | 1348 | } 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); | |
| 1348 | 1352 | } |
| 1349 | 1353 | }, |
| 1350 | 1354 | .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) | |
| 1352 | 1356 | 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); | |
| 1355 | 1359 | }, |
| 1356 | 1360 | .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); | |
| 1359 | 1363 | }, |
| 1360 | 1364 | .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); | |
| 1363 | 1367 | }, |
| 1364 | 1368 | .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); | |
| 1367 | 1371 | } 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]); | |
| 1370 | 1374 | }, |
| 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), | |
| 1373 | 1377 | .def_cfa, .def_cfa_register, .def_cfa_offset, .adjust_cfa_offset => { |
| 1374 | 1378 | const reg_off: RegOff = switch (cfa) { |
| 1375 | 1379 | else => unreachable, |
| ... | ... | @@ -1382,51 +1386,51 @@ pub const Cfa = union(enum) { |
| 1382 | 1386 | const unsigned_off = std.math.cast(u63, reg_off.off); |
| 1383 | 1387 | if (reg_off.off == wip_nav.cfi.cfa.off) { |
| 1384 | 1388 | 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); | |
| 1387 | 1391 | } |
| 1388 | 1392 | } else if (switch (wip_nav.dwarf.debug_frame.header.data_alignment_factor) { |
| 1389 | 1393 | 0 => unreachable, |
| 1390 | 1394 | 1 => unsigned_off != null, |
| 1391 | 1395 | else => |data_alignment_factor| @rem(reg_off.off, data_alignment_factor) != 0, |
| 1392 | 1396 | }) { |
| 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.?); | |
| 1396 | 1400 | } 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)); | |
| 1400 | 1404 | } |
| 1401 | 1405 | wip_nav.cfi.cfa = reg_off; |
| 1402 | 1406 | }, |
| 1403 | 1407 | .def_cfa_expression => |expr| { |
| 1404 | try writer.writeByte(DW.CFA.def_cfa_expression); | |
| 1408 | try bw.writeByte(DW.CFA.def_cfa_expression); | |
| 1405 | 1409 | try wip_nav.frameExprLoc(expr); |
| 1406 | 1410 | }, |
| 1407 | 1411 | .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); | |
| 1410 | 1414 | try wip_nav.frameExprLoc(reg_expr.expr); |
| 1411 | 1415 | }, |
| 1412 | 1416 | .val_offset => |reg_off| { |
| 1413 | 1417 | const factored_off = @divExact(reg_off.off, wip_nav.dwarf.debug_frame.header.data_alignment_factor); |
| 1414 | 1418 | 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); | |
| 1418 | 1422 | } 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); | |
| 1422 | 1426 | } |
| 1423 | 1427 | }, |
| 1424 | 1428 | .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); | |
| 1427 | 1431 | try wip_nav.frameExprLoc(reg_expr.expr); |
| 1428 | 1432 | }, |
| 1429 | .escape => |bytes| try writer.writeAll(bytes), | |
| 1433 | .escape => |bytes| try bw.writeAll(bytes), | |
| 1430 | 1434 | } |
| 1431 | 1435 | } |
| 1432 | 1436 | }; |
| ... | ... | @@ -1449,19 +1453,27 @@ pub const WipNav = struct { |
| 1449 | 1453 | loc: u32, |
| 1450 | 1454 | cfa: Cfa.RegOff, |
| 1451 | 1455 | }, |
| 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, | |
| 1456 | 1460 | pending_lazy: PendingLazy, |
| 1457 | 1461 | |
| 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 | ||
| 1458 | 1470 | pub fn deinit(wip_nav: *WipNav) void { |
| 1459 | 1471 | const gpa = wip_nav.dwarf.gpa; |
| 1460 | 1472 | 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(); | |
| 1465 | 1477 | wip_nav.pending_lazy.types.deinit(gpa); |
| 1466 | 1478 | wip_nav.pending_lazy.values.deinit(gpa); |
| 1467 | 1479 | } |
| ... | ... | @@ -1470,8 +1482,8 @@ pub const WipNav = struct { |
| 1470 | 1482 | assert(wip_nav.func != .none); |
| 1471 | 1483 | if (wip_nav.dwarf.debug_frame.header.format == .none) return; |
| 1472 | 1484 | 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); | |
| 1475 | 1487 | } |
| 1476 | 1488 | |
| 1477 | 1489 | pub const LocalVarTag = enum { arg, local_var }; |
| ... | ... | @@ -1529,7 +1541,7 @@ pub const WipNav = struct { |
| 1529 | 1541 | |
| 1530 | 1542 | pub fn genVarArgsDebugInfo(wip_nav: *WipNav) UpdateError!void { |
| 1531 | 1543 | 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); | |
| 1533 | 1545 | wip_nav.any_children = true; |
| 1534 | 1546 | } |
| 1535 | 1547 | |
| ... | ... | @@ -1538,7 +1550,7 @@ pub const WipNav = struct { |
| 1538 | 1550 | delta_line: i33, |
| 1539 | 1551 | delta_pc: u64, |
| 1540 | 1552 | ) error{OutOfMemory}!void { |
| 1541 | const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa); | |
| 1553 | const dlbw = &wip_nav.debug_line.buffered_writer; | |
| 1542 | 1554 | |
| 1543 | 1555 | const header = wip_nav.dwarf.debug_line.header; |
| 1544 | 1556 | assert(header.maximum_operations_per_instruction == 1); |
| ... | ... | @@ -1548,8 +1560,8 @@ pub const WipNav = struct { |
| 1548 | 1560 | delta_line - header.line_base >= header.line_range) |
| 1549 | 1561 | remaining: { |
| 1550 | 1562 | 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); | |
| 1553 | 1565 | break :remaining 0; |
| 1554 | 1566 | } else delta_line); |
| 1555 | 1567 | |
| ... | ... | @@ -1557,68 +1569,68 @@ pub const WipNav = struct { |
| 1557 | 1569 | header.maximum_operations_per_instruction + delta_op; |
| 1558 | 1570 | const max_op_advance: u9 = (std.math.maxInt(u8) - header.opcode_base) / header.line_range; |
| 1559 | 1571 | 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); | |
| 1562 | 1574 | break :remaining 0; |
| 1563 | 1575 | } 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); | |
| 1565 | 1577 | break :remaining op_advance - max_op_advance; |
| 1566 | 1578 | } else op_advance); |
| 1567 | 1579 | |
| 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); | |
| 1573 | 1587 | } |
| 1574 | 1588 | |
| 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); | |
| 1579 | 1593 | } |
| 1580 | 1594 | |
| 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)); | |
| 1584 | 1597 | } |
| 1585 | 1598 | |
| 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)); | |
| 1589 | 1601 | } |
| 1590 | 1602 | |
| 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)); | |
| 1594 | 1605 | } |
| 1595 | 1606 | |
| 1596 | pub fn enterBlock(wip_nav: *WipNav, code_off: u64) UpdateError!void { | |
| 1607 | pub fn enterBlock(wip_nav: *WipNav, code_off: u64) anyerror!void { | |
| 1597 | 1608 | const dwarf = wip_nav.dwarf; |
| 1598 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 1609 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 1599 | 1610 | const block = try wip_nav.blocks.addOne(dwarf.gpa); |
| 1600 | 1611 | |
| 1601 | block.abbrev_code = @intCast(wip_nav.debug_info.items.len); | |
| 1612 | block.abbrev_code = @intCast(dibw.count); | |
| 1602 | 1613 | try wip_nav.abbrevCode(.block); |
| 1603 | 1614 | block.low_pc_off = code_off; |
| 1604 | 1615 | 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); | |
| 1607 | 1618 | wip_nav.any_children = false; |
| 1608 | 1619 | } |
| 1609 | 1620 | |
| 1610 | pub fn leaveBlock(wip_nav: *WipNav, code_off: u64) UpdateError!void { | |
| 1621 | pub fn leaveBlock(wip_nav: *WipNav, code_off: u64) anyerror!void { | |
| 1611 | 1622 | const block_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.block)); |
| 1612 | 1623 | const block = wip_nav.blocks.pop().?; |
| 1624 | const dib = wip_nav.debug_info.getWritten(); | |
| 1613 | 1625 | 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)) | |
| 1615 | 1627 | else |
| 1616 | 1628 | std.leb.writeUnsignedFixed( |
| 1617 | 1629 | block_bytes, |
| 1618 | wip_nav.debug_info.items[block.abbrev_code..][0..block_bytes], | |
| 1630 | dib[block.abbrev_code..][0..block_bytes], | |
| 1619 | 1631 | try wip_nav.dwarf.refAbbrevCode(.empty_block), |
| 1620 | 1632 | ); |
| 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); | |
| 1622 | 1634 | wip_nav.any_children = true; |
| 1623 | 1635 | } |
| 1624 | 1636 | |
| ... | ... | @@ -1628,42 +1640,43 @@ pub const WipNav = struct { |
| 1628 | 1640 | code_off: u64, |
| 1629 | 1641 | line: u32, |
| 1630 | 1642 | column: u32, |
| 1631 | ) UpdateError!void { | |
| 1643 | ) anyerror!void { | |
| 1632 | 1644 | const dwarf = wip_nav.dwarf; |
| 1633 | 1645 | 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; | |
| 1635 | 1647 | const block = try wip_nav.blocks.addOne(dwarf.gpa); |
| 1636 | 1648 | |
| 1637 | block.abbrev_code = @intCast(wip_nav.debug_info.items.len); | |
| 1649 | block.abbrev_code = @intCast(dibw.count); | |
| 1638 | 1650 | try wip_nav.abbrevCode(.inlined_func); |
| 1639 | 1651 | 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); | |
| 1642 | 1654 | block.low_pc_off = code_off; |
| 1643 | 1655 | 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); | |
| 1646 | 1658 | try wip_nav.setInlineFunc(func); |
| 1647 | 1659 | wip_nav.any_children = false; |
| 1648 | 1660 | } |
| 1649 | 1661 | |
| 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 { | |
| 1651 | 1663 | const inlined_func_bytes = comptime uleb128Bytes(@intFromEnum(AbbrevCode.inlined_func)); |
| 1652 | 1664 | const block = wip_nav.blocks.pop().?; |
| 1665 | const dib = wip_nav.debug_info.getWritten(); | |
| 1653 | 1666 | 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)) | |
| 1655 | 1668 | else |
| 1656 | 1669 | std.leb.writeUnsignedFixed( |
| 1657 | 1670 | 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], | |
| 1659 | 1672 | try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func), |
| 1660 | 1673 | ); |
| 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); | |
| 1662 | 1675 | try wip_nav.setInlineFunc(func); |
| 1663 | 1676 | wip_nav.any_children = true; |
| 1664 | 1677 | } |
| 1665 | 1678 | |
| 1666 | pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) UpdateError!void { | |
| 1679 | pub fn setInlineFunc(wip_nav: *WipNav, func: InternPool.Index) anyerror!void { | |
| 1667 | 1680 | const zcu = wip_nav.pt.zcu; |
| 1668 | 1681 | const dwarf = wip_nav.dwarf; |
| 1669 | 1682 | if (wip_nav.func == func) return; |
| ... | ... | @@ -1672,22 +1685,22 @@ pub const WipNav = struct { |
| 1672 | 1685 | const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav); |
| 1673 | 1686 | const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod.?); |
| 1674 | 1687 | |
| 1675 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); | |
| 1688 | const dlbw = &wip_nav.debug_line.buffered_writer; | |
| 1676 | 1689 | if (dwarf.incremental()) { |
| 1677 | 1690 | const new_nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, new_func_info.owner_nav); |
| 1678 | 1691 | errdefer _ = if (!new_nav_gop.found_existing) dwarf.navs.pop(); |
| 1679 | 1692 | if (!new_nav_gop.found_existing) new_nav_gop.value_ptr.* = try dwarf.addCommonEntry(new_unit); |
| 1680 | 1693 | |
| 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); | |
| 1684 | 1697 | 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), | |
| 1686 | 1699 | .target_sec = .debug_info, |
| 1687 | 1700 | .target_unit = new_unit, |
| 1688 | 1701 | .target_entry = new_nav_gop.value_ptr.toOptional(), |
| 1689 | 1702 | }); |
| 1690 | try dlw.writeByteNTimes(0, dwarf.sectionOffsetBytes()); | |
| 1703 | try dlbw.splatByteAll(0, dwarf.sectionOffsetBytes()); | |
| 1691 | 1704 | return; |
| 1692 | 1705 | } |
| 1693 | 1706 | |
| ... | ... | @@ -1698,15 +1711,15 @@ pub const WipNav = struct { |
| 1698 | 1711 | try mod_info.dirs.put(dwarf.gpa, new_unit, {}); |
| 1699 | 1712 | const file_gop = try mod_info.files.getOrPut(dwarf.gpa, new_file); |
| 1700 | 1713 | |
| 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); | |
| 1703 | 1716 | } |
| 1704 | 1717 | |
| 1705 | 1718 | const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav); |
| 1706 | 1719 | const new_src_line: i33 = zcu.navSrcLine(new_func_info.owner_nav); |
| 1707 | 1720 | 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); | |
| 1710 | 1723 | } |
| 1711 | 1724 | |
| 1712 | 1725 | wip_nav.func = func; |
| ... | ... | @@ -1724,16 +1737,23 @@ pub const WipNav = struct { |
| 1724 | 1737 | try wip_nav.externalReloc(&wip_nav.dwarf.debug_frame.section, reloc); |
| 1725 | 1738 | } |
| 1726 | 1739 | |
| 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)); | |
| 1729 | 1742 | } |
| 1730 | 1743 | |
| 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 { | |
| 1732 | 1752 | const dwarf = wip_nav.dwarf; |
| 1733 | 1753 | const gpa = dwarf.gpa; |
| 1734 | 1754 | 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); | |
| 1737 | 1757 | if (target_sec != sec) { |
| 1738 | 1758 | try entry_ptr.cross_section_relocs.append(gpa, .{ |
| 1739 | 1759 | .source_off = source_off, |
| ... | ... | @@ -1756,112 +1776,108 @@ pub const WipNav = struct { |
| 1756 | 1776 | .target_off = target_off, |
| 1757 | 1777 | }); |
| 1758 | 1778 | } |
| 1759 | try bytes.appendNTimes(gpa, 0, dwarf.sectionOffsetBytes()); | |
| 1779 | try bw.splatByteAll(0, dwarf.sectionOffsetBytes()); | |
| 1760 | 1780 | } |
| 1761 | 1781 | |
| 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 { | |
| 1763 | 1783 | try wip_nav.sectionOffset(.debug_info, target_sec, target_unit, target_entry, target_off); |
| 1764 | 1784 | } |
| 1765 | 1785 | |
| 1766 | fn strp(wip_nav: *WipNav, str: []const u8) UpdateError!void { | |
| 1786 | fn strp(wip_nav: *WipNav, str: []const u8) anyerror!void { | |
| 1767 | 1787 | try wip_nav.infoSectionOffset(.debug_str, StringSection.unit, try wip_nav.dwarf.debug_str.addString(wip_nav.dwarf, str), 0); |
| 1768 | 1788 | } |
| 1769 | 1789 | |
| 1770 | 1790 | const ExprLocCounter = struct { |
| 1771 | stream: *std.io.BufferedWriter, | |
| 1772 | 1791 | section_offset_bytes: u32, |
| 1773 | 1792 | address_size: AddressSize, |
| 1774 | counter: usize, | |
| 1775 | fn init(dwarf: *Dwarf, stream: *std.io.BufferedWriter) ExprLocCounter { | |
| 1793 | fn init(dwarf: *Dwarf) ExprLocCounter { | |
| 1776 | 1794 | return .{ |
| 1777 | .stream = stream, | |
| 1778 | 1795 | .section_offset_bytes = dwarf.sectionOffsetBytes(), |
| 1779 | 1796 | .address_size = dwarf.address_size, |
| 1780 | 1797 | }; |
| 1781 | 1798 | } |
| 1782 | fn writer(counter: *ExprLocCounter) *std.io.BufferedWriter { | |
| 1783 | return counter.stream; | |
| 1784 | } | |
| 1785 | 1799 | fn endian(_: ExprLocCounter) std.builtin.Endian { |
| 1786 | 1800 | return @import("builtin").cpu.arch.endian(); |
| 1787 | 1801 | } |
| 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); | |
| 1790 | 1804 | } |
| 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; | |
| 1793 | 1807 | } |
| 1794 | 1808 | }; |
| 1795 | 1809 | |
| 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); | |
| 1801 | 1818 | |
| 1802 | 1819 | const adapter: struct { |
| 1803 | 1820 | 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 | } | |
| 1807 | 1821 | fn endian(ctx: @This()) std.builtin.Endian { |
| 1808 | 1822 | return ctx.wip_nav.dwarf.endian; |
| 1809 | 1823 | } |
| 1810 | fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void { | |
| 1824 | fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) anyerror!void { | |
| 1811 | 1825 | try ctx.wip_nav.infoAddrSym(sym_index, 0); |
| 1812 | 1826 | } |
| 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 { | |
| 1814 | 1828 | try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); |
| 1815 | 1829 | } |
| 1816 | 1830 | } = .{ .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); | |
| 1819 | 1833 | } |
| 1820 | 1834 | |
| 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; | |
| 1822 | 1837 | try wip_nav.infoExternalReloc(.{ |
| 1823 | .source_off = @intCast(wip_nav.debug_info.items.len), | |
| 1838 | .source_off = @intCast(dibw.count), | |
| 1824 | 1839 | .target_sym = sym_index, |
| 1825 | 1840 | .target_off = sym_off, |
| 1826 | 1841 | }); |
| 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)); | |
| 1828 | 1843 | } |
| 1829 | 1844 | |
| 1830 | 1845 | 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); | |
| 1835 | 1853 | |
| 1836 | 1854 | const adapter: struct { |
| 1837 | 1855 | 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 | } | |
| 1841 | 1856 | fn endian(ctx: @This()) std.builtin.Endian { |
| 1842 | 1857 | return ctx.wip_nav.dwarf.endian; |
| 1843 | 1858 | } |
| 1844 | fn addrSym(ctx: @This(), sym_index: u32) UpdateError!void { | |
| 1859 | fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) anyerror!void { | |
| 1845 | 1860 | try ctx.wip_nav.frameAddrSym(sym_index, 0); |
| 1846 | 1861 | } |
| 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 { | |
| 1848 | 1863 | try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0); |
| 1849 | 1864 | } |
| 1850 | 1865 | } = .{ .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); | |
| 1853 | 1868 | } |
| 1854 | 1869 | |
| 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; | |
| 1856 | 1872 | try wip_nav.frameExternalReloc(.{ |
| 1857 | .source_off = @intCast(wip_nav.debug_frame.items.len), | |
| 1873 | .source_off = @intCast(dfbw.count), | |
| 1858 | 1874 | .target_sym = sym_index, |
| 1859 | 1875 | .target_off = sym_off, |
| 1860 | 1876 | }); |
| 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)); | |
| 1862 | 1878 | } |
| 1863 | 1879 | |
| 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 } { | |
| 1865 | 1881 | const zcu = wip_nav.pt.zcu; |
| 1866 | 1882 | const ip = &zcu.intern_pool; |
| 1867 | 1883 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -1873,12 +1889,12 @@ pub const WipNav = struct { |
| 1873 | 1889 | return .{ unit, entry }; |
| 1874 | 1890 | } |
| 1875 | 1891 | |
| 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 { | |
| 1877 | 1893 | const unit, const entry = try wip_nav.getNavEntry(nav_index); |
| 1878 | 1894 | try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); |
| 1879 | 1895 | } |
| 1880 | 1896 | |
| 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 } { | |
| 1882 | 1898 | const zcu = wip_nav.pt.zcu; |
| 1883 | 1899 | const ip = &zcu.intern_pool; |
| 1884 | 1900 | const maybe_inst_index = ty.typeDeclInst(zcu); |
| ... | ... | @@ -1900,12 +1916,12 @@ pub const WipNav = struct { |
| 1900 | 1916 | return .{ unit, entry }; |
| 1901 | 1917 | } |
| 1902 | 1918 | |
| 1903 | fn refType(wip_nav: *WipNav, ty: Type) UpdateError!void { | |
| 1919 | fn refType(wip_nav: *WipNav, ty: Type) anyerror!void { | |
| 1904 | 1920 | const unit, const entry = try wip_nav.getTypeEntry(ty); |
| 1905 | 1921 | try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); |
| 1906 | 1922 | } |
| 1907 | 1923 | |
| 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 } { | |
| 1909 | 1925 | const zcu = wip_nav.pt.zcu; |
| 1910 | 1926 | const ip = &zcu.intern_pool; |
| 1911 | 1927 | const ty = value.typeOf(zcu); |
| ... | ... | @@ -1921,47 +1937,50 @@ pub const WipNav = struct { |
| 1921 | 1937 | return .{ unit, entry }; |
| 1922 | 1938 | } |
| 1923 | 1939 | |
| 1924 | fn refValue(wip_nav: *WipNav, value: Value) UpdateError!void { | |
| 1940 | fn refValue(wip_nav: *WipNav, value: Value) anyerror!void { | |
| 1925 | 1941 | const unit, const entry = try wip_nav.getValueEntry(value); |
| 1926 | 1942 | try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0); |
| 1927 | 1943 | } |
| 1928 | 1944 | |
| 1929 | fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 { | |
| 1945 | fn refForward(wip_nav: *WipNav) anyerror!u32 { | |
| 1930 | 1946 | const dwarf = wip_nav.dwarf; |
| 1947 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 1931 | 1948 | const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs; |
| 1932 | 1949 | const reloc_index: u32 = @intCast(cross_entry_relocs.items.len); |
| 1933 | 1950 | try cross_entry_relocs.append(dwarf.gpa, .{ |
| 1934 | .source_off = @intCast(wip_nav.debug_info.items.len), | |
| 1951 | .source_off = @intCast(dibw.count), | |
| 1935 | 1952 | .target_entry = undefined, |
| 1936 | 1953 | .target_off = undefined, |
| 1937 | 1954 | }); |
| 1938 | try wip_nav.debug_info.appendNTimes(dwarf.gpa, 0, dwarf.sectionOffsetBytes()); | |
| 1955 | try dibw.splatByteAll(0, dwarf.sectionOffsetBytes()); | |
| 1939 | 1956 | return reloc_index; |
| 1940 | 1957 | } |
| 1941 | 1958 | |
| 1942 | 1959 | fn finishForward(wip_nav: *WipNav, reloc_index: u32) void { |
| 1943 | 1960 | const reloc = &wip_nav.dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs.items[reloc_index]; |
| 1944 | 1961 | 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); | |
| 1946 | 1963 | } |
| 1947 | 1964 | |
| 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 { | |
| 1949 | 1966 | 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; | |
| 1951 | 1968 | 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); | |
| 1953 | 1970 | 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; | |
| 1955 | 1974 | try codegen.generateSymbol( |
| 1956 | 1975 | wip_nav.dwarf.bin_file, |
| 1957 | 1976 | wip_nav.pt, |
| 1958 | 1977 | src_loc, |
| 1959 | 1978 | val, |
| 1960 | &wip_nav.debug_info, | |
| 1979 | &dial, | |
| 1961 | 1980 | .{ .debug_output = .{ .dwarf = wip_nav } }, |
| 1962 | 1981 | ); |
| 1963 | 1982 | 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 }); | |
| 1965 | 1984 | unreachable; |
| 1966 | 1985 | } |
| 1967 | 1986 | } |
| ... | ... | @@ -1977,9 +1996,9 @@ pub const WipNav = struct { |
| 1977 | 1996 | abbrev_code: AbbrevCodeForForm, |
| 1978 | 1997 | ty: Type, |
| 1979 | 1998 | big_int: std.math.big.int.Const, |
| 1980 | ) UpdateError!void { | |
| 1999 | ) anyerror!void { | |
| 1981 | 2000 | 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; | |
| 1983 | 2002 | const signedness = switch (ty.toIntern()) { |
| 1984 | 2003 | .comptime_int_type, .comptime_float_type => .signed, |
| 1985 | 2004 | else => ty.intInfo(zcu).signedness, |
| ... | ... | @@ -1990,7 +2009,7 @@ pub const WipNav = struct { |
| 1990 | 2009 | .signed => abbrev_code.sdata, |
| 1991 | 2010 | .unsigned => abbrev_code.udata, |
| 1992 | 2011 | }); |
| 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); | |
| 1994 | 2013 | var bit: usize = 0; |
| 1995 | 2014 | var carry: u1 = 1; |
| 1996 | 2015 | while (bit < bits) { |
| ... | ... | @@ -2007,16 +2026,17 @@ pub const WipNav = struct { |
| 2007 | 2026 | break :twos_comp_part twos_comp_part; |
| 2008 | 2027 | }; |
| 2009 | 2028 | 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; | |
| 2011 | 2030 | } |
| 2012 | 2031 | } else { |
| 2013 | 2032 | try wip_nav.abbrevCode(abbrev_code.block); |
| 2014 | 2033 | const bytes = @max(ty.abiSize(zcu), std.math.divCeil(usize, bits, 8) catch unreachable); |
| 2015 | try uleb128(diw, bytes); | |
| 2034 | try dibw.writeLeb128(bytes); | |
| 2016 | 2035 | big_int.writeTwosComplement( |
| 2017 | try wip_nav.debug_info.addManyAsSlice(wip_nav.dwarf.gpa, @intCast(bytes)), | |
| 2036 | try dibw.writableSlice(@intCast(bytes)), | |
| 2018 | 2037 | wip_nav.dwarf.endian, |
| 2019 | 2038 | ); |
| 2039 | dibw.advance(@intCast(bytes)); | |
| 2020 | 2040 | } |
| 2021 | 2041 | } |
| 2022 | 2042 | |
| ... | ... | @@ -2025,7 +2045,7 @@ pub const WipNav = struct { |
| 2025 | 2045 | loaded_enum: InternPool.LoadedEnumType, |
| 2026 | 2046 | abbrev_code: AbbrevCodeForForm, |
| 2027 | 2047 | field_index: usize, |
| 2028 | ) UpdateError!void { | |
| 2048 | ) anyerror!void { | |
| 2029 | 2049 | const zcu = wip_nav.pt.zcu; |
| 2030 | 2050 | const ip = &zcu.intern_pool; |
| 2031 | 2051 | var big_int_space: Value.BigIntSpace = undefined; |
| ... | ... | @@ -2045,11 +2065,11 @@ pub const WipNav = struct { |
| 2045 | 2065 | nav: *const InternPool.Nav, |
| 2046 | 2066 | file: Zcu.File.Index, |
| 2047 | 2067 | decl: *const std.zig.Zir.Inst.Declaration.Unwrapped, |
| 2048 | ) UpdateError!void { | |
| 2068 | ) anyerror!void { | |
| 2049 | 2069 | const zcu = wip_nav.pt.zcu; |
| 2050 | 2070 | const ip = &zcu.intern_pool; |
| 2051 | 2071 | const dwarf = wip_nav.dwarf; |
| 2052 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 2072 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 2053 | 2073 | |
| 2054 | 2074 | const orig_entry = wip_nav.entry; |
| 2055 | 2075 | defer wip_nav.entry = orig_entry; |
| ... | ... | @@ -2100,15 +2120,15 @@ pub const WipNav = struct { |
| 2100 | 2120 | try wip_nav.abbrevCode(if (is_generic_decl) abbrev_code.generic_decl else abbrev_code.decl); |
| 2101 | 2121 | try wip_nav.refType((if (is_generic_decl) null else parent_type) orelse |
| 2102 | 2122 | .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); | |
| 2107 | 2127 | try wip_nav.strp(nav.name.toSlice(ip)); |
| 2108 | 2128 | |
| 2109 | 2129 | if (!is_generic_decl) return; |
| 2110 | 2130 | 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()); | |
| 2112 | 2132 | wip_nav.debug_info.clearRetainingCapacity(); |
| 2113 | 2133 | wip_nav.entry = orig_entry; |
| 2114 | 2134 | try wip_nav.abbrevCode(abbrev_code.decl_instance); |
| ... | ... | @@ -2123,7 +2143,7 @@ pub const WipNav = struct { |
| 2123 | 2143 | const empty: PendingLazy = .{ .types = .empty, .values = .empty }; |
| 2124 | 2144 | }; |
| 2125 | 2145 | |
| 2126 | fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void { | |
| 2146 | fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) anyerror!void { | |
| 2127 | 2147 | while (true) if (wip_nav.pending_lazy.types.pop()) |pending_ty| |
| 2128 | 2148 | try wip_nav.dwarf.updateLazyType(wip_nav.pt, src_loc, pending_ty, &wip_nav.pending_lazy) |
| 2129 | 2149 | else if (wip_nav.pending_lazy.values.pop()) |pending_val| |
| ... | ... | @@ -2346,7 +2366,7 @@ pub fn deinit(dwarf: *Dwarf) void { |
| 2346 | 2366 | dwarf.* = undefined; |
| 2347 | 2367 | } |
| 2348 | 2368 | |
| 2349 | fn getUnit(dwarf: *Dwarf, mod: *Module) !Unit.Index { | |
| 2369 | fn getUnit(dwarf: *Dwarf, mod: *Module) anyerror!Unit.Index { | |
| 2350 | 2370 | const mod_gop = try dwarf.mods.getOrPut(dwarf.gpa, mod); |
| 2351 | 2371 | const unit: Unit.Index = @enumFromInt(mod_gop.index); |
| 2352 | 2372 | if (!mod_gop.found_existing) { |
| ... | ... | @@ -2412,18 +2432,69 @@ pub fn initWipNav( |
| 2412 | 2432 | nav_index: InternPool.Nav.Index, |
| 2413 | 2433 | sym_index: u32, |
| 2414 | 2434 | ) 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 | ||
| 2441 | pub 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))) { | |
| 2416 | 2449 | 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)}), | |
| 2418 | 2451 | }; |
| 2419 | 2452 | } |
| 2420 | 2453 | |
| 2454 | pub 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 | ||
| 2466 | pub 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 | ||
| 2477 | pub 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 | ||
| 2488 | pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | |
| 2489 | return @errorCast(dwarf.flushModuleInner(pt)); | |
| 2490 | } | |
| 2491 | ||
| 2421 | 2492 | fn initWipNavInner( |
| 2422 | 2493 | dwarf: *Dwarf, |
| 2423 | 2494 | pt: Zcu.PerThread, |
| 2424 | 2495 | nav_index: InternPool.Nav.Index, |
| 2425 | 2496 | sym_index: u32, |
| 2426 | ) !?WipNav { | |
| 2497 | ) anyerror!?WipNav { | |
| 2427 | 2498 | const zcu = pt.zcu; |
| 2428 | 2499 | const ip = &zcu.intern_pool; |
| 2429 | 2500 | |
| ... | ... | @@ -2431,7 +2502,7 @@ fn initWipNavInner( |
| 2431 | 2502 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; |
| 2432 | 2503 | const file = zcu.fileByIndex(inst_info.file); |
| 2433 | 2504 | 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})", .{ | |
| 2435 | 2506 | file.sub_file_path, |
| 2436 | 2507 | decl.src_line + 1, |
| 2437 | 2508 | decl.src_column + 1, |
| ... | ... | @@ -2472,17 +2543,17 @@ fn initWipNavInner( |
| 2472 | 2543 | .func_high_pc = undefined, |
| 2473 | 2544 | .blocks = undefined, |
| 2474 | 2545 | .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, | |
| 2479 | 2550 | .pending_lazy = .empty, |
| 2480 | 2551 | }; |
| 2481 | 2552 | errdefer wip_nav.deinit(); |
| 2482 | 2553 | |
| 2483 | 2554 | switch (nav_key) { |
| 2484 | 2555 | else => { |
| 2485 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 2556 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 2486 | 2557 | try wip_nav.declCommon(.{ |
| 2487 | 2558 | .decl = .decl_var, |
| 2488 | 2559 | .generic_decl = .generic_decl_var, |
| ... | ... | @@ -2497,9 +2568,9 @@ fn initWipNavInner( |
| 2497 | 2568 | .@"const" => { |
| 2498 | 2569 | const const_ty_reloc_index = try wip_nav.refForward(); |
| 2499 | 2570 | 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 | |
| 2501 | 2572 | ty.abiAlignment(zcu).toByteUnits().?); |
| 2502 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 2573 | try dibw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 2503 | 2574 | wip_nav.finishForward(const_ty_reloc_index); |
| 2504 | 2575 | try wip_nav.abbrevCode(.is_const); |
| 2505 | 2576 | try wip_nav.refType(ty); |
| ... | ... | @@ -2507,9 +2578,9 @@ fn initWipNavInner( |
| 2507 | 2578 | .@"var" => { |
| 2508 | 2579 | try wip_nav.refType(ty); |
| 2509 | 2580 | 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 | |
| 2511 | 2582 | ty.abiAlignment(zcu).toByteUnits().?); |
| 2512 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 2583 | try dibw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 2513 | 2584 | }, |
| 2514 | 2585 | } |
| 2515 | 2586 | }, |
| ... | ... | @@ -2534,39 +2605,39 @@ fn initWipNavInner( |
| 2534 | 2605 | .none => {}, |
| 2535 | 2606 | .debug_frame, .eh_frame => |format| { |
| 2536 | 2607 | 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; | |
| 2538 | 2609 | switch (dwarf.format) { |
| 2539 | .@"32" => try dfw.writeInt(u32, undefined, dwarf.endian), | |
| 2610 | .@"32" => try dfbw.writeInt(u32, undefined, dwarf.endian), | |
| 2540 | 2611 | .@"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); | |
| 2543 | 2614 | }, |
| 2544 | 2615 | } |
| 2545 | 2616 | switch (format) { |
| 2546 | 2617 | .none => unreachable, |
| 2547 | 2618 | .debug_frame => { |
| 2548 | 2619 | try entry.cross_entry_relocs.append(dwarf.gpa, .{ |
| 2549 | .source_off = @intCast(wip_nav.debug_frame.items.len), | |
| 2620 | .source_off = @intCast(dfbw.count), | |
| 2550 | 2621 | }); |
| 2551 | try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes()); | |
| 2622 | try dfbw.splatByteAll(0, dwarf.sectionOffsetBytes()); | |
| 2552 | 2623 | 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)); | |
| 2554 | 2625 | }, |
| 2555 | 2626 | .eh_frame => { |
| 2556 | try dfw.writeInt(u32, undefined, dwarf.endian); | |
| 2627 | try dfbw.writeInt(u32, undefined, dwarf.endian); | |
| 2557 | 2628 | try wip_nav.frameExternalReloc(.{ |
| 2558 | .source_off = @intCast(wip_nav.debug_frame.items.len), | |
| 2629 | .source_off = @intCast(dfbw.count), | |
| 2559 | 2630 | .target_sym = sym_index, |
| 2560 | 2631 | }); |
| 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); | |
| 2564 | 2635 | }, |
| 2565 | 2636 | } |
| 2566 | 2637 | }, |
| 2567 | 2638 | } |
| 2568 | 2639 | |
| 2569 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 2640 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 2570 | 2641 | try wip_nav.declCommon(.{ |
| 2571 | 2642 | .decl = .decl_func, |
| 2572 | 2643 | .generic_decl = .generic_decl_func, |
| ... | ... | @@ -2576,47 +2647,47 @@ fn initWipNavInner( |
| 2576 | 2647 | try wip_nav.refType(.fromInterned(func_type.return_type)); |
| 2577 | 2648 | try wip_nav.infoAddrSym(sym_index, 0); |
| 2578 | 2649 | 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); | |
| 2580 | 2651 | 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) { | |
| 2582 | 2653 | .none => target_info.defaultFunctionAlignment(target), |
| 2583 | 2654 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), |
| 2584 | 2655 | }.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)); | |
| 2587 | 2658 | |
| 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); | |
| 2590 | 2661 | 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); | |
| 2593 | 2664 | 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), | |
| 2595 | 2666 | .target_sec = .debug_info, |
| 2596 | 2667 | .target_unit = wip_nav.unit, |
| 2597 | 2668 | .target_entry = wip_nav.entry.toOptional(), |
| 2598 | 2669 | }); |
| 2599 | try dlw.writeByteNTimes(0, dwarf.sectionOffsetBytes()); | |
| 2670 | try dlbw.splatByteAll(0, dwarf.sectionOffsetBytes()); | |
| 2600 | 2671 | |
| 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); | |
| 2603 | 2674 | |
| 2604 | 2675 | try wip_nav.advancePCAndLine(func.lbrace_line, 0); |
| 2605 | 2676 | } 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); | |
| 2608 | 2679 | 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), | |
| 2610 | 2681 | .target_sym = sym_index, |
| 2611 | 2682 | }); |
| 2612 | try dlw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); | |
| 2683 | try dlbw.splatByteAll(0, @intFromEnum(dwarf.address_size)); | |
| 2613 | 2684 | |
| 2614 | 2685 | 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); | |
| 2617 | 2688 | |
| 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); | |
| 2620 | 2691 | |
| 2621 | 2692 | try wip_nav.advancePCAndLine(@intCast(decl.src_line + func.lbrace_line), 0); |
| 2622 | 2693 | } |
| ... | ... | @@ -2625,18 +2696,18 @@ fn initWipNavInner( |
| 2625 | 2696 | return wip_nav; |
| 2626 | 2697 | } |
| 2627 | 2698 | |
| 2628 | pub fn finishWipNavFunc( | |
| 2699 | fn finishWipNavFuncInner( | |
| 2629 | 2700 | dwarf: *Dwarf, |
| 2630 | 2701 | pt: Zcu.PerThread, |
| 2631 | 2702 | nav_index: InternPool.Nav.Index, |
| 2632 | 2703 | code_size: u64, |
| 2633 | 2704 | wip_nav: *WipNav, |
| 2634 | ) UpdateError!void { | |
| 2705 | ) anyerror!void { | |
| 2635 | 2706 | const zcu = pt.zcu; |
| 2636 | 2707 | const ip = &zcu.intern_pool; |
| 2637 | 2708 | const nav = ip.getNav(nav_index); |
| 2638 | 2709 | assert(wip_nav.func != .none); |
| 2639 | log.debug("finishWipNavFunc({})", .{nav.fqn.fmt(ip)}); | |
| 2710 | log.debug("finishWipNavFunc({f})", .{nav.fqn.fmt(ip)}); | |
| 2640 | 2711 | |
| 2641 | 2712 | { |
| 2642 | 2713 | const external_relocs = &dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs; |
| ... | ... | @@ -2654,12 +2725,9 @@ pub fn finishWipNavFunc( |
| 2654 | 2725 | switch (dwarf.debug_frame.header.format) { |
| 2655 | 2726 | .none => {}, |
| 2656 | 2727 | .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(); | |
| 2663 | 2731 | try dwarf.debug_frame.section.resizeEntry(wip_nav.unit, wip_nav.entry, dwarf, @intCast(contents.len)); |
| 2664 | 2732 | const unit = dwarf.debug_frame.section.getUnit(wip_nav.unit); |
| 2665 | 2733 | const entry = unit.getEntry(wip_nav.entry); |
| ... | ... | @@ -2686,14 +2754,15 @@ pub fn finishWipNavFunc( |
| 2686 | 2754 | }, |
| 2687 | 2755 | } |
| 2688 | 2756 | { |
| 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); | |
| 2690 | 2758 | 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)); | |
| 2693 | 2761 | } 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); | |
| 2697 | 2766 | std.leb.writeUnsignedFixed( |
| 2698 | 2767 | AbbrevCode.decl_bytes, |
| 2699 | 2768 | abbrev_code_buf, |
| ... | ... | @@ -2725,41 +2794,35 @@ pub fn finishWipNavFunc( |
| 2725 | 2794 | ); |
| 2726 | 2795 | } |
| 2727 | 2796 | |
| 2728 | try dwarf.finishWipNav(pt, nav_index, wip_nav); | |
| 2797 | try dwarf.finishWipNavInner(pt, nav_index, wip_nav); | |
| 2729 | 2798 | } |
| 2730 | 2799 | |
| 2731 | pub fn finishWipNav( | |
| 2800 | fn finishWipNavInner( | |
| 2732 | 2801 | dwarf: *Dwarf, |
| 2733 | 2802 | pt: Zcu.PerThread, |
| 2734 | 2803 | nav_index: InternPool.Nav.Index, |
| 2735 | 2804 | wip_nav: *WipNav, |
| 2736 | ) UpdateError!void { | |
| 2805 | ) anyerror!void { | |
| 2737 | 2806 | const zcu = pt.zcu; |
| 2738 | 2807 | const ip = &zcu.intern_pool; |
| 2739 | 2808 | 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()); | |
| 2749 | 2819 | } |
| 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()); | |
| 2751 | 2821 | |
| 2752 | 2822 | try wip_nav.updateLazy(zcu.navSrcLoc(nav_index)); |
| 2753 | 2823 | } |
| 2754 | 2824 | |
| 2755 | pub 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 | ||
| 2762 | fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | |
| 2825 | fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) anyerror!void { | |
| 2763 | 2826 | const zcu = pt.zcu; |
| 2764 | 2827 | const ip = &zcu.intern_pool; |
| 2765 | 2828 | const nav_src_loc = zcu.navSrcLoc(nav_index); |
| ... | ... | @@ -2769,7 +2832,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2769 | 2832 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; |
| 2770 | 2833 | const file = zcu.fileByIndex(inst_info.file); |
| 2771 | 2834 | 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})", .{ | |
| 2773 | 2836 | file.sub_file_path, |
| 2774 | 2837 | decl.src_line + 1, |
| 2775 | 2838 | decl.src_column + 1, |
| ... | ... | @@ -2797,12 +2860,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2797 | 2860 | .func_high_pc = undefined, |
| 2798 | 2861 | .blocks = undefined, |
| 2799 | 2862 | .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, | |
| 2804 | 2867 | .pending_lazy = .empty, |
| 2805 | 2868 | }; |
| 2869 | wip_nav.init(); | |
| 2806 | 2870 | defer wip_nav.deinit(); |
| 2807 | 2871 | |
| 2808 | 2872 | 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 |
| 2846 | 2910 | } |
| 2847 | 2911 | wip_nav.entry = nav_gop.value_ptr.*; |
| 2848 | 2912 | |
| 2849 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 2913 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 2850 | 2914 | |
| 2851 | 2915 | switch (loaded_struct.layout) { |
| 2852 | 2916 | .auto, .@"extern" => { |
| ... | ... | @@ -2859,9 +2923,9 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2859 | 2923 | .generic_decl = .generic_decl_const, |
| 2860 | 2924 | .decl_instance = .decl_instance_struct, |
| 2861 | 2925 | }, &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().?); | |
| 2865 | 2929 | for (0..loaded_struct.field_types.len) |field_index| { |
| 2866 | 2930 | const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); |
| 2867 | 2931 | const field_init = loaded_struct.fieldInit(ip, field_index); |
| ... | ... | @@ -2897,8 +2961,8 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2897 | 2961 | } |
| 2898 | 2962 | try wip_nav.refType(field_type); |
| 2899 | 2963 | 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 | |
| 2902 | 2966 | field_type.abiAlignment(zcu).toByteUnits().?); |
| 2903 | 2967 | } |
| 2904 | 2968 | if (has_comptime_state) |
| ... | ... | @@ -2906,7 +2970,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2906 | 2970 | else if (has_runtime_bits) |
| 2907 | 2971 | try wip_nav.blockValue(nav_src_loc, .fromInterned(field_init)); |
| 2908 | 2972 | } |
| 2909 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 2973 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 2910 | 2974 | } |
| 2911 | 2975 | }, |
| 2912 | 2976 | .@"packed" => { |
| ... | ... | @@ -2922,10 +2986,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2922 | 2986 | try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip)); |
| 2923 | 2987 | const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]); |
| 2924 | 2988 | try wip_nav.refType(field_type); |
| 2925 | try uleb128(diw, field_bit_offset); | |
| 2989 | try dibw.writeLeb128(field_bit_offset); | |
| 2926 | 2990 | field_bit_offset += @intCast(field_type.bitSize(zcu)); |
| 2927 | 2991 | } |
| 2928 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 2992 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 2929 | 2993 | }, |
| 2930 | 2994 | } |
| 2931 | 2995 | break :tag .done; |
| ... | ... | @@ -2948,7 +3012,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2948 | 3012 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 2949 | 3013 | } |
| 2950 | 3014 | 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; | |
| 2952 | 3016 | try wip_nav.declCommon(if (loaded_enum.names.len > 0) .{ |
| 2953 | 3017 | .decl = .decl_enum, |
| 2954 | 3018 | .generic_decl = .generic_decl_const, |
| ... | ... | @@ -2967,7 +3031,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2967 | 3031 | }, field_index); |
| 2968 | 3032 | try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip)); |
| 2969 | 3033 | } |
| 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)); | |
| 2971 | 3035 | break :tag .done; |
| 2972 | 3036 | }, |
| 2973 | 3037 | .union_type => tag: { |
| ... | ... | @@ -2987,15 +3051,15 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2987 | 3051 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 2988 | 3052 | } |
| 2989 | 3053 | 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; | |
| 2991 | 3055 | try wip_nav.declCommon(.{ |
| 2992 | 3056 | .decl = .decl_union, |
| 2993 | 3057 | .generic_decl = .generic_decl_const, |
| 2994 | 3058 | .decl_instance = .decl_instance_union, |
| 2995 | 3059 | }, &nav, inst_info.file, &decl); |
| 2996 | 3060 | 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().?); | |
| 2999 | 3063 | const loaded_tag = loaded_union.loadTagType(ip); |
| 3000 | 3064 | if (loaded_union.hasTag(ip)) { |
| 3001 | 3065 | try wip_nav.abbrevCode(.tagged_union); |
| ... | ... | @@ -3003,13 +3067,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3003 | 3067 | .debug_info, |
| 3004 | 3068 | wip_nav.unit, |
| 3005 | 3069 | wip_nav.entry, |
| 3006 | @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), | |
| 3070 | @intCast(dibw.count + dwarf.sectionOffsetBytes()), | |
| 3007 | 3071 | ); |
| 3008 | 3072 | { |
| 3009 | 3073 | try wip_nav.abbrevCode(.generated_field); |
| 3010 | 3074 | try wip_nav.strp("tag"); |
| 3011 | 3075 | try wip_nav.refType(.fromInterned(loaded_union.enum_tag_ty)); |
| 3012 | try uleb128(diw, union_layout.tagOffset()); | |
| 3076 | try dibw.writeLeb128(union_layout.tagOffset()); | |
| 3013 | 3077 | |
| 3014 | 3078 | for (0..loaded_union.field_types.len) |field_index| { |
| 3015 | 3079 | try wip_nav.enumConstValue(loaded_tag, .{ |
| ... | ... | @@ -3022,23 +3086,23 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3022 | 3086 | try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); |
| 3023 | 3087 | const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 3024 | 3088 | 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 | |
| 3027 | 3091 | if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?); |
| 3028 | 3092 | } |
| 3029 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3093 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3030 | 3094 | } |
| 3031 | 3095 | } |
| 3032 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3096 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3033 | 3097 | } else for (0..loaded_union.field_types.len) |field_index| { |
| 3034 | 3098 | try wip_nav.abbrevCode(.untagged_union_field); |
| 3035 | 3099 | try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); |
| 3036 | 3100 | const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]); |
| 3037 | 3101 | 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 | |
| 3039 | 3103 | field_type.abiAlignment(zcu).toByteUnits().?); |
| 3040 | 3104 | } |
| 3041 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3105 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3042 | 3106 | break :tag .done; |
| 3043 | 3107 | }, |
| 3044 | 3108 | .opaque_type => tag: { |
| ... | ... | @@ -3058,13 +3122,13 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3058 | 3122 | type_gop.value_ptr.* = nav_gop.value_ptr.*; |
| 3059 | 3123 | } |
| 3060 | 3124 | 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; | |
| 3062 | 3126 | try wip_nav.declCommon(.{ |
| 3063 | 3127 | .decl = .decl_namespace_struct, |
| 3064 | 3128 | .generic_decl = .generic_decl_const, |
| 3065 | 3129 | .decl_instance = .decl_instance_namespace_struct, |
| 3066 | 3130 | }, &nav, inst_info.file, &decl); |
| 3067 | try diw.writeByte(@intFromBool(true)); | |
| 3131 | try dibw.writeByte(@intFromBool(true)); | |
| 3068 | 3132 | break :tag .done; |
| 3069 | 3133 | }, |
| 3070 | 3134 | .undef, |
| ... | ... | @@ -3102,7 +3166,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3102 | 3166 | const is_nullary = !func_type.is_var_args and for (0..func_type.param_types.len) |param_index| { |
| 3103 | 3167 | if (!func_type.paramIsComptime(std.math.cast(u5, param_index) orelse break false)) break false; |
| 3104 | 3168 | } else true; |
| 3105 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 3169 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 3106 | 3170 | try wip_nav.declCommon(if (is_nullary) .{ |
| 3107 | 3171 | .decl = .decl_nullary_func_generic, |
| 3108 | 3172 | .generic_decl = .generic_decl_func, |
| ... | ... | @@ -3121,7 +3185,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3121 | 3185 | try wip_nav.refType(.fromInterned(func_type.param_types.get(ip)[param_index])); |
| 3122 | 3186 | } |
| 3123 | 3187 | 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)); | |
| 3125 | 3189 | } |
| 3126 | 3190 | break :tag .done; |
| 3127 | 3191 | }, |
| ... | ... | @@ -3146,7 +3210,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3146 | 3210 | try wip_nav.refType(nav_val.toType()); |
| 3147 | 3211 | }, |
| 3148 | 3212 | .decl_var => { |
| 3149 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 3213 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 3150 | 3214 | try wip_nav.declCommon(.{ |
| 3151 | 3215 | .decl = .decl_var, |
| 3152 | 3216 | .generic_decl = .generic_decl_var, |
| ... | ... | @@ -3156,12 +3220,12 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3156 | 3220 | const nav_ty = nav_val.typeOf(zcu); |
| 3157 | 3221 | try wip_nav.refType(nav_ty); |
| 3158 | 3222 | 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 | |
| 3160 | 3224 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3161 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 3225 | try dibw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 3162 | 3226 | }, |
| 3163 | 3227 | .decl_const => { |
| 3164 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 3228 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 3165 | 3229 | const nav_ty = nav_val.typeOf(zcu); |
| 3166 | 3230 | const has_runtime_bits = nav_ty.hasRuntimeBits(zcu); |
| 3167 | 3231 | 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 |
| 3184 | 3248 | }, &nav, inst_info.file, &decl); |
| 3185 | 3249 | try wip_nav.strp(nav.fqn.toSlice(ip)); |
| 3186 | 3250 | 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 | |
| 3188 | 3252 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3189 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 3253 | try dibw.writeByte(@intFromBool(decl.linkage != .normal)); | |
| 3190 | 3254 | if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val); |
| 3191 | 3255 | if (has_comptime_state) try wip_nav.refValue(nav_val); |
| 3192 | 3256 | wip_nav.finishForward(nav_ty_reloc_index); |
| ... | ... | @@ -3202,7 +3266,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3202 | 3266 | try wip_nav.refNav(owner_nav); |
| 3203 | 3267 | }, |
| 3204 | 3268 | } |
| 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()); | |
| 3206 | 3270 | try wip_nav.updateLazy(nav_src_loc); |
| 3207 | 3271 | } |
| 3208 | 3272 | |
| ... | ... | @@ -3212,14 +3276,14 @@ fn updateLazyType( |
| 3212 | 3276 | src_loc: Zcu.LazySrcLoc, |
| 3213 | 3277 | type_index: InternPool.Index, |
| 3214 | 3278 | pending_lazy: *WipNav.PendingLazy, |
| 3215 | ) UpdateError!void { | |
| 3279 | ) anyerror!void { | |
| 3216 | 3280 | const zcu = pt.zcu; |
| 3217 | 3281 | const ip = &zcu.intern_pool; |
| 3218 | 3282 | assert(ip.typeOf(type_index) == .type_type); |
| 3219 | 3283 | const ty: Type = .fromInterned(type_index); |
| 3220 | 3284 | switch (type_index) { |
| 3221 | 3285 | .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)}), | |
| 3223 | 3287 | } |
| 3224 | 3288 | |
| 3225 | 3289 | var wip_nav: WipNav = .{ |
| ... | ... | @@ -3233,21 +3297,22 @@ fn updateLazyType( |
| 3233 | 3297 | .func_high_pc = undefined, |
| 3234 | 3298 | .blocks = undefined, |
| 3235 | 3299 | .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, | |
| 3240 | 3304 | .pending_lazy = pending_lazy.*, |
| 3241 | 3305 | }; |
| 3306 | wip_nav.init(); | |
| 3242 | 3307 | defer { |
| 3243 | 3308 | pending_lazy.* = wip_nav.pending_lazy; |
| 3244 | 3309 | wip_nav.pending_lazy = .empty; |
| 3245 | 3310 | wip_nav.deinit(); |
| 3246 | 3311 | } |
| 3247 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 3312 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 3248 | 3313 | const name = switch (type_index) { |
| 3249 | 3314 | .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)}), | |
| 3251 | 3316 | }; |
| 3252 | 3317 | defer dwarf.gpa.free(name); |
| 3253 | 3318 | |
| ... | ... | @@ -3259,12 +3324,12 @@ fn updateLazyType( |
| 3259 | 3324 | .int_type => |int_type| { |
| 3260 | 3325 | try wip_nav.abbrevCode(.numeric_type); |
| 3261 | 3326 | try wip_nav.strp(name); |
| 3262 | try diw.writeByte(switch (int_type.signedness) { | |
| 3327 | try dibw.writeByte(switch (int_type.signedness) { | |
| 3263 | 3328 | inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)), |
| 3264 | 3329 | }); |
| 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().?); | |
| 3268 | 3333 | }, |
| 3269 | 3334 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 3270 | 3335 | .one, .many, .c => { |
| ... | ... | @@ -3272,14 +3337,14 @@ fn updateLazyType( |
| 3272 | 3337 | try wip_nav.abbrevCode(if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type); |
| 3273 | 3338 | try wip_nav.strp(name); |
| 3274 | 3339 | 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 | |
| 3276 | 3341 | 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)); | |
| 3278 | 3343 | if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset( |
| 3279 | 3344 | .debug_info, |
| 3280 | 3345 | wip_nav.unit, |
| 3281 | 3346 | wip_nav.entry, |
| 3282 | @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), | |
| 3347 | @intCast(dibw.count + dwarf.sectionOffsetBytes()), | |
| 3283 | 3348 | ) else try wip_nav.refType(ptr_child_type); |
| 3284 | 3349 | if (ptr_type.flags.is_const) { |
| 3285 | 3350 | try wip_nav.abbrevCode(.is_const); |
| ... | ... | @@ -3287,7 +3352,7 @@ fn updateLazyType( |
| 3287 | 3352 | .debug_info, |
| 3288 | 3353 | wip_nav.unit, |
| 3289 | 3354 | wip_nav.entry, |
| 3290 | @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), | |
| 3355 | @intCast(dibw.count + dwarf.sectionOffsetBytes()), | |
| 3291 | 3356 | ) else try wip_nav.refType(ptr_child_type); |
| 3292 | 3357 | } |
| 3293 | 3358 | if (ptr_type.flags.is_volatile) { |
| ... | ... | @@ -3298,19 +3363,19 @@ fn updateLazyType( |
| 3298 | 3363 | .slice => { |
| 3299 | 3364 | try wip_nav.abbrevCode(.generated_struct_type); |
| 3300 | 3365 | 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().?); | |
| 3303 | 3368 | try wip_nav.abbrevCode(.generated_field); |
| 3304 | 3369 | try wip_nav.strp("ptr"); |
| 3305 | 3370 | const ptr_field_type = ty.slicePtrFieldType(zcu); |
| 3306 | 3371 | try wip_nav.refType(ptr_field_type); |
| 3307 | try uleb128(diw, 0); | |
| 3372 | try dibw.writeUleb128(0); | |
| 3308 | 3373 | try wip_nav.abbrevCode(.generated_field); |
| 3309 | 3374 | try wip_nav.strp("len"); |
| 3310 | 3375 | const len_field_type: Type = .usize; |
| 3311 | 3376 | 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)); | |
| 3314 | 3379 | }, |
| 3315 | 3380 | }, |
| 3316 | 3381 | .array_type => |array_type| { |
| ... | ... | @@ -3321,8 +3386,8 @@ fn updateLazyType( |
| 3321 | 3386 | try wip_nav.refType(array_child_type); |
| 3322 | 3387 | try wip_nav.abbrevCode(.array_index); |
| 3323 | 3388 | 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)); | |
| 3326 | 3391 | }, |
| 3327 | 3392 | .vector_type => |vector_type| { |
| 3328 | 3393 | try wip_nav.abbrevCode(.vector_type); |
| ... | ... | @@ -3330,22 +3395,22 @@ fn updateLazyType( |
| 3330 | 3395 | try wip_nav.refType(.fromInterned(vector_type.child)); |
| 3331 | 3396 | try wip_nav.abbrevCode(.array_index); |
| 3332 | 3397 | 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)); | |
| 3335 | 3400 | }, |
| 3336 | 3401 | .opt_type => |opt_child_type_index| { |
| 3337 | 3402 | const opt_child_type: Type = .fromInterned(opt_child_type_index); |
| 3338 | 3403 | const opt_repr = optRepr(opt_child_type, zcu); |
| 3339 | 3404 | try wip_nav.abbrevCode(.generated_union_type); |
| 3340 | 3405 | 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().?); | |
| 3343 | 3408 | switch (opt_repr) { |
| 3344 | 3409 | .opv_null => { |
| 3345 | 3410 | try wip_nav.abbrevCode(.generated_field); |
| 3346 | 3411 | try wip_nav.strp("null"); |
| 3347 | 3412 | try wip_nav.refType(.null); |
| 3348 | try uleb128(diw, 0); | |
| 3413 | try dibw.writeUleb128(0); | |
| 3349 | 3414 | }, |
| 3350 | 3415 | .unpacked, .error_set, .pointer => { |
| 3351 | 3416 | try wip_nav.abbrevCode(.tagged_union); |
| ... | ... | @@ -3353,7 +3418,7 @@ fn updateLazyType( |
| 3353 | 3418 | .debug_info, |
| 3354 | 3419 | wip_nav.unit, |
| 3355 | 3420 | wip_nav.entry, |
| 3356 | @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), | |
| 3421 | @intCast(dibw.count + dwarf.sectionOffsetBytes()), | |
| 3357 | 3422 | ); |
| 3358 | 3423 | { |
| 3359 | 3424 | try wip_nav.abbrevCode(.generated_field); |
| ... | ... | @@ -3362,7 +3427,7 @@ fn updateLazyType( |
| 3362 | 3427 | .opv_null => unreachable, |
| 3363 | 3428 | .unpacked => { |
| 3364 | 3429 | 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)) | |
| 3366 | 3431 | opt_child_type.abiSize(zcu) |
| 3367 | 3432 | else |
| 3368 | 3433 | 0); |
| ... | ... | @@ -3372,37 +3437,37 @@ fn updateLazyType( |
| 3372 | 3437 | .signedness = .unsigned, |
| 3373 | 3438 | .bits = zcu.errorSetBits(), |
| 3374 | 3439 | } }))); |
| 3375 | try uleb128(diw, 0); | |
| 3440 | try dibw.writeUleb128(0); | |
| 3376 | 3441 | }, |
| 3377 | 3442 | .pointer => { |
| 3378 | 3443 | try wip_nav.refType(.usize); |
| 3379 | try uleb128(diw, 0); | |
| 3444 | try dibw.writeUleb128(0); | |
| 3380 | 3445 | }, |
| 3381 | 3446 | } |
| 3382 | 3447 | |
| 3383 | 3448 | try wip_nav.abbrevCode(.unsigned_tagged_union_field); |
| 3384 | try uleb128(diw, 0); | |
| 3449 | try dibw.writeUleb128(0); | |
| 3385 | 3450 | { |
| 3386 | 3451 | try wip_nav.abbrevCode(.generated_field); |
| 3387 | 3452 | try wip_nav.strp("null"); |
| 3388 | 3453 | try wip_nav.refType(.null); |
| 3389 | try uleb128(diw, 0); | |
| 3454 | try dibw.writeUleb128(0); | |
| 3390 | 3455 | } |
| 3391 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3456 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3392 | 3457 | |
| 3393 | 3458 | try wip_nav.abbrevCode(.tagged_union_default_field); |
| 3394 | 3459 | { |
| 3395 | 3460 | try wip_nav.abbrevCode(.generated_field); |
| 3396 | 3461 | try wip_nav.strp("?"); |
| 3397 | 3462 | try wip_nav.refType(opt_child_type); |
| 3398 | try uleb128(diw, 0); | |
| 3463 | try dibw.writeUleb128(0); | |
| 3399 | 3464 | } |
| 3400 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3465 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3401 | 3466 | } |
| 3402 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3467 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3403 | 3468 | }, |
| 3404 | 3469 | } |
| 3405 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3470 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3406 | 3471 | }, |
| 3407 | 3472 | .anyframe_type => unreachable, |
| 3408 | 3473 | .error_union_type => |error_union_type| { |
| ... | ... | @@ -3421,11 +3486,11 @@ fn updateLazyType( |
| 3421 | 3486 | if (error_union_type.error_set_type != .generic_poison_type and |
| 3422 | 3487 | error_union_type.payload_type != .generic_poison_type) |
| 3423 | 3488 | { |
| 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().?); | |
| 3426 | 3491 | } else { |
| 3427 | try uleb128(diw, 0); | |
| 3428 | try uleb128(diw, 1); | |
| 3492 | try dibw.writeUleb128(0); | |
| 3493 | try dibw.writeUleb128(1); | |
| 3429 | 3494 | } |
| 3430 | 3495 | { |
| 3431 | 3496 | try wip_nav.abbrevCode(.tagged_union); |
| ... | ... | @@ -3433,7 +3498,7 @@ fn updateLazyType( |
| 3433 | 3498 | .debug_info, |
| 3434 | 3499 | wip_nav.unit, |
| 3435 | 3500 | wip_nav.entry, |
| 3436 | @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), | |
| 3501 | @intCast(dibw.count + dwarf.sectionOffsetBytes()), | |
| 3437 | 3502 | ); |
| 3438 | 3503 | { |
| 3439 | 3504 | try wip_nav.abbrevCode(.generated_field); |
| ... | ... | @@ -3442,30 +3507,30 @@ fn updateLazyType( |
| 3442 | 3507 | .signedness = .unsigned, |
| 3443 | 3508 | .bits = zcu.errorSetBits(), |
| 3444 | 3509 | } }))); |
| 3445 | try uleb128(diw, error_union_error_set_offset); | |
| 3510 | try dibw.writeLeb128(error_union_error_set_offset); | |
| 3446 | 3511 | |
| 3447 | 3512 | try wip_nav.abbrevCode(.unsigned_tagged_union_field); |
| 3448 | try uleb128(diw, 0); | |
| 3513 | try dibw.writeUleb128(0); | |
| 3449 | 3514 | { |
| 3450 | 3515 | try wip_nav.abbrevCode(.generated_field); |
| 3451 | 3516 | try wip_nav.strp("value"); |
| 3452 | 3517 | try wip_nav.refType(error_union_payload_type); |
| 3453 | try uleb128(diw, error_union_payload_offset); | |
| 3518 | try dibw.writeLeb128(error_union_payload_offset); | |
| 3454 | 3519 | } |
| 3455 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3520 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3456 | 3521 | |
| 3457 | 3522 | try wip_nav.abbrevCode(.tagged_union_default_field); |
| 3458 | 3523 | { |
| 3459 | 3524 | try wip_nav.abbrevCode(.generated_field); |
| 3460 | 3525 | try wip_nav.strp("error"); |
| 3461 | 3526 | 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); | |
| 3463 | 3528 | } |
| 3464 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3529 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3465 | 3530 | } |
| 3466 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3531 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3467 | 3532 | } |
| 3468 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3533 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3469 | 3534 | }, |
| 3470 | 3535 | .simple_type => |simple_type| switch (simple_type) { |
| 3471 | 3536 | .f16, |
| ... | ... | @@ -3489,7 +3554,7 @@ fn updateLazyType( |
| 3489 | 3554 | => { |
| 3490 | 3555 | try wip_nav.abbrevCode(.numeric_type); |
| 3491 | 3556 | try wip_nav.strp(name); |
| 3492 | try diw.writeByte(if (type_index == .bool_type) | |
| 3557 | try dibw.writeByte(if (type_index == .bool_type) | |
| 3493 | 3558 | DW.ATE.boolean |
| 3494 | 3559 | else if (ty.isRuntimeFloat()) |
| 3495 | 3560 | DW.ATE.float |
| ... | ... | @@ -3499,9 +3564,9 @@ fn updateLazyType( |
| 3499 | 3564 | DW.ATE.unsigned |
| 3500 | 3565 | else |
| 3501 | 3566 | 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().?); | |
| 3505 | 3570 | }, |
| 3506 | 3571 | .anyopaque, |
| 3507 | 3572 | .void, |
| ... | ... | @@ -3527,12 +3592,12 @@ fn updateLazyType( |
| 3527 | 3592 | .tuple_type => |tuple_type| if (tuple_type.types.len == 0) { |
| 3528 | 3593 | try wip_nav.abbrevCode(.generated_empty_struct_type); |
| 3529 | 3594 | try wip_nav.strp(name); |
| 3530 | try diw.writeByte(@intFromBool(false)); | |
| 3595 | try dibw.writeByte(@intFromBool(false)); | |
| 3531 | 3596 | } else { |
| 3532 | 3597 | try wip_nav.abbrevCode(.generated_struct_type); |
| 3533 | 3598 | 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().?); | |
| 3536 | 3601 | var field_byte_offset: u64 = 0; |
| 3537 | 3602 | for (0..tuple_type.types.len) |field_index| { |
| 3538 | 3603 | const comptime_value = tuple_type.values.get(ip)[field_index]; |
| ... | ... | @@ -3561,8 +3626,8 @@ fn updateLazyType( |
| 3561 | 3626 | if (comptime_value == .none) { |
| 3562 | 3627 | const field_align = field_type.abiAlignment(zcu); |
| 3563 | 3628 | 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().?); | |
| 3566 | 3631 | field_byte_offset += field_type.abiSize(zcu); |
| 3567 | 3632 | } |
| 3568 | 3633 | if (has_comptime_state) |
| ... | ... | @@ -3570,7 +3635,7 @@ fn updateLazyType( |
| 3570 | 3635 | else if (has_runtime_bits) |
| 3571 | 3636 | try wip_nav.blockValue(src_loc, .fromInterned(comptime_value)); |
| 3572 | 3637 | } |
| 3573 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3638 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3574 | 3639 | }, |
| 3575 | 3640 | .enum_type => { |
| 3576 | 3641 | const loaded_enum = ip.loadEnumType(type_index); |
| ... | ... | @@ -3585,7 +3650,7 @@ fn updateLazyType( |
| 3585 | 3650 | }, field_index); |
| 3586 | 3651 | try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip)); |
| 3587 | 3652 | } |
| 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)); | |
| 3589 | 3654 | }, |
| 3590 | 3655 | .func_type => |func_type| { |
| 3591 | 3656 | const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args; |
| ... | ... | @@ -3653,7 +3718,7 @@ fn updateLazyType( |
| 3653 | 3718 | else => .nocall, |
| 3654 | 3719 | }; |
| 3655 | 3720 | }; |
| 3656 | try diw.writeByte(@intFromEnum(cc)); | |
| 3721 | try dibw.writeByte(@intFromEnum(cc)); | |
| 3657 | 3722 | try wip_nav.refType(.fromInterned(func_type.return_type)); |
| 3658 | 3723 | if (!is_nullary) { |
| 3659 | 3724 | for (0..func_type.param_types.len) |param_index| { |
| ... | ... | @@ -3661,7 +3726,7 @@ fn updateLazyType( |
| 3661 | 3726 | try wip_nav.refType(.fromInterned(func_type.param_types.get(ip)[param_index])); |
| 3662 | 3727 | } |
| 3663 | 3728 | 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)); | |
| 3665 | 3730 | } |
| 3666 | 3731 | }, |
| 3667 | 3732 | .error_set_type => |error_set_type| { |
| ... | ... | @@ -3674,10 +3739,10 @@ fn updateLazyType( |
| 3674 | 3739 | for (0..error_set_type.names.len) |field_index| { |
| 3675 | 3740 | const field_name = error_set_type.names.get(ip)[field_index]; |
| 3676 | 3741 | try wip_nav.abbrevCode(.unsigned_enum_field); |
| 3677 | try uleb128(diw, ip.getErrorValueIfExists(field_name).?); | |
| 3742 | try dibw.writeLeb128(ip.getErrorValueIfExists(field_name).?); | |
| 3678 | 3743 | try wip_nav.strp(field_name.toSlice(ip)); |
| 3679 | 3744 | } |
| 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)); | |
| 3681 | 3746 | }, |
| 3682 | 3747 | .inferred_error_set_type => |func| { |
| 3683 | 3748 | try wip_nav.abbrevCode(.inferred_error_set_type); |
| ... | ... | @@ -3709,7 +3774,7 @@ fn updateLazyType( |
| 3709 | 3774 | .memoized_call, |
| 3710 | 3775 | => unreachable, |
| 3711 | 3776 | } |
| 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()); | |
| 3713 | 3778 | } |
| 3714 | 3779 | |
| 3715 | 3780 | fn updateLazyValue( |
| ... | ... | @@ -3718,11 +3783,11 @@ fn updateLazyValue( |
| 3718 | 3783 | src_loc: Zcu.LazySrcLoc, |
| 3719 | 3784 | value_index: InternPool.Index, |
| 3720 | 3785 | pending_lazy: *WipNav.PendingLazy, |
| 3721 | ) UpdateError!void { | |
| 3786 | ) anyerror!void { | |
| 3722 | 3787 | const zcu = pt.zcu; |
| 3723 | 3788 | const ip = &zcu.intern_pool; |
| 3724 | 3789 | assert(ip.typeOf(value_index) != .type_type); |
| 3725 | log.debug("updateLazyValue(@as({}, {}))", .{ | |
| 3790 | log.debug("updateLazyValue(@as({f}, {f}))", .{ | |
| 3726 | 3791 | Value.fromInterned(value_index).typeOf(zcu).fmt(pt), |
| 3727 | 3792 | Value.fromInterned(value_index).fmtValue(pt), |
| 3728 | 3793 | }); |
| ... | ... | @@ -3737,18 +3802,19 @@ fn updateLazyValue( |
| 3737 | 3802 | .func_high_pc = undefined, |
| 3738 | 3803 | .blocks = undefined, |
| 3739 | 3804 | .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, | |
| 3744 | 3809 | .pending_lazy = pending_lazy.*, |
| 3745 | 3810 | }; |
| 3811 | wip_nav.init(); | |
| 3746 | 3812 | defer { |
| 3747 | 3813 | pending_lazy.* = wip_nav.pending_lazy; |
| 3748 | 3814 | wip_nav.pending_lazy = .empty; |
| 3749 | 3815 | wip_nav.deinit(); |
| 3750 | 3816 | } |
| 3751 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 3817 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 3752 | 3818 | var big_int_space: Value.BigIntSpace = undefined; |
| 3753 | 3819 | switch (ip.indexToKey(value_index)) { |
| 3754 | 3820 | .int_type, |
| ... | ... | @@ -3786,7 +3852,7 @@ fn updateLazyValue( |
| 3786 | 3852 | .err => |err| { |
| 3787 | 3853 | try wip_nav.abbrevCode(.udata_comptime_value); |
| 3788 | 3854 | 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)); | |
| 3790 | 3856 | }, |
| 3791 | 3857 | .error_union => |error_union| { |
| 3792 | 3858 | try wip_nav.abbrevCode(.aggregate_comptime_value); |
| ... | ... | @@ -3798,8 +3864,8 @@ fn updateLazyValue( |
| 3798 | 3864 | { |
| 3799 | 3865 | try wip_nav.abbrevCode(.comptime_value_field_runtime_bits); |
| 3800 | 3866 | 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); | |
| 3803 | 3869 | } |
| 3804 | 3870 | payload_field: switch (error_union.val) { |
| 3805 | 3871 | .err_name => {}, |
| ... | ... | @@ -3823,8 +3889,8 @@ fn updateLazyValue( |
| 3823 | 3889 | { |
| 3824 | 3890 | try wip_nav.abbrevCode(.comptime_value_field_runtime_bits); |
| 3825 | 3891 | 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); | |
| 3828 | 3894 | } |
| 3829 | 3895 | switch (error_union.val) { |
| 3830 | 3896 | .err_name => {}, |
| ... | ... | @@ -3834,7 +3900,7 @@ fn updateLazyValue( |
| 3834 | 3900 | }, |
| 3835 | 3901 | } |
| 3836 | 3902 | try wip_nav.refType(.fromInterned(error_union.ty)); |
| 3837 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 3903 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3838 | 3904 | }, |
| 3839 | 3905 | .enum_literal => |enum_literal| { |
| 3840 | 3906 | try wip_nav.abbrevCode(.string_comptime_value); |
| ... | ... | @@ -3855,24 +3921,24 @@ fn updateLazyValue( |
| 3855 | 3921 | switch (float.storage) { |
| 3856 | 3922 | .f16 => |f16_val| { |
| 3857 | 3923 | 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); | |
| 3859 | 3925 | }, |
| 3860 | 3926 | .f32 => |f32_val| { |
| 3861 | 3927 | 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); | |
| 3863 | 3929 | }, |
| 3864 | 3930 | .f64 => |f64_val| { |
| 3865 | 3931 | 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); | |
| 3867 | 3933 | }, |
| 3868 | 3934 | .f80 => |f80_val| { |
| 3869 | 3935 | 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); | |
| 3872 | 3938 | }, |
| 3873 | 3939 | .f128 => |f128_val| { |
| 3874 | 3940 | 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); | |
| 3876 | 3942 | }, |
| 3877 | 3943 | } |
| 3878 | 3944 | try wip_nav.refType(.fromInterned(float.ty)); |
| ... | ... | @@ -3889,14 +3955,14 @@ fn updateLazyValue( |
| 3889 | 3955 | const uav_ty: Type = .fromInterned(ip.typeOf(uav.val)); |
| 3890 | 3956 | if (try uav_ty.onePossibleValue(pt)) |_| { |
| 3891 | 3957 | 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 | |
| 3893 | 3959 | uav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3894 | 3960 | break :location; |
| 3895 | 3961 | } else break try wip_nav.getValueEntry(.fromInterned(uav.val)); |
| 3896 | 3962 | }, |
| 3897 | 3963 | .int => { |
| 3898 | 3964 | try wip_nav.abbrevCode(.udata_comptime_value); |
| 3899 | try uleb128(diw, byte_offset); | |
| 3965 | try dibw.writeLeb128(byte_offset); | |
| 3900 | 3966 | break :location; |
| 3901 | 3967 | }, |
| 3902 | 3968 | .eu_payload => |eu_ptr| { |
| ... | ... | @@ -3935,7 +4001,7 @@ fn updateLazyValue( |
| 3935 | 4001 | try wip_nav.strp("len"); |
| 3936 | 4002 | try wip_nav.blockValue(src_loc, .fromInterned(slice.len)); |
| 3937 | 4003 | } |
| 3938 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 4004 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3939 | 4005 | }, |
| 3940 | 4006 | .opt => |opt| { |
| 3941 | 4007 | const opt_child_type: Type = .fromInterned(ip.indexToKey(opt.ty).opt_type); |
| ... | ... | @@ -3945,7 +4011,7 @@ fn updateLazyValue( |
| 3945 | 4011 | try wip_nav.abbrevCode(.comptime_value_field_runtime_bits); |
| 3946 | 4012 | try wip_nav.strp("has_value"); |
| 3947 | 4013 | switch (optRepr(opt_child_type, zcu)) { |
| 3948 | .opv_null => try uleb128(diw, 0), | |
| 4014 | .opv_null => try dibw.writeUleb128(0), | |
| 3949 | 4015 | .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)), |
| 3950 | 4016 | .error_set => try wip_nav.blockValue(src_loc, .fromInterned(value_index)), |
| 3951 | 4017 | .pointer => if (opt_child_type.comptimeOnly(zcu)) { |
| ... | ... | @@ -3955,8 +4021,8 @@ fn updateLazyValue( |
| 3955 | 4021 | .none => 0, |
| 3956 | 4022 | else => opt_child_type.ptrAlignment(zcu).toByteUnits().?, |
| 3957 | 4023 | }); |
| 3958 | try uleb128(diw, bytes.len); | |
| 3959 | try diw.writeAll(bytes); | |
| 4024 | try dibw.writeLeb128(bytes.len); | |
| 4025 | try dibw.writeAll(bytes); | |
| 3960 | 4026 | } else try wip_nav.blockValue(src_loc, .fromInterned(value_index)), |
| 3961 | 4027 | } |
| 3962 | 4028 | } |
| ... | ... | @@ -3975,7 +4041,7 @@ fn updateLazyValue( |
| 3975 | 4041 | else |
| 3976 | 4042 | try wip_nav.blockValue(src_loc, .fromInterned(opt.val)); |
| 3977 | 4043 | } |
| 3978 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 4044 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 3979 | 4045 | }, |
| 3980 | 4046 | .aggregate => |aggregate| { |
| 3981 | 4047 | try wip_nav.abbrevCode(.aggregate_comptime_value); |
| ... | ... | @@ -4060,7 +4126,7 @@ fn updateLazyValue( |
| 4060 | 4126 | }, |
| 4061 | 4127 | else => unreachable, |
| 4062 | 4128 | } |
| 4063 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 4129 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 4064 | 4130 | }, |
| 4065 | 4131 | .un => |un| { |
| 4066 | 4132 | try wip_nav.abbrevCode(.aggregate_comptime_value); |
| ... | ... | @@ -4085,11 +4151,11 @@ fn updateLazyValue( |
| 4085 | 4151 | else |
| 4086 | 4152 | try wip_nav.blockValue(src_loc, .fromInterned(un.val)); |
| 4087 | 4153 | } |
| 4088 | try uleb128(diw, @intFromEnum(AbbrevCode.null)); | |
| 4154 | try dibw.writeLeb128(@intFromEnum(AbbrevCode.null)); | |
| 4089 | 4155 | }, |
| 4090 | 4156 | .memoized_call => unreachable, // not a value |
| 4091 | 4157 | } |
| 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()); | |
| 4093 | 4159 | } |
| 4094 | 4160 | |
| 4095 | 4161 | fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { |
| ... | ... | @@ -4109,12 +4175,12 @@ fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { |
| 4109 | 4175 | }; |
| 4110 | 4176 | } |
| 4111 | 4177 | |
| 4112 | pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternPool.Index) UpdateError!void { | |
| 4178 | fn updateContainerTypeInner(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternPool.Index) anyerror!void { | |
| 4113 | 4179 | const zcu = pt.zcu; |
| 4114 | 4180 | const ip = &zcu.intern_pool; |
| 4115 | 4181 | const ty: Type = .fromInterned(type_index); |
| 4116 | 4182 | const ty_src_loc = ty.srcLoc(zcu); |
| 4117 | log.debug("updateContainerType({})", .{ty.fmt(pt)}); | |
| 4183 | log.debug("updateContainerType({f})", .{ty.fmt(pt)}); | |
| 4118 | 4184 | |
| 4119 | 4185 | const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?; |
| 4120 | 4186 | const file = zcu.fileByIndex(inst_info.file); |
| ... | ... | @@ -4432,29 +4498,31 @@ pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void { |
| 4432 | 4498 | _ = nav_index; |
| 4433 | 4499 | } |
| 4434 | 4500 | |
| 4435 | fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(AbbrevCode).@"enum".tag_type { | |
| 4501 | fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) anyerror!@typeInfo(AbbrevCode).@"enum".tag_type { | |
| 4436 | 4502 | assert(abbrev_code != .null); |
| 4437 | 4503 | const entry: Entry.Index = @enumFromInt(@intFromEnum(abbrev_code)); |
| 4438 | 4504 | 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; | |
| 4442 | 4509 | 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()); | |
| 4449 | 4516 | return @intFromEnum(abbrev_code); |
| 4450 | 4517 | } |
| 4451 | 4518 | |
| 4452 | 4519 | pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4520 | const gpa = dwarf.gpa; | |
| 4453 | 4521 | const zcu = pt.zcu; |
| 4454 | 4522 | const ip = &zcu.intern_pool; |
| 4455 | 4523 | |
| 4456 | 4524 | { |
| 4457 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type); | |
| 4525 | const type_gop = try dwarf.types.getOrPut(gpa, .anyerror_type); | |
| 4458 | 4526 | if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main); |
| 4459 | 4527 | var wip_nav: WipNav = .{ |
| 4460 | 4528 | .dwarf = dwarf, |
| ... | ... | @@ -4467,14 +4535,15 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4467 | 4535 | .func_high_pc = undefined, |
| 4468 | 4536 | .blocks = undefined, |
| 4469 | 4537 | .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, | |
| 4474 | 4542 | .pending_lazy = .empty, |
| 4475 | 4543 | }; |
| 4544 | wip_nav.init(); | |
| 4476 | 4545 | defer wip_nav.deinit(); |
| 4477 | const diw = wip_nav.debug_info.writer(dwarf.gpa); | |
| 4546 | const dibw = &wip_nav.debug_info.buffered_writer; | |
| 4478 | 4547 | const global_error_set_names = ip.global_error_set.getNamesFromMainThread(); |
| 4479 | 4548 | try wip_nav.abbrevCode(if (global_error_set_names.len == 0) .generated_empty_enum_type else .generated_enum_type); |
| 4480 | 4549 | try wip_nav.strp("anyerror"); |
| ... | ... | @@ -4484,50 +4553,52 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4484 | 4553 | } }))); |
| 4485 | 4554 | for (global_error_set_names, 1..) |name, value| { |
| 4486 | 4555 | try wip_nav.abbrevCode(.unsigned_enum_field); |
| 4487 | try uleb128(diw, value); | |
| 4556 | try dibw.writeLeb128(value); | |
| 4488 | 4557 | try wip_nav.strp(name.toSlice(ip)); |
| 4489 | 4558 | } |
| 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()); | |
| 4492 | 4561 | try wip_nav.updateLazy(.unneeded); |
| 4493 | 4562 | } |
| 4494 | 4563 | |
| 4495 | 4564 | 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); | |
| 4498 | 4567 | mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path); |
| 4499 | 4568 | } |
| 4500 | 4569 | |
| 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; | |
| 4503 | 4573 | if (dwarf.debug_aranges.section.dirty) { |
| 4504 | 4574 | for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| { |
| 4505 | 4575 | const unit: Unit.Index = @enumFromInt(unit_index); |
| 4506 | 4576 | 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); | |
| 4510 | 4580 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| |
| 4511 | 4581 | dwarf.debug_aranges.section.getUnit(next_unit).off |
| 4512 | 4582 | else |
| 4513 | 4583 | dwarf.debug_aranges.section.len) - unit_ptr.off - dwarf.unitLengthBytes(); |
| 4514 | 4584 | 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, | |
| 4516 | 4586 | .@"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; | |
| 4519 | 4589 | }, |
| 4520 | 4590 | } |
| 4521 | std.mem.writeInt(u16, header.addManyAsArrayAssumeCapacity(2), 2, dwarf.endian); | |
| 4591 | header_bw.writeInt(u16, 2, dwarf.endian) catch unreachable; | |
| 4522 | 4592 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4523 | .source_off = @intCast(header.items.len), | |
| 4593 | .source_off = @intCast(header_bw.end), | |
| 4524 | 4594 | .target_sec = .debug_info, |
| 4525 | 4595 | .target_unit = unit, |
| 4526 | 4596 | }); |
| 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); | |
| 4531 | 4602 | try unit_ptr.writeTrailer(&dwarf.debug_aranges.section, dwarf); |
| 4532 | 4603 | } |
| 4533 | 4604 | dwarf.debug_aranges.section.dirty = false; |
| ... | ... | @@ -4542,31 +4613,33 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4542 | 4613 | dev.check(.x86_64_backend); |
| 4543 | 4614 | const Register = @import("../arch/x86_64/bits.zig").Register; |
| 4544 | 4615 | 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); | |
| 4547 | 4618 | const unit_len = unit.header_len - dwarf.unitLengthBytes(); |
| 4548 | 4619 | 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, | |
| 4550 | 4621 | .@"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; | |
| 4553 | 4624 | }, |
| 4554 | 4625 | } |
| 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); | |
| 4570 | 4643 | try unit.writeTrailer(&dwarf.debug_frame.section, dwarf); |
| 4571 | 4644 | } |
| 4572 | 4645 | }, |
| ... | ... | @@ -4579,83 +4652,84 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4579 | 4652 | for (dwarf.mods.keys(), dwarf.mods.values(), dwarf.debug_info.section.units.items, 0..) |mod, mod_info, *unit_ptr, unit_index| { |
| 4580 | 4653 | const unit: Unit.Index = @enumFromInt(unit_index); |
| 4581 | 4654 | 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); | |
| 4586 | 4659 | const unit_len = (if (unit_ptr.next.unwrap()) |next_unit| |
| 4587 | 4660 | dwarf.debug_info.section.getUnit(next_unit).off |
| 4588 | 4661 | else |
| 4589 | 4662 | dwarf.debug_info.section.len) - unit_ptr.off - dwarf.unitLengthBytes(); |
| 4590 | 4663 | 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, | |
| 4592 | 4665 | .@"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; | |
| 4595 | 4668 | }, |
| 4596 | 4669 | } |
| 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; | |
| 4599 | 4672 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4600 | .source_off = @intCast(header.items.len), | |
| 4673 | .source_off = @intCast(header_bw.end), | |
| 4601 | 4674 | .target_sec = .debug_abbrev, |
| 4602 | 4675 | .target_unit = DebugAbbrev.unit, |
| 4603 | 4676 | }); |
| 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; | |
| 4608 | 4681 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4609 | .source_off = @intCast(header.items.len), | |
| 4682 | .source_off = @intCast(header_bw.end), | |
| 4610 | 4683 | .target_sec = .debug_line_str, |
| 4611 | 4684 | .target_unit = StringSection.unit, |
| 4612 | 4685 | .target_entry = (try dwarf.debug_line_str.addString(dwarf, "zig " ++ @import("build_options").version)).toOptional(), |
| 4613 | 4686 | }); |
| 4614 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4687 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4615 | 4688 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4616 | .source_off = @intCast(header.items.len), | |
| 4689 | .source_off = @intCast(header_bw.end), | |
| 4617 | 4690 | .target_sec = .debug_line_str, |
| 4618 | 4691 | .target_unit = StringSection.unit, |
| 4619 | 4692 | .target_entry = mod_info.root_dir_path.toOptional(), |
| 4620 | 4693 | }); |
| 4621 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4694 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4622 | 4695 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4623 | .source_off = @intCast(header.items.len), | |
| 4696 | .source_off = @intCast(header_bw.end), | |
| 4624 | 4697 | .target_sec = .debug_line_str, |
| 4625 | 4698 | .target_unit = StringSection.unit, |
| 4626 | 4699 | .target_entry = (try dwarf.debug_line_str.addString(dwarf, mod.root_src_path)).toOptional(), |
| 4627 | 4700 | }); |
| 4628 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4701 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4629 | 4702 | unit_ptr.cross_unit_relocs.appendAssumeCapacity(.{ |
| 4630 | .source_off = @intCast(header.items.len), | |
| 4703 | .source_off = @intCast(header_bw.end), | |
| 4631 | 4704 | .target_unit = .main, |
| 4632 | 4705 | .target_off = compile_unit_off, |
| 4633 | 4706 | }); |
| 4634 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4707 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4635 | 4708 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4636 | .source_off = @intCast(header.items.len), | |
| 4709 | .source_off = @intCast(header_bw.end), | |
| 4637 | 4710 | .target_sec = .debug_line, |
| 4638 | 4711 | .target_unit = unit, |
| 4639 | 4712 | }); |
| 4640 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4713 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4641 | 4714 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4642 | .source_off = @intCast(header.items.len), | |
| 4715 | .source_off = @intCast(header_bw.end), | |
| 4643 | 4716 | .target_sec = .debug_rnglists, |
| 4644 | 4717 | .target_unit = unit, |
| 4645 | 4718 | .target_off = DebugRngLists.baseOffset(dwarf), |
| 4646 | 4719 | }); |
| 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; | |
| 4650 | 4723 | unit_ptr.cross_section_relocs.appendAssumeCapacity(.{ |
| 4651 | .source_off = @intCast(header.items.len), | |
| 4724 | .source_off = @intCast(header_bw.end), | |
| 4652 | 4725 | .target_sec = .debug_str, |
| 4653 | 4726 | .target_unit = StringSection.unit, |
| 4654 | 4727 | .target_entry = (try dwarf.debug_str.addString(dwarf, mod.fully_qualified_name)).toOptional(), |
| 4655 | 4728 | }); |
| 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); | |
| 4659 | 4733 | try unit_ptr.writeTrailer(&dwarf.debug_info.section, dwarf); |
| 4660 | 4734 | } |
| 4661 | 4735 | dwarf.debug_info.section.dirty = false; |
| ... | ... | @@ -4679,33 +4753,37 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4679 | 4753 | ); |
| 4680 | 4754 | for (dwarf.mods.values(), dwarf.debug_line.section.units.items) |mod_info, *unit| { |
| 4681 | 4755 | 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); | |
| 4685 | 4759 | const unit_len = (if (unit.next.unwrap()) |next_unit| |
| 4686 | 4760 | dwarf.debug_line.section.getUnit(next_unit).off |
| 4687 | 4761 | else |
| 4688 | 4762 | dwarf.debug_line.section.len) - unit.off - dwarf.unitLengthBytes(); |
| 4689 | 4763 | 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, | |
| 4691 | 4765 | .@"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; | |
| 4694 | 4768 | }, |
| 4695 | 4769 | } |
| 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; | |
| 4699 | 4777 | const StandardOpcode = DeclValEnum(DW.LNS); |
| 4700 | header.appendSliceAssumeCapacity(&[_]u8{ | |
| 4778 | header_bw.writeAll(&.{ | |
| 4701 | 4779 | dwarf.debug_line.header.minimum_instruction_length, |
| 4702 | 4780 | dwarf.debug_line.header.maximum_operations_per_instruction, |
| 4703 | 4781 | @intFromBool(dwarf.debug_line.header.default_is_stmt), |
| 4704 | 4782 | @bitCast(dwarf.debug_line.header.line_base), |
| 4705 | 4783 | dwarf.debug_line.header.line_range, |
| 4706 | 4784 | 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(.{ | |
| 4709 | 4787 | .extended_op = undefined, |
| 4710 | 4788 | .copy = 0, |
| 4711 | 4789 | .advance_pc = 1, |
| ... | ... | @@ -4719,44 +4797,45 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4719 | 4797 | .set_prologue_end = 0, |
| 4720 | 4798 | .set_epilogue_begin = 0, |
| 4721 | 4799 | .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; | |
| 4727 | 4805 | for (mod_info.dirs.keys()) |dir_unit| { |
| 4728 | 4806 | unit.cross_section_relocs.appendAssumeCapacity(.{ |
| 4729 | .source_off = @intCast(header.items.len), | |
| 4807 | .source_off = @intCast(header_bw.end), | |
| 4730 | 4808 | .target_sec = .debug_line_str, |
| 4731 | 4809 | .target_unit = StringSection.unit, |
| 4732 | 4810 | .target_entry = dwarf.getModInfo(dir_unit).root_dir_path.toOptional(), |
| 4733 | 4811 | }); |
| 4734 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4812 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4735 | 4813 | } |
| 4736 | 4814 | 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; | |
| 4745 | 4823 | for (mod_info.files.keys()) |file_index| { |
| 4746 | 4824 | const file = zcu.fileByIndex(file_index); |
| 4747 | 4825 | unit.cross_section_relocs.appendAssumeCapacity(.{ |
| 4748 | .source_off = @intCast(header.items.len), | |
| 4826 | .source_off = @intCast(header_bw.end), | |
| 4749 | 4827 | .target_sec = .debug_line_str, |
| 4750 | 4828 | .target_unit = StringSection.unit, |
| 4751 | 4829 | .target_entry = (try dwarf.debug_line_str.addString(dwarf, file.sub_file_path)).toOptional(), |
| 4752 | 4830 | }); |
| 4753 | 4831 | 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, | |
| 4756 | 4835 | mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod.?).?) orelse 0, |
| 4757 | 4836 | ); |
| 4758 | 4837 | unit.cross_section_relocs.appendAssumeCapacity(.{ |
| 4759 | .source_off = @intCast(header.items.len), | |
| 4838 | .source_off = @intCast(header_bw.end), | |
| 4760 | 4839 | .target_sec = .debug_line_str, |
| 4761 | 4840 | .target_unit = StringSection.unit, |
| 4762 | 4841 | .target_entry = (try dwarf.debug_line_str.addString( |
| ... | ... | @@ -4764,9 +4843,10 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4764 | 4843 | if (file.is_builtin) file.source.? else "", |
| 4765 | 4844 | )).toOptional(), |
| 4766 | 4845 | }); |
| 4767 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | |
| 4846 | header_bw.splatByteAll(0, dwarf.sectionOffsetBytes()) catch unreachable; | |
| 4768 | 4847 | } |
| 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); | |
| 4770 | 4850 | try unit.writeTrailer(&dwarf.debug_line.section, dwarf); |
| 4771 | 4851 | } |
| 4772 | 4852 | dwarf.debug_line.section.dirty = false; |
| ... | ... | @@ -4782,24 +4862,25 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4782 | 4862 | } |
| 4783 | 4863 | if (dwarf.debug_rnglists.section.dirty) { |
| 4784 | 4864 | 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); | |
| 4787 | 4867 | const unit_len = (if (unit.next.unwrap()) |next_unit| |
| 4788 | 4868 | dwarf.debug_rnglists.section.getUnit(next_unit).off |
| 4789 | 4869 | else |
| 4790 | 4870 | dwarf.debug_rnglists.section.len) - unit.off - dwarf.unitLengthBytes(); |
| 4791 | 4871 | 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, | |
| 4793 | 4873 | .@"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; | |
| 4796 | 4876 | }, |
| 4797 | 4877 | } |
| 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); | |
| 4803 | 4884 | try unit.writeTrailer(&dwarf.debug_rnglists.section, dwarf); |
| 4804 | 4885 | } |
| 4805 | 4886 | dwarf.debug_rnglists.section.dirty = false; |
| ... | ... | @@ -4815,6 +4896,9 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4815 | 4896 | assert(!dwarf.debug_str.section.dirty); |
| 4816 | 4897 | } |
| 4817 | 4898 | |
| 4899 | const sleb128 = {}; | |
| 4900 | const uleb128 = {}; | |
| 4901 | ||
| 4818 | 4902 | pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void { |
| 4819 | 4903 | for ([_]*Section{ |
| 4820 | 4904 | &dwarf.debug_abbrev.section, |
| ... | ... | @@ -5979,7 +6063,7 @@ fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index { |
| 5979 | 6063 | return entry; |
| 5980 | 6064 | } |
| 5981 | 6065 | |
| 5982 | fn freeCommonEntry(dwarf: *Dwarf, unit: Unit.Index, entry: Entry.Index) UpdateError!void { | |
| 6066 | fn freeCommonEntry(dwarf: *Dwarf, unit: Unit.Index, entry: Entry.Index) anyerror!void { | |
| 5983 | 6067 | try dwarf.debug_aranges.section.freeEntry(unit, entry, dwarf); |
| 5984 | 6068 | try dwarf.debug_frame.section.freeEntry(unit, entry, dwarf); |
| 5985 | 6069 | try dwarf.debug_info.section.freeEntry(unit, entry, dwarf); |
| ... | ... | @@ -5998,6 +6082,11 @@ fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void { |
| 5998 | 6082 | } |
| 5999 | 6083 | } |
| 6000 | 6084 | |
| 6085 | fn 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 | ||
| 6001 | 6090 | fn resolveReloc(dwarf: *Dwarf, source: u64, target: u64, size: u32) RelocError!void { |
| 6002 | 6091 | var buf: [8]u8 = undefined; |
| 6003 | 6092 | dwarf.writeInt(buf[0..size], target); |
| ... | ... | @@ -6019,21 +6108,34 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 { |
| 6019 | 6108 | } |
| 6020 | 6109 | |
| 6021 | 6110 | fn 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 | }); | |
| 6028 | 6119 | } |
| 6029 | ||
| 6030 | 6120 | fn 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 | } | |
| 6130 | fn 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); | |
| 6037 | 6139 | } |
| 6038 | 6140 | |
| 6039 | 6141 | /// overrides `-fno-incremental` for testing incremental debug info until `-fincremental` is functional |
| ... | ... | @@ -6055,7 +6157,5 @@ const codegen = @import("../codegen.zig"); |
| 6055 | 6157 | const dev = @import("../dev.zig"); |
| 6056 | 6158 | const link = @import("../link.zig"); |
| 6057 | 6159 | const log = std.log.scoped(.dwarf); |
| 6058 | const sleb128 = std.leb.writeIleb128; | |
| 6059 | 6160 | const std = @import("std"); |
| 6060 | 6161 | const target_info = @import("../target.zig"); |
| 6061 | const uleb128 = std.leb.writeUleb128; |
src/link/Elf.zig+132-143| ... | ... | @@ -702,7 +702,7 @@ pub fn allocateChunk(self: *Elf, args: struct { |
| 702 | 702 | shdr.sh_addr + res.value, |
| 703 | 703 | shdr.sh_offset + res.value, |
| 704 | 704 | }); |
| 705 | log.debug(" placement {}, {s}", .{ | |
| 705 | log.debug(" placement {f}, {s}", .{ | |
| 706 | 706 | res.placement, |
| 707 | 707 | if (self.atom(res.placement)) |atom_ptr| atom_ptr.name(self) else "", |
| 708 | 708 | }); |
| ... | ... | @@ -869,7 +869,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 869 | 869 | // Dump the state for easy debugging. |
| 870 | 870 | // State can be dumped via `--debug-log link_state`. |
| 871 | 871 | if (build_options.enable_logging) { |
| 872 | state_log.debug("{}", .{self.dumpState()}); | |
| 872 | state_log.debug("{f}", .{self.dumpState()}); | |
| 873 | 873 | } |
| 874 | 874 | |
| 875 | 875 | // Beyond this point, everything has been allocated a virtual address and we can resolve |
| ... | ... | @@ -1849,7 +1849,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void { |
| 1849 | 1849 | |
| 1850 | 1850 | pub fn writeMergeSections(self: *Elf) !void { |
| 1851 | 1851 | const gpa = self.base.comp.gpa; |
| 1852 | var buffer = std.ArrayList(u8).init(gpa); | |
| 1852 | var buffer: std.ArrayList(u8) = .init(gpa); | |
| 1853 | 1853 | defer buffer.deinit(); |
| 1854 | 1854 | |
| 1855 | 1855 | for (self.merge_sections.items) |*msec| { |
| ... | ... | @@ -2996,7 +2996,7 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 2996 | 2996 | } |
| 2997 | 2997 | } |
| 2998 | 2998 | |
| 2999 | fn writeAtoms(self: *Elf) !void { | |
| 2999 | fn writeAtoms(self: *Elf) anyerror!void { | |
| 3000 | 3000 | const gpa = self.base.comp.gpa; |
| 3001 | 3001 | |
| 3002 | 3002 | var undefs: std.AutoArrayHashMap(SymbolResolver.Index, std.ArrayList(Ref)) = .init(gpa); |
| ... | ... | @@ -3005,7 +3005,7 @@ fn writeAtoms(self: *Elf) !void { |
| 3005 | 3005 | undefs.deinit(); |
| 3006 | 3006 | } |
| 3007 | 3007 | |
| 3008 | var buffer = std.ArrayList(u8).init(gpa); | |
| 3008 | var buffer: std.ArrayList(u8) = .init(gpa); | |
| 3009 | 3009 | defer buffer.deinit(); |
| 3010 | 3010 | |
| 3011 | 3011 | const slice = self.sections.slice(); |
| ... | ... | @@ -3028,14 +3028,14 @@ fn writeAtoms(self: *Elf) !void { |
| 3028 | 3028 | |
| 3029 | 3029 | if (self.requiresThunks()) { |
| 3030 | 3030 | 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); | |
| 3033 | 3034 | const shdr = slice.items(.shdr)[th.output_section_index]; |
| 3034 | 3035 | 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); | |
| 3039 | 3039 | } |
| 3040 | 3040 | } |
| 3041 | 3041 | } |
| ... | ... | @@ -3130,32 +3130,36 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 3130 | 3130 | strtab.sh_size = strsize + 1; |
| 3131 | 3131 | } |
| 3132 | 3132 | |
| 3133 | fn writeSyntheticSections(self: *Elf) !void { | |
| 3133 | fn writeSyntheticSections(self: *Elf) anyerror!void { | |
| 3134 | 3134 | const gpa = self.base.comp.gpa; |
| 3135 | 3135 | const slice = self.sections.slice(); |
| 3136 | 3136 | |
| 3137 | var buffer: std.ArrayListUnmanaged(u8) = .empty; | |
| 3138 | defer buffer.deinit(gpa); | |
| 3139 | var bw: std.io.BufferedWriter = undefined; | |
| 3140 | ||
| 3137 | 3141 | 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]; | |
| 3143 | 3142 | 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); | |
| 3146 | 3149 | } |
| 3147 | 3150 | |
| 3148 | 3151 | if (self.section_indexes.hash) |shndx| { |
| 3149 | 3152 | 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); | |
| 3151 | 3154 | } |
| 3152 | 3155 | |
| 3153 | 3156 | if (self.section_indexes.gnu_hash) |shndx| { |
| 3154 | 3157 | 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); | |
| 3159 | 3163 | } |
| 3160 | 3164 | |
| 3161 | 3165 | if (self.section_indexes.versym) |shndx| { |
| ... | ... | @@ -3165,26 +3169,29 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3165 | 3169 | |
| 3166 | 3170 | if (self.section_indexes.verneed) |shndx| { |
| 3167 | 3171 | 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); | |
| 3172 | 3177 | } |
| 3173 | 3178 | |
| 3174 | 3179 | if (self.section_indexes.dynamic) |shndx| { |
| 3175 | 3180 | 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); | |
| 3180 | 3186 | } |
| 3181 | 3187 | |
| 3182 | 3188 | if (self.section_indexes.dynsymtab) |shndx| { |
| 3183 | 3189 | 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); | |
| 3188 | 3195 | } |
| 3189 | 3196 | |
| 3190 | 3197 | if (self.section_indexes.dynstrtab) |shndx| { |
| ... | ... | @@ -3200,28 +3207,30 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3200 | 3207 | }; |
| 3201 | 3208 | const shdr = slice.items(.shdr)[shndx]; |
| 3202 | 3209 | 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); | |
| 3208 | 3215 | } |
| 3209 | 3216 | |
| 3210 | 3217 | if (self.section_indexes.eh_frame_hdr) |shndx| { |
| 3211 | 3218 | const shdr = slice.items(.shdr)[shndx]; |
| 3212 | 3219 | 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); | |
| 3217 | 3225 | } |
| 3218 | 3226 | |
| 3219 | 3227 | if (self.section_indexes.got) |index| { |
| 3220 | 3228 | 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); | |
| 3225 | 3234 | } |
| 3226 | 3235 | |
| 3227 | 3236 | if (self.section_indexes.rela_dyn) |shndx| { |
| ... | ... | @@ -3234,26 +3243,29 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 3234 | 3243 | |
| 3235 | 3244 | if (self.section_indexes.plt) |shndx| { |
| 3236 | 3245 | 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); | |
| 3241 | 3251 | } |
| 3242 | 3252 | |
| 3243 | 3253 | if (self.section_indexes.got_plt) |shndx| { |
| 3244 | 3254 | 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); | |
| 3249 | 3260 | } |
| 3250 | 3261 | |
| 3251 | 3262 | if (self.section_indexes.plt_got) |shndx| { |
| 3252 | 3263 | 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); | |
| 3257 | 3269 | } |
| 3258 | 3270 | |
| 3259 | 3271 | if (self.section_indexes.rela_plt) |shndx| { |
| ... | ... | @@ -3544,7 +3556,7 @@ pub fn addRelaDyn(self: *Elf, opts: RelaDyn) !void { |
| 3544 | 3556 | } |
| 3545 | 3557 | |
| 3546 | 3558 | pub 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}", .{ | |
| 3548 | 3560 | relocation.fmtRelocType(opts.type, self.getTarget().cpu.arch), |
| 3549 | 3561 | opts.offset, |
| 3550 | 3562 | opts.sym, |
| ... | ... | @@ -3754,9 +3766,8 @@ fn shString( |
| 3754 | 3766 | |
| 3755 | 3767 | pub fn insertShString(self: *Elf, name: [:0]const u8) error{OutOfMemory}!u32 { |
| 3756 | 3768 | 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}); | |
| 3760 | 3771 | return off; |
| 3761 | 3772 | } |
| 3762 | 3773 | |
| ... | ... | @@ -3769,7 +3780,7 @@ pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 { |
| 3769 | 3780 | const gpa = self.base.comp.gpa; |
| 3770 | 3781 | const off = @as(u32, @intCast(self.dynstrtab.items.len)); |
| 3771 | 3782 | 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; | |
| 3773 | 3784 | return off; |
| 3774 | 3785 | } |
| 3775 | 3786 | |
| ... | ... | @@ -3791,7 +3802,7 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void { |
| 3791 | 3802 | for (refs.items[0..nrefs]) |ref| { |
| 3792 | 3803 | const atom_ptr = self.atom(ref).?; |
| 3793 | 3804 | 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) }); | |
| 3795 | 3806 | } |
| 3796 | 3807 | |
| 3797 | 3808 | if (refs.items.len > max_notes) { |
| ... | ... | @@ -3813,12 +3824,12 @@ fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemor |
| 3813 | 3824 | |
| 3814 | 3825 | var err = try diags.addErrorWithNotes(nnotes + 1); |
| 3815 | 3826 | 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()}); | |
| 3817 | 3828 | |
| 3818 | 3829 | var inote: usize = 0; |
| 3819 | 3830 | while (inote < @min(notes.items.len, max_notes)) : (inote += 1) { |
| 3820 | 3831 | 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()}); | |
| 3822 | 3833 | } |
| 3823 | 3834 | |
| 3824 | 3835 | if (notes.items.len > max_notes) { |
| ... | ... | @@ -3847,7 +3858,7 @@ pub fn addFileError( |
| 3847 | 3858 | const diags = &self.base.comp.link_diags; |
| 3848 | 3859 | var err = try diags.addErrorWithNotes(1); |
| 3849 | 3860 | 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()}); | |
| 3851 | 3862 | } |
| 3852 | 3863 | |
| 3853 | 3864 | pub fn failFile( |
| ... | ... | @@ -3872,16 +3883,10 @@ fn fmtShdr(self: *Elf, shdr: elf.Elf64_Shdr) std.fmt.Formatter(formatShdr) { |
| 3872 | 3883 | } }; |
| 3873 | 3884 | } |
| 3874 | 3885 | |
| 3875 | fn formatShdr( | |
| 3876 | ctx: FormatShdrCtx, | |
| 3877 | comptime unused_fmt_string: []const u8, | |
| 3878 | options: std.fmt.FormatOptions, | |
| 3879 | writer: anytype, | |
| 3880 | ) !void { | |
| 3881 | _ = options; | |
| 3886 | fn formatShdr(ctx: FormatShdrCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 3882 | 3887 | _ = unused_fmt_string; |
| 3883 | 3888 | 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})", .{ | |
| 3885 | 3890 | ctx.elf_file.getShString(shdr.sh_name), shdr.sh_offset, |
| 3886 | 3891 | shdr.sh_addr, shdr.sh_addralign, |
| 3887 | 3892 | shdr.sh_size, shdr.sh_entsize, |
| ... | ... | @@ -3893,55 +3898,49 @@ pub fn fmtShdrFlags(sh_flags: u64) std.fmt.Formatter(formatShdrFlags) { |
| 3893 | 3898 | return .{ .data = sh_flags }; |
| 3894 | 3899 | } |
| 3895 | 3900 | |
| 3896 | fn formatShdrFlags( | |
| 3897 | sh_flags: u64, | |
| 3898 | comptime unused_fmt_string: []const u8, | |
| 3899 | options: std.fmt.FormatOptions, | |
| 3900 | writer: anytype, | |
| 3901 | ) !void { | |
| 3901 | fn formatShdrFlags(sh_flags: u64, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) !void { | |
| 3902 | 3902 | _ = unused_fmt_string; |
| 3903 | _ = options; | |
| 3904 | 3903 | if (elf.SHF_WRITE & sh_flags != 0) { |
| 3905 | try writer.writeAll("W"); | |
| 3904 | try bw.writeByte('W'); | |
| 3906 | 3905 | } |
| 3907 | 3906 | if (elf.SHF_ALLOC & sh_flags != 0) { |
| 3908 | try writer.writeAll("A"); | |
| 3907 | try bw.writeByte('A'); | |
| 3909 | 3908 | } |
| 3910 | 3909 | if (elf.SHF_EXECINSTR & sh_flags != 0) { |
| 3911 | try writer.writeAll("X"); | |
| 3910 | try bw.writeByte('X'); | |
| 3912 | 3911 | } |
| 3913 | 3912 | if (elf.SHF_MERGE & sh_flags != 0) { |
| 3914 | try writer.writeAll("M"); | |
| 3913 | try bw.writeByte('M'); | |
| 3915 | 3914 | } |
| 3916 | 3915 | if (elf.SHF_STRINGS & sh_flags != 0) { |
| 3917 | try writer.writeAll("S"); | |
| 3916 | try bw.writeByte('S'); | |
| 3918 | 3917 | } |
| 3919 | 3918 | if (elf.SHF_INFO_LINK & sh_flags != 0) { |
| 3920 | try writer.writeAll("I"); | |
| 3919 | try bw.writeByte('I'); | |
| 3921 | 3920 | } |
| 3922 | 3921 | if (elf.SHF_LINK_ORDER & sh_flags != 0) { |
| 3923 | try writer.writeAll("L"); | |
| 3922 | try bw.writeByte('L'); | |
| 3924 | 3923 | } |
| 3925 | 3924 | if (elf.SHF_EXCLUDE & sh_flags != 0) { |
| 3926 | try writer.writeAll("E"); | |
| 3925 | try bw.writeByte('E'); | |
| 3927 | 3926 | } |
| 3928 | 3927 | if (elf.SHF_COMPRESSED & sh_flags != 0) { |
| 3929 | try writer.writeAll("C"); | |
| 3928 | try bw.writeByte('C'); | |
| 3930 | 3929 | } |
| 3931 | 3930 | if (elf.SHF_GROUP & sh_flags != 0) { |
| 3932 | try writer.writeAll("G"); | |
| 3931 | try bw.writeByte('G'); | |
| 3933 | 3932 | } |
| 3934 | 3933 | if (elf.SHF_OS_NONCONFORMING & sh_flags != 0) { |
| 3935 | try writer.writeAll("O"); | |
| 3934 | try bw.writeByte('O'); | |
| 3936 | 3935 | } |
| 3937 | 3936 | if (elf.SHF_TLS & sh_flags != 0) { |
| 3938 | try writer.writeAll("T"); | |
| 3937 | try bw.writeByte('T'); | |
| 3939 | 3938 | } |
| 3940 | 3939 | if (elf.SHF_X86_64_LARGE & sh_flags != 0) { |
| 3941 | try writer.writeAll("l"); | |
| 3940 | try bw.writeByte('l'); | |
| 3942 | 3941 | } |
| 3943 | 3942 | 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'); | |
| 3945 | 3944 | } |
| 3946 | 3945 | } |
| 3947 | 3946 | |
| ... | ... | @@ -3959,11 +3958,9 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Formatter(formatPhdr) { |
| 3959 | 3958 | |
| 3960 | 3959 | fn formatPhdr( |
| 3961 | 3960 | ctx: FormatPhdrCtx, |
| 3961 | bw: *std.io.BufferedWriter, | |
| 3962 | 3962 | comptime unused_fmt_string: []const u8, |
| 3963 | options: std.fmt.FormatOptions, | |
| 3964 | writer: anytype, | |
| 3965 | 3963 | ) !void { |
| 3966 | _ = options; | |
| 3967 | 3964 | _ = unused_fmt_string; |
| 3968 | 3965 | const phdr = ctx.phdr; |
| 3969 | 3966 | const write = phdr.p_flags & elf.PF_W != 0; |
| ... | ... | @@ -3985,7 +3982,7 @@ fn formatPhdr( |
| 3985 | 3982 | elf.PT_NOTE => "NOTE", |
| 3986 | 3983 | else => "UNKNOWN", |
| 3987 | 3984 | }; |
| 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})", .{ | |
| 3989 | 3986 | p_type, flags, phdr.p_offset, phdr.p_vaddr, |
| 3990 | 3987 | phdr.p_align, phdr.p_filesz, phdr.p_memsz, |
| 3991 | 3988 | }); |
| ... | ... | @@ -3997,30 +3994,28 @@ pub fn dumpState(self: *Elf) std.fmt.Formatter(fmtDumpState) { |
| 3997 | 3994 | |
| 3998 | 3995 | fn fmtDumpState( |
| 3999 | 3996 | self: *Elf, |
| 3997 | bw: *std.io.BufferedWriter, | |
| 4000 | 3998 | comptime unused_fmt_string: []const u8, |
| 4001 | options: std.fmt.FormatOptions, | |
| 4002 | writer: anytype, | |
| 4003 | 3999 | ) !void { |
| 4004 | 4000 | _ = unused_fmt_string; |
| 4005 | _ = options; | |
| 4006 | 4001 | |
| 4007 | 4002 | const shared_objects = self.shared_objects.values(); |
| 4008 | 4003 | |
| 4009 | 4004 | 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}", .{ | |
| 4012 | 4007 | zig_object.fmtAtoms(self), |
| 4013 | 4008 | zig_object.fmtSymtab(self), |
| 4014 | 4009 | }); |
| 4015 | try writer.writeByte('\n'); | |
| 4010 | try bw.writeByte('\n'); | |
| 4016 | 4011 | } |
| 4017 | 4012 | |
| 4018 | 4013 | for (self.objects.items) |index| { |
| 4019 | 4014 | 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", .{ | |
| 4024 | 4019 | object.fmtAtoms(self), |
| 4025 | 4020 | object.fmtCies(self), |
| 4026 | 4021 | object.fmtFdes(self), |
| ... | ... | @@ -4031,59 +4026,59 @@ fn fmtDumpState( |
| 4031 | 4026 | |
| 4032 | 4027 | for (shared_objects) |index| { |
| 4033 | 4028 | 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({})", .{ | |
| 4035 | 4030 | index, shared_object.path, shared_object.needed, |
| 4036 | 4031 | }); |
| 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)}); | |
| 4040 | 4035 | } |
| 4041 | 4036 | |
| 4042 | 4037 | if (self.linker_defined_index) |index| { |
| 4043 | 4038 | 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)}); | |
| 4046 | 4041 | } |
| 4047 | 4042 | |
| 4048 | 4043 | const slice = self.sections.slice(); |
| 4049 | 4044 | { |
| 4050 | try writer.writeAll("atom lists\n"); | |
| 4045 | try bw.writeAll("atom lists\n"); | |
| 4051 | 4046 | 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) }); | |
| 4053 | 4048 | } |
| 4054 | 4049 | } |
| 4055 | 4050 | |
| 4056 | 4051 | if (self.requiresThunks()) { |
| 4057 | try writer.writeAll("thunks\n"); | |
| 4052 | try bw.writeAll("thunks\n"); | |
| 4058 | 4053 | 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) }); | |
| 4060 | 4055 | } |
| 4061 | 4056 | } |
| 4062 | 4057 | |
| 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)}); | |
| 4065 | 4060 | |
| 4066 | try writer.writeAll("Output groups\n"); | |
| 4061 | try bw.writeAll("Output groups\n"); | |
| 4067 | 4062 | 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 }); | |
| 4069 | 4064 | } |
| 4070 | 4065 | |
| 4071 | try writer.writeAll("\nOutput merge sections\n"); | |
| 4066 | try bw.writeAll("\nOutput merge sections\n"); | |
| 4072 | 4067 | 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) }); | |
| 4074 | 4069 | } |
| 4075 | 4070 | |
| 4076 | try writer.writeAll("\nOutput shdrs\n"); | |
| 4071 | try bw.writeAll("\nOutput shdrs\n"); | |
| 4077 | 4072 | 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", .{ | |
| 4079 | 4074 | shndx, |
| 4080 | 4075 | phndx, |
| 4081 | 4076 | self.fmtShdr(shdr), |
| 4082 | 4077 | }); |
| 4083 | 4078 | } |
| 4084 | try writer.writeAll("\nOutput phdrs\n"); | |
| 4079 | try bw.writeAll("\nOutput phdrs\n"); | |
| 4085 | 4080 | 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) }); | |
| 4087 | 4082 | } |
| 4088 | 4083 | } |
| 4089 | 4084 | |
| ... | ... | @@ -4221,15 +4216,9 @@ pub const Ref = struct { |
| 4221 | 4216 | return ref.index == other.index and ref.file == other.file; |
| 4222 | 4217 | } |
| 4223 | 4218 | |
| 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 { | |
| 4230 | 4220 | _ = unused_fmt_string; |
| 4231 | _ = options; | |
| 4232 | try writer.print("ref({},{})", .{ ref.index, ref.file }); | |
| 4221 | try bw.print("ref({},{})", .{ ref.index, ref.file }); | |
| 4233 | 4222 | } |
| 4234 | 4223 | }; |
| 4235 | 4224 | |
| ... | ... | @@ -4424,7 +4413,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void { |
| 4424 | 4413 | for (atom_list.atoms.keys()[start..i]) |ref| { |
| 4425 | 4414 | const atom_ptr = elf_file.atom(ref).?; |
| 4426 | 4415 | 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) }); | |
| 4428 | 4417 | for (atom_ptr.relocs(elf_file)) |rel| { |
| 4429 | 4418 | const is_reachable = switch (cpu_arch) { |
| 4430 | 4419 | .aarch64 => r: { |
| ... | ... | @@ -4453,7 +4442,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void { |
| 4453 | 4442 | |
| 4454 | 4443 | thunk_ptr.value = try advance(atom_list, thunk_ptr.size(elf_file), Atom.Alignment.fromNonzeroByteUnits(2)); |
| 4455 | 4444 | |
| 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) }); | |
| 4457 | 4446 | } |
| 4458 | 4447 | } |
| 4459 | 4448 |
src/link/Elf/Archive.zig+20-55| ... | ... | @@ -44,7 +44,7 @@ pub fn parse( |
| 44 | 44 | pos += @sizeOf(elf.ar_hdr); |
| 45 | 45 | |
| 46 | 46 | 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}", .{ | |
| 48 | 48 | std.fmt.fmtSliceEscapeLower(&hdr.ar_fmag), |
| 49 | 49 | }); |
| 50 | 50 | } |
| ... | ... | @@ -83,8 +83,8 @@ pub fn parse( |
| 83 | 83 | .alive = false, |
| 84 | 84 | }; |
| 85 | 85 | |
| 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, | |
| 88 | 88 | }); |
| 89 | 89 | |
| 90 | 90 | try objects.append(gpa, object); |
| ... | ... | @@ -110,33 +110,16 @@ pub fn setArHdr(opts: struct { |
| 110 | 110 | }, |
| 111 | 111 | size: usize, |
| 112 | 112 | }) 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), ' '); | |
| 123 | 115 | @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, | |
| 134 | 121 | } |
| 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; | |
| 140 | 123 | return hdr; |
| 141 | 124 | } |
| 142 | 125 | |
| ... | ... | @@ -201,16 +184,10 @@ pub const ArSymtab = struct { |
| 201 | 184 | } |
| 202 | 185 | } |
| 203 | 186 | |
| 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 { | |
| 210 | 188 | _ = ar; |
| 189 | _ = bw; | |
| 211 | 190 | _ = unused_fmt_string; |
| 212 | _ = options; | |
| 213 | _ = writer; | |
| 214 | 191 | @compileError("do not format ar symtab directly; use fmt instead"); |
| 215 | 192 | } |
| 216 | 193 | |
| ... | ... | @@ -226,20 +203,14 @@ pub const ArSymtab = struct { |
| 226 | 203 | } }; |
| 227 | 204 | } |
| 228 | 205 | |
| 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 { | |
| 235 | 207 | _ = unused_fmt_string; |
| 236 | _ = options; | |
| 237 | 208 | const ar = ctx.ar; |
| 238 | 209 | const elf_file = ctx.elf_file; |
| 239 | 210 | for (ar.symtab.items, 0..) |entry, i| { |
| 240 | 211 | const name = ar.strtab.getAssumeExists(entry.off); |
| 241 | 212 | 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() }); | |
| 243 | 214 | } |
| 244 | 215 | } |
| 245 | 216 | |
| ... | ... | @@ -264,9 +235,9 @@ pub const ArStrtab = struct { |
| 264 | 235 | ar.buffer.deinit(allocator); |
| 265 | 236 | } |
| 266 | 237 | |
| 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 }); | |
| 270 | 241 | return off; |
| 271 | 242 | } |
| 272 | 243 | |
| ... | ... | @@ -280,15 +251,9 @@ pub const ArStrtab = struct { |
| 280 | 251 | try writer.writeAll(ar.buffer.items); |
| 281 | 252 | } |
| 282 | 253 | |
| 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 { | |
| 289 | 255 | _ = 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)}); | |
| 292 | 257 | } |
| 293 | 258 | }; |
| 294 | 259 |
src/link/Elf/Atom.zig+181-219| ... | ... | @@ -142,7 +142,7 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool { |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | pub 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) }); | |
| 146 | 146 | |
| 147 | 147 | const comp = elf_file.base.comp; |
| 148 | 148 | const gpa = comp.gpa; |
| ... | ... | @@ -243,7 +243,7 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El |
| 243 | 243 | }, |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{ | |
| 246 | relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{ | |
| 247 | 247 | relocation.fmtRelocType(rel.r_type(), cpu_arch), |
| 248 | 248 | r_offset, |
| 249 | 249 | r_sym, |
| ... | ... | @@ -316,7 +316,7 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype |
| 316 | 316 | }; |
| 317 | 317 | // Violation of One Definition Rule for COMDATs. |
| 318 | 318 | // 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", .{ | |
| 320 | 320 | file_ptr.fmtPath(), |
| 321 | 321 | self.name(elf_file), |
| 322 | 322 | sym_name, |
| ... | ... | @@ -519,11 +519,11 @@ fn dataType(symbol: *const Symbol, elf_file: *Elf) u2 { |
| 519 | 519 | fn reportUnhandledRelocError(self: Atom, rel: elf.Elf64_Rela, elf_file: *Elf) RelocError!void { |
| 520 | 520 | const diags = &elf_file.base.comp.link_diags; |
| 521 | 521 | 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}", .{ | |
| 523 | 523 | relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch), |
| 524 | 524 | rel.r_offset, |
| 525 | 525 | }); |
| 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) }); | |
| 527 | 527 | return error.RelocFailure; |
| 528 | 528 | } |
| 529 | 529 | |
| ... | ... | @@ -539,7 +539,7 @@ fn reportTextRelocError( |
| 539 | 539 | rel.r_offset, |
| 540 | 540 | symbol.name(elf_file), |
| 541 | 541 | }); |
| 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) }); | |
| 543 | 543 | return error.RelocFailure; |
| 544 | 544 | } |
| 545 | 545 | |
| ... | ... | @@ -555,7 +555,7 @@ fn reportPicError( |
| 555 | 555 | rel.r_offset, |
| 556 | 556 | symbol.name(elf_file), |
| 557 | 557 | }); |
| 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) }); | |
| 559 | 559 | err.addNote("recompile with -fPIC", .{}); |
| 560 | 560 | return error.RelocFailure; |
| 561 | 561 | } |
| ... | ... | @@ -572,7 +572,7 @@ fn reportNoPicError( |
| 572 | 572 | rel.r_offset, |
| 573 | 573 | symbol.name(elf_file), |
| 574 | 574 | }); |
| 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) }); | |
| 576 | 576 | err.addNote("recompile with -fno-PIC", .{}); |
| 577 | 577 | return error.RelocFailure; |
| 578 | 578 | } |
| ... | ... | @@ -621,7 +621,9 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi |
| 621 | 621 | |
| 622 | 622 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 623 | 623 | 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); | |
| 625 | 627 | |
| 626 | 628 | const rels = self.relocs(elf_file); |
| 627 | 629 | var it = RelocsIterator{ .relocs = rels }; |
| ... | ... | @@ -652,7 +654,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi |
| 652 | 654 | // Address of the dynamic thread pointer. |
| 653 | 655 | const DTP = elf_file.dtpAddress(); |
| 654 | 656 | |
| 655 | relocs_log.debug(" {s}: {x}: [{x} => {x}] GOT({x}) ({s})", .{ | |
| 657 | relocs_log.debug(" {f}: {x}: [{x} => {x}] GOT({x}) ({s})", .{ | |
| 656 | 658 | relocation.fmtRelocType(rel.r_type(), cpu_arch), |
| 657 | 659 | r_offset, |
| 658 | 660 | P, |
| ... | ... | @@ -661,32 +663,32 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi |
| 661 | 663 | target.name(elf_file), |
| 662 | 664 | }); |
| 663 | 665 | |
| 664 | try stream.seekTo(r_offset); | |
| 665 | ||
| 666 | 666 | const args = ResolveArgs{ P, A, S, GOT, G, TP, DTP }; |
| 667 | 667 | |
| 668 | bw.end = r_offset; | |
| 669 | bw.count = 0; | |
| 668 | 670 | 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) { | |
| 670 | 672 | error.RelocFailure, |
| 671 | 673 | error.RelaxFailure, |
| 672 | 674 | error.InvalidInstruction, |
| 673 | 675 | error.CannotEncode, |
| 674 | 676 | => has_reloc_errors = true, |
| 675 | else => |e| return e, | |
| 677 | else => |e| return @errorCast(e), | |
| 676 | 678 | }, |
| 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) { | |
| 678 | 680 | error.RelocFailure, |
| 679 | 681 | error.RelaxFailure, |
| 680 | 682 | error.UnexpectedRemainder, |
| 681 | 683 | error.DivisionByZero, |
| 682 | 684 | => has_reloc_errors = true, |
| 683 | else => |e| return e, | |
| 685 | else => |e| return @errorCast(e), | |
| 684 | 686 | }, |
| 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) { | |
| 686 | 688 | error.RelocFailure, |
| 687 | 689 | error.RelaxFailure, |
| 688 | 690 | => has_reloc_errors = true, |
| 689 | else => |e| return e, | |
| 691 | else => |e| return @errorCast(e), | |
| 690 | 692 | }, |
| 691 | 693 | else => return error.UnsupportedCpuArch, |
| 692 | 694 | } |
| ... | ... | @@ -804,7 +806,9 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 804 | 806 | |
| 805 | 807 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 806 | 808 | 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); | |
| 808 | 812 | |
| 809 | 813 | const rels = self.relocs(elf_file); |
| 810 | 814 | var has_reloc_errors = false; |
| ... | ... | @@ -823,7 +827,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 823 | 827 | }; |
| 824 | 828 | // Violation of One Definition Rule for COMDATs. |
| 825 | 829 | // 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", .{ | |
| 827 | 831 | file_ptr.fmtPath(), |
| 828 | 832 | self.name(elf_file), |
| 829 | 833 | sym_name, |
| ... | ... | @@ -855,7 +859,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 855 | 859 | |
| 856 | 860 | const args = ResolveArgs{ P, A, S, GOT, 0, 0, DTP }; |
| 857 | 861 | |
| 858 | relocs_log.debug(" {}: {x}: [{x} => {x}] ({s})", .{ | |
| 862 | relocs_log.debug(" {f}: {x}: [{x} => {x}] ({s})", .{ | |
| 859 | 863 | relocation.fmtRelocType(rel.r_type(), cpu_arch), |
| 860 | 864 | rel.r_offset, |
| 861 | 865 | P, |
| ... | ... | @@ -863,18 +867,18 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 863 | 867 | target.name(elf_file), |
| 864 | 868 | }); |
| 865 | 869 | |
| 866 | try stream.seekTo(r_offset); | |
| 867 | ||
| 870 | bw.end = r_offset; | |
| 871 | bw.count = 0; | |
| 868 | 872 | 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) { | |
| 870 | 874 | error.RelocFailure => has_reloc_errors = true, |
| 871 | 875 | else => |e| return e, |
| 872 | 876 | }, |
| 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) { | |
| 874 | 878 | error.RelocFailure => has_reloc_errors = true, |
| 875 | 879 | else => |e| return e, |
| 876 | 880 | }, |
| 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) { | |
| 878 | 882 | error.RelocFailure => has_reloc_errors = true, |
| 879 | 883 | else => |e| return e, |
| 880 | 884 | }, |
| ... | ... | @@ -904,16 +908,10 @@ pub fn setExtra(atom: Atom, extras: Extra, elf_file: *Elf) void { |
| 904 | 908 | atom.file(elf_file).?.setAtomExtra(atom.extra_index, extras); |
| 905 | 909 | } |
| 906 | 910 | |
| 907 | pub fn format( | |
| 908 | atom: Atom, | |
| 909 | comptime unused_fmt_string: []const u8, | |
| 910 | options: std.fmt.FormatOptions, | |
| 911 | writer: anytype, | |
| 912 | ) !void { | |
| 911 | pub fn format(atom: Atom, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 913 | 912 | _ = atom; |
| 913 | _ = bw; | |
| 914 | 914 | _ = unused_fmt_string; |
| 915 | _ = options; | |
| 916 | _ = writer; | |
| 917 | 915 | @compileError("do not format Atom directly"); |
| 918 | 916 | } |
| 919 | 917 | |
| ... | ... | @@ -929,17 +927,11 @@ const FormatContext = struct { |
| 929 | 927 | elf_file: *Elf, |
| 930 | 928 | }; |
| 931 | 929 | |
| 932 | fn format2( | |
| 933 | ctx: FormatContext, | |
| 934 | comptime unused_fmt_string: []const u8, | |
| 935 | options: std.fmt.FormatOptions, | |
| 936 | writer: anytype, | |
| 937 | ) !void { | |
| 938 | _ = options; | |
| 930 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 939 | 931 | _ = unused_fmt_string; |
| 940 | 932 | const atom = ctx.atom; |
| 941 | 933 | 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})", .{ | |
| 943 | 935 | atom.atom_index, atom.name(elf_file), atom.address(elf_file), |
| 944 | 936 | atom.output_section_index, atom.alignment.toByteUnits() orelse 0, atom.size, |
| 945 | 937 | atom.prev_atom_ref, atom.next_atom_ref, |
| ... | ... | @@ -947,20 +939,20 @@ fn format2( |
| 947 | 939 | if (atom.file(elf_file)) |atom_file| switch (atom_file) { |
| 948 | 940 | .object => |object| { |
| 949 | 941 | if (atom.fdes(object).len > 0) { |
| 950 | try writer.writeAll(" : fdes{ "); | |
| 942 | try bw.writeAll(" : fdes{ "); | |
| 951 | 943 | const extras = atom.extra(elf_file); |
| 952 | 944 | 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(", "); | |
| 956 | 948 | } |
| 957 | try writer.writeAll(" }"); | |
| 949 | try bw.writeAll(" }"); | |
| 958 | 950 | } |
| 959 | 951 | }, |
| 960 | 952 | else => {}, |
| 961 | 953 | }; |
| 962 | 954 | if (!atom.alive) { |
| 963 | try writer.writeAll(" : [*]"); | |
| 955 | try bw.writeAll(" : [*]"); | |
| 964 | 956 | } |
| 965 | 957 | } |
| 966 | 958 | |
| ... | ... | @@ -1087,16 +1079,12 @@ const x86_64 = struct { |
| 1087 | 1079 | target: *const Symbol, |
| 1088 | 1080 | args: ResolveArgs, |
| 1089 | 1081 | it: *RelocsIterator, |
| 1090 | code: []u8, | |
| 1091 | stream: anytype, | |
| 1092 | ) (error{ InvalidInstruction, CannotEncode } || RelocError)!void { | |
| 1082 | bw: *std.io.BufferedWriter, | |
| 1083 | ) anyerror!void { | |
| 1093 | 1084 | dev.check(.x86_64_backend); |
| 1094 | 1085 | const t = &elf_file.base.comp.root_mod.resolved_target.result; |
| 1095 | 1086 | const diags = &elf_file.base.comp.link_diags; |
| 1096 | 1087 | 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(); | |
| 1100 | 1088 | |
| 1101 | 1089 | const P, const A, const S, const GOT, const G, const TP, const DTP = args; |
| 1102 | 1090 | |
| ... | ... | @@ -1109,58 +1097,54 @@ const x86_64 = struct { |
| 1109 | 1097 | rel, |
| 1110 | 1098 | dynAbsRelocAction(target, elf_file), |
| 1111 | 1099 | elf_file, |
| 1112 | cwriter, | |
| 1100 | bw, | |
| 1113 | 1101 | ); |
| 1114 | 1102 | }, |
| 1115 | 1103 | |
| 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), | |
| 1118 | 1106 | |
| 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), | |
| 1122 | 1110 | |
| 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); | |
| 1130 | 1116 | }, |
| 1131 | 1117 | |
| 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); | |
| 1139 | 1123 | }, |
| 1140 | 1124 | |
| 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), | |
| 1143 | 1127 | |
| 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), | |
| 1146 | 1130 | |
| 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), | |
| 1149 | 1133 | |
| 1150 | 1134 | .TLSGD => { |
| 1151 | 1135 | if (target.flags.has_tlsgd) { |
| 1152 | 1136 | 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); | |
| 1154 | 1138 | } else if (target.flags.has_gottp) { |
| 1155 | 1139 | 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); | |
| 1157 | 1141 | } else { |
| 1158 | 1142 | try x86_64.relaxTlsGdToLe( |
| 1159 | 1143 | atom, |
| 1160 | 1144 | &.{ rel, it.next().? }, |
| 1161 | 1145 | @as(i32, @intCast(S - TP)), |
| 1162 | 1146 | elf_file, |
| 1163 | stream, | |
| 1147 | bw, | |
| 1164 | 1148 | ); |
| 1165 | 1149 | } |
| 1166 | 1150 | }, |
| ... | ... | @@ -1169,14 +1153,14 @@ const x86_64 = struct { |
| 1169 | 1153 | if (elf_file.got.tlsld_index) |entry_index| { |
| 1170 | 1154 | const tlsld_entry = elf_file.got.entries.items[entry_index]; |
| 1171 | 1155 | 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); | |
| 1173 | 1157 | } else { |
| 1174 | 1158 | try x86_64.relaxTlsLdToLe( |
| 1175 | 1159 | atom, |
| 1176 | 1160 | &.{ rel, it.next().? }, |
| 1177 | 1161 | @as(i32, @intCast(TP - elf_file.tlsAddress())), |
| 1178 | 1162 | elf_file, |
| 1179 | stream, | |
| 1163 | bw, | |
| 1180 | 1164 | ); |
| 1181 | 1165 | } |
| 1182 | 1166 | }, |
| ... | ... | @@ -1184,38 +1168,38 @@ const x86_64 = struct { |
| 1184 | 1168 | .GOTPC32_TLSDESC => { |
| 1185 | 1169 | if (target.flags.has_tlsdesc) { |
| 1186 | 1170 | 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); | |
| 1188 | 1172 | } else { |
| 1189 | x86_64.relaxGotPcTlsDesc(code[r_offset - 3 ..], t) catch { | |
| 1173 | x86_64.relaxGotPcTlsDesc(bw.buffer[bw.end - 3 ..], t) catch { | |
| 1190 | 1174 | var err = try diags.addErrorWithNotes(1); |
| 1191 | 1175 | 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}", .{ | |
| 1193 | 1177 | atom.file(elf_file).?.fmtPath(), |
| 1194 | 1178 | atom.name(elf_file), |
| 1195 | 1179 | rel.r_offset, |
| 1196 | 1180 | }); |
| 1197 | 1181 | return error.RelaxFailure; |
| 1198 | 1182 | }; |
| 1199 | try cwriter.writeInt(i32, @as(i32, @intCast(S - TP)), .little); | |
| 1183 | try bw.writeInt(i32, @as(i32, @intCast(S - TP)), .little); | |
| 1200 | 1184 | } |
| 1201 | 1185 | }, |
| 1202 | 1186 | |
| 1203 | 1187 | .TLSDESC_CALL => if (!target.flags.has_tlsdesc) { |
| 1204 | 1188 | // call -> nop |
| 1205 | try cwriter.writeAll(&.{ 0x66, 0x90 }); | |
| 1189 | try bw.writeAll(&.{ 0x66, 0x90 }); | |
| 1206 | 1190 | }, |
| 1207 | 1191 | |
| 1208 | 1192 | .GOTTPOFF => { |
| 1209 | 1193 | if (target.flags.has_gottp) { |
| 1210 | 1194 | 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); | |
| 1212 | 1196 | } 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); | |
| 1215 | 1199 | } |
| 1216 | 1200 | }, |
| 1217 | 1201 | |
| 1218 | .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + A)), .little), | |
| 1202 | .GOT32 => try bw.writeInt(i32, @as(i32, @intCast(G + A)), .little), | |
| 1219 | 1203 | |
| 1220 | 1204 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 1221 | 1205 | } |
| ... | ... | @@ -1227,45 +1211,40 @@ const x86_64 = struct { |
| 1227 | 1211 | rel: elf.Elf64_Rela, |
| 1228 | 1212 | target: *const Symbol, |
| 1229 | 1213 | args: ResolveArgs, |
| 1230 | it: *RelocsIterator, | |
| 1231 | code: []u8, | |
| 1232 | stream: anytype, | |
| 1233 | ) !void { | |
| 1214 | bw: *std.io.BufferedWriter, | |
| 1215 | ) anyerror!void { | |
| 1234 | 1216 | 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(); | |
| 1239 | 1217 | |
| 1218 | const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); | |
| 1240 | 1219 | _, const A, const S, const GOT, _, _, const DTP = args; |
| 1241 | 1220 | |
| 1242 | 1221 | switch (r_type) { |
| 1243 | 1222 | .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), | |
| 1248 | 1227 | .@"64" => if (atom.debugTombstoneValue(target.*, elf_file)) |value| |
| 1249 | try cwriter.writeInt(u64, value, .little) | |
| 1228 | try bw.writeInt(u64, value, .little) | |
| 1250 | 1229 | else |
| 1251 | try cwriter.writeInt(i64, S + A, .little), | |
| 1230 | try bw.writeInt(i64, S + A, .little), | |
| 1252 | 1231 | .DTPOFF32 => if (atom.debugTombstoneValue(target.*, elf_file)) |value| |
| 1253 | try cwriter.writeInt(u64, value, .little) | |
| 1232 | try bw.writeInt(u64, value, .little) | |
| 1254 | 1233 | 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), | |
| 1256 | 1235 | .DTPOFF64 => if (atom.debugTombstoneValue(target.*, elf_file)) |value| |
| 1257 | try cwriter.writeInt(u64, value, .little) | |
| 1236 | try bw.writeInt(u64, value, .little) | |
| 1258 | 1237 | 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), | |
| 1262 | 1241 | .SIZE32 => { |
| 1263 | 1242 | 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); | |
| 1265 | 1244 | }, |
| 1266 | 1245 | .SIZE64 => { |
| 1267 | 1246 | 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); | |
| 1269 | 1248 | }, |
| 1270 | 1249 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 1271 | 1250 | } |
| ... | ... | @@ -1285,7 +1264,7 @@ const x86_64 = struct { |
| 1285 | 1264 | }, t), |
| 1286 | 1265 | else => return error.RelaxFailure, |
| 1287 | 1266 | }; |
| 1288 | relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding }); | |
| 1267 | relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding }); | |
| 1289 | 1268 | const nop: Instruction = try .new(.none, .nop, &.{}, t); |
| 1290 | 1269 | try encode(&.{ nop, inst }, code); |
| 1291 | 1270 | } |
| ... | ... | @@ -1296,7 +1275,7 @@ const x86_64 = struct { |
| 1296 | 1275 | switch (old_inst.encoding.mnemonic) { |
| 1297 | 1276 | .mov => { |
| 1298 | 1277 | 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 }); | |
| 1300 | 1279 | try encode(&.{inst}, code); |
| 1301 | 1280 | }, |
| 1302 | 1281 | else => return error.RelaxFailure, |
| ... | ... | @@ -1308,12 +1287,11 @@ const x86_64 = struct { |
| 1308 | 1287 | rels: []const elf.Elf64_Rela, |
| 1309 | 1288 | value: i32, |
| 1310 | 1289 | elf_file: *Elf, |
| 1311 | stream: anytype, | |
| 1290 | bw: *std.io.BufferedWriter, | |
| 1312 | 1291 | ) !void { |
| 1313 | 1292 | dev.check(.x86_64_backend); |
| 1314 | 1293 | assert(rels.len == 2); |
| 1315 | 1294 | const diags = &elf_file.base.comp.link_diags; |
| 1316 | const writer = stream.writer(); | |
| 1317 | 1295 | const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type()); |
| 1318 | 1296 | switch (rel) { |
| 1319 | 1297 | .PC32, |
| ... | ... | @@ -1324,17 +1302,17 @@ const x86_64 = struct { |
| 1324 | 1302 | 0x48, 0x03, 0x05, 0, 0, 0, 0, // add foo@gottpoff(%rip), %rax |
| 1325 | 1303 | }; |
| 1326 | 1304 | 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); | |
| 1329 | 1307 | }, |
| 1330 | 1308 | |
| 1331 | 1309 | else => { |
| 1332 | 1310 | 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}", .{ | |
| 1334 | 1312 | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1335 | 1313 | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1336 | 1314 | }); |
| 1337 | err.addNote("in {}:{s} at offset 0x{x}", .{ | |
| 1315 | err.addNote("in {f}:{s} at offset 0x{x}", .{ | |
| 1338 | 1316 | self.file(elf_file).?.fmtPath(), |
| 1339 | 1317 | self.name(elf_file), |
| 1340 | 1318 | rels[0].r_offset, |
| ... | ... | @@ -1349,12 +1327,11 @@ const x86_64 = struct { |
| 1349 | 1327 | rels: []const elf.Elf64_Rela, |
| 1350 | 1328 | value: i32, |
| 1351 | 1329 | elf_file: *Elf, |
| 1352 | stream: anytype, | |
| 1330 | bw: *std.io.BufferedWriter, | |
| 1353 | 1331 | ) !void { |
| 1354 | 1332 | dev.check(.x86_64_backend); |
| 1355 | 1333 | assert(rels.len == 2); |
| 1356 | 1334 | const diags = &elf_file.base.comp.link_diags; |
| 1357 | const writer = stream.writer(); | |
| 1358 | 1335 | const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type()); |
| 1359 | 1336 | switch (rel) { |
| 1360 | 1337 | .PC32, |
| ... | ... | @@ -1366,8 +1343,8 @@ const x86_64 = struct { |
| 1366 | 1343 | 0x48, 0x2d, 0, 0, 0, 0, // sub $tls_size, %rax |
| 1367 | 1344 | }; |
| 1368 | 1345 | 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); | |
| 1371 | 1348 | }, |
| 1372 | 1349 | |
| 1373 | 1350 | .GOTPCREL, |
| ... | ... | @@ -1380,17 +1357,17 @@ const x86_64 = struct { |
| 1380 | 1357 | 0x90, // nop |
| 1381 | 1358 | }; |
| 1382 | 1359 | 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); | |
| 1385 | 1362 | }, |
| 1386 | 1363 | |
| 1387 | 1364 | else => { |
| 1388 | 1365 | 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}", .{ | |
| 1390 | 1367 | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1391 | 1368 | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1392 | 1369 | }); |
| 1393 | err.addNote("in {}:{s} at offset 0x{x}", .{ | |
| 1370 | err.addNote("in {f}:{s} at offset 0x{x}", .{ | |
| 1394 | 1371 | self.file(elf_file).?.fmtPath(), |
| 1395 | 1372 | self.name(elf_file), |
| 1396 | 1373 | rels[0].r_offset, |
| ... | ... | @@ -1410,7 +1387,12 @@ const x86_64 = struct { |
| 1410 | 1387 | // TODO: hack to force imm32s in the assembler |
| 1411 | 1388 | .{ .imm = .s(-129) }, |
| 1412 | 1389 | }, 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; | |
| 1414 | 1396 | return true; |
| 1415 | 1397 | }, |
| 1416 | 1398 | else => return false, |
| ... | ... | @@ -1427,7 +1409,7 @@ const x86_64 = struct { |
| 1427 | 1409 | // TODO: hack to force imm32s in the assembler |
| 1428 | 1410 | .{ .imm = .s(-129) }, |
| 1429 | 1411 | }, 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 }); | |
| 1431 | 1413 | encode(&.{inst}, code) catch unreachable; |
| 1432 | 1414 | }, |
| 1433 | 1415 | else => unreachable, |
| ... | ... | @@ -1444,7 +1426,7 @@ const x86_64 = struct { |
| 1444 | 1426 | // TODO: hack to force imm32s in the assembler |
| 1445 | 1427 | .{ .imm = .s(-129) }, |
| 1446 | 1428 | }, target); |
| 1447 | relocs_log.debug(" relaxing {} => {}", .{ old_inst.encoding, inst.encoding }); | |
| 1429 | relocs_log.debug(" relaxing {f} => {f}", .{ old_inst.encoding, inst.encoding }); | |
| 1448 | 1430 | try encode(&.{inst}, code); |
| 1449 | 1431 | }, |
| 1450 | 1432 | else => return error.RelaxFailure, |
| ... | ... | @@ -1456,12 +1438,11 @@ const x86_64 = struct { |
| 1456 | 1438 | rels: []const elf.Elf64_Rela, |
| 1457 | 1439 | value: i32, |
| 1458 | 1440 | elf_file: *Elf, |
| 1459 | stream: anytype, | |
| 1441 | bw: *std.io.BufferedWriter, | |
| 1460 | 1442 | ) !void { |
| 1461 | 1443 | dev.check(.x86_64_backend); |
| 1462 | 1444 | assert(rels.len == 2); |
| 1463 | 1445 | const diags = &elf_file.base.comp.link_diags; |
| 1464 | const writer = stream.writer(); | |
| 1465 | 1446 | const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type()); |
| 1466 | 1447 | switch (rel) { |
| 1467 | 1448 | .PC32, |
| ... | ... | @@ -1474,9 +1455,9 @@ const x86_64 = struct { |
| 1474 | 1455 | 0x48, 0x81, 0xc0, 0, 0, 0, 0, // add $tp_offset, %rax |
| 1475 | 1456 | }; |
| 1476 | 1457 | 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}", .{ | |
| 1480 | 1461 | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1481 | 1462 | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1482 | 1463 | }); |
| ... | ... | @@ -1484,11 +1465,11 @@ const x86_64 = struct { |
| 1484 | 1465 | |
| 1485 | 1466 | else => { |
| 1486 | 1467 | 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}", .{ | |
| 1488 | 1469 | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1489 | 1470 | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1490 | 1471 | }); |
| 1491 | err.addNote("in {}:{s} at offset 0x{x}", .{ | |
| 1472 | err.addNote("in {f}:{s} at offset 0x{x}", .{ | |
| 1492 | 1473 | self.file(elf_file).?.fmtPath(), |
| 1493 | 1474 | self.name(elf_file), |
| 1494 | 1475 | rels[0].r_offset, |
| ... | ... | @@ -1505,11 +1486,9 @@ const x86_64 = struct { |
| 1505 | 1486 | } |
| 1506 | 1487 | |
| 1507 | 1488 | 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, .{}); | |
| 1513 | 1492 | } |
| 1514 | 1493 | |
| 1515 | 1494 | const bits = @import("../../arch/x86_64/bits.zig"); |
| ... | ... | @@ -1613,16 +1592,14 @@ const aarch64 = struct { |
| 1613 | 1592 | target: *const Symbol, |
| 1614 | 1593 | args: ResolveArgs, |
| 1615 | 1594 | it: *RelocsIterator, |
| 1616 | code_buffer: []u8, | |
| 1617 | stream: anytype, | |
| 1618 | ) (error{ UnexpectedRemainder, DivisionByZero } || RelocError)!void { | |
| 1595 | bw: *std.io.BufferedWriter, | |
| 1596 | ) anyerror!void { | |
| 1619 | 1597 | _ = it; |
| 1620 | 1598 | |
| 1621 | 1599 | const diags = &elf_file.base.comp.link_diags; |
| 1622 | 1600 | const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type()); |
| 1623 | 1601 | 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]; | |
| 1626 | 1603 | const file_ptr = atom.file(elf_file).?; |
| 1627 | 1604 | |
| 1628 | 1605 | const P, const A, const S, const GOT, const G, const TP, const DTP = args; |
| ... | ... | @@ -1636,7 +1613,7 @@ const aarch64 = struct { |
| 1636 | 1613 | rel, |
| 1637 | 1614 | dynAbsRelocAction(target, elf_file), |
| 1638 | 1615 | elf_file, |
| 1639 | cwriter, | |
| 1616 | bw, | |
| 1640 | 1617 | ); |
| 1641 | 1618 | }, |
| 1642 | 1619 | |
| ... | ... | @@ -1649,17 +1626,17 @@ const aarch64 = struct { |
| 1649 | 1626 | const S_ = th.targetAddress(target_index, elf_file); |
| 1650 | 1627 | break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow; |
| 1651 | 1628 | }; |
| 1652 | aarch64_util.writeBranchImm(disp, code); | |
| 1629 | aarch64_util.writeBranchImm(disp, (try bw.writableSlice(4))[0..4]); | |
| 1653 | 1630 | }, |
| 1654 | 1631 | |
| 1655 | 1632 | .PREL32 => { |
| 1656 | 1633 | 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); | |
| 1658 | 1635 | }, |
| 1659 | 1636 | |
| 1660 | 1637 | .PREL64 => { |
| 1661 | 1638 | 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); | |
| 1663 | 1640 | }, |
| 1664 | 1641 | |
| 1665 | 1642 | .ADR_PREL_PG_HI21 => { |
| ... | ... | @@ -1675,7 +1652,7 @@ const aarch64 = struct { |
| 1675 | 1652 | // TODO: relax |
| 1676 | 1653 | var err = try diags.addErrorWithNotes(1); |
| 1677 | 1654 | 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}", .{ | |
| 1679 | 1656 | atom.file(elf_file).?.fmtPath(), |
| 1680 | 1657 | atom.name(elf_file), |
| 1681 | 1658 | r_offset, |
| ... | ... | @@ -1818,25 +1795,18 @@ const aarch64 = struct { |
| 1818 | 1795 | rel: elf.Elf64_Rela, |
| 1819 | 1796 | target: *const Symbol, |
| 1820 | 1797 | args: ResolveArgs, |
| 1821 | it: *RelocsIterator, | |
| 1822 | code: []u8, | |
| 1823 | stream: anytype, | |
| 1798 | bw: *std.io.BufferedWriter, | |
| 1824 | 1799 | ) !void { |
| 1825 | _ = it; | |
| 1826 | _ = code; | |
| 1827 | ||
| 1828 | 1800 | const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type()); |
| 1829 | const cwriter = stream.writer(); | |
| 1830 | ||
| 1831 | 1801 | _, const A, const S, _, _, _, _ = args; |
| 1832 | 1802 | |
| 1833 | 1803 | switch (r_type) { |
| 1834 | 1804 | .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), | |
| 1836 | 1806 | .ABS64 => if (atom.debugTombstoneValue(target.*, elf_file)) |value| |
| 1837 | try cwriter.writeInt(u64, value, .little) | |
| 1807 | try bw.writeInt(u64, value, .little) | |
| 1838 | 1808 | else |
| 1839 | try cwriter.writeInt(i64, S + A, .little), | |
| 1809 | try bw.writeInt(i64, S + A, .little), | |
| 1840 | 1810 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 1841 | 1811 | } |
| 1842 | 1812 | } |
| ... | ... | @@ -1898,13 +1868,10 @@ const riscv = struct { |
| 1898 | 1868 | target: *const Symbol, |
| 1899 | 1869 | args: ResolveArgs, |
| 1900 | 1870 | it: *RelocsIterator, |
| 1901 | code: []u8, | |
| 1902 | stream: anytype, | |
| 1871 | bw: *std.io.BufferedWriter, | |
| 1903 | 1872 | ) !void { |
| 1904 | 1873 | const diags = &elf_file.base.comp.link_diags; |
| 1905 | 1874 | 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(); | |
| 1908 | 1875 | |
| 1909 | 1876 | const P, const A, const S, const GOT, const G, const TP, const DTP = args; |
| 1910 | 1877 | _ = TP; |
| ... | ... | @@ -1913,7 +1880,7 @@ const riscv = struct { |
| 1913 | 1880 | switch (r_type) { |
| 1914 | 1881 | .NONE => unreachable, |
| 1915 | 1882 | |
| 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), | |
| 1917 | 1884 | |
| 1918 | 1885 | .@"64" => { |
| 1919 | 1886 | try atom.resolveDynAbsReloc( |
| ... | ... | @@ -1921,34 +1888,35 @@ const riscv = struct { |
| 1921 | 1888 | rel, |
| 1922 | 1889 | dynAbsRelocAction(target, elf_file), |
| 1923 | 1890 | elf_file, |
| 1924 | cwriter, | |
| 1891 | bw, | |
| 1925 | 1892 | ); |
| 1926 | 1893 | }, |
| 1927 | 1894 | |
| 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), | |
| 1930 | 1897 | |
| 1931 | 1898 | .HI20 => { |
| 1932 | 1899 | 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); | |
| 1934 | 1901 | }, |
| 1935 | 1902 | |
| 1936 | 1903 | .GOT_HI20 => { |
| 1937 | 1904 | assert(target.flags.has_got); |
| 1938 | 1905 | 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); | |
| 1940 | 1907 | }, |
| 1941 | 1908 | |
| 1942 | 1909 | .CALL_PLT => { |
| 1943 | 1910 | // TODO: relax |
| 1944 | 1911 | 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 | |
| 1947 | 1915 | }, |
| 1948 | 1916 | |
| 1949 | 1917 | .PCREL_HI20 => { |
| 1950 | 1918 | 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); | |
| 1952 | 1920 | }, |
| 1953 | 1921 | |
| 1954 | 1922 | .PCREL_LO12_I, |
| ... | ... | @@ -1965,7 +1933,7 @@ const riscv = struct { |
| 1965 | 1933 | // TODO: implement searching forward |
| 1966 | 1934 | var err = try diags.addErrorWithNotes(1); |
| 1967 | 1935 | 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}", .{ | |
| 1969 | 1937 | atom.file(elf_file).?.fmtPath(), |
| 1970 | 1938 | atom.name(elf_file), |
| 1971 | 1939 | rel.r_offset, |
| ... | ... | @@ -1986,8 +1954,8 @@ const riscv = struct { |
| 1986 | 1954 | }; |
| 1987 | 1955 | relocs_log.debug(" [{x} => {x}]", .{ P_, disp + P_ }); |
| 1988 | 1956 | 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)), | |
| 1991 | 1959 | else => unreachable, |
| 1992 | 1960 | } |
| 1993 | 1961 | }, |
| ... | ... | @@ -1997,8 +1965,8 @@ const riscv = struct { |
| 1997 | 1965 | => { |
| 1998 | 1966 | const disp: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow); |
| 1999 | 1967 | 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), | |
| 2002 | 1970 | else => unreachable, |
| 2003 | 1971 | } |
| 2004 | 1972 | }, |
| ... | ... | @@ -2006,7 +1974,7 @@ const riscv = struct { |
| 2006 | 1974 | .TPREL_HI20 => { |
| 2007 | 1975 | const target_addr: u32 = @intCast(target.address(.{}, elf_file)); |
| 2008 | 1976 | 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)); | |
| 2010 | 1978 | }, |
| 2011 | 1979 | |
| 2012 | 1980 | .TPREL_LO12_I, |
| ... | ... | @@ -2015,8 +1983,8 @@ const riscv = struct { |
| 2015 | 1983 | const target_addr: u32 = @intCast(target.address(.{}, elf_file)); |
| 2016 | 1984 | const val: i32 = @intCast(S + A - target_addr); |
| 2017 | 1985 | 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)), | |
| 2020 | 1988 | else => unreachable, |
| 2021 | 1989 | } |
| 2022 | 1990 | }, |
| ... | ... | @@ -2035,15 +2003,9 @@ const riscv = struct { |
| 2035 | 2003 | rel: elf.Elf64_Rela, |
| 2036 | 2004 | target: *const Symbol, |
| 2037 | 2005 | args: ResolveArgs, |
| 2038 | it: *RelocsIterator, | |
| 2039 | code: []u8, | |
| 2040 | stream: anytype, | |
| 2041 | ) !void { | |
| 2042 | _ = it; | |
| 2043 | ||
| 2006 | bw: *std.io.BufferedWriter, | |
| 2007 | ) anyerror!void { | |
| 2044 | 2008 | 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(); | |
| 2047 | 2009 | |
| 2048 | 2010 | _, const A, const S, const GOT, _, _, const DTP = args; |
| 2049 | 2011 | _ = GOT; |
| ... | ... | @@ -2052,30 +2014,30 @@ const riscv = struct { |
| 2052 | 2014 | switch (r_type) { |
| 2053 | 2015 | .NONE => unreachable, |
| 2054 | 2016 | |
| 2055 | .@"32" => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little), | |
| 2017 | .@"32" => try bw.writeInt(i32, @as(i32, @intCast(S + A)), .little), | |
| 2056 | 2018 | .@"64" => if (atom.debugTombstoneValue(target.*, elf_file)) |value| |
| 2057 | try cwriter.writeInt(u64, value, .little) | |
| 2019 | try bw.writeInt(u64, value, .little) | |
| 2058 | 2020 | 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), | |
| 2079 | 2041 | |
| 2080 | 2042 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 2081 | 2043 | } |
src/link/Elf/AtomList.zig+10-22| ... | ... | @@ -108,7 +108,7 @@ pub fn write(list: AtomList, buffer: *std.ArrayList(u8), undefs: anytype, elf_fi |
| 108 | 108 | const off = math.cast(usize, atom_ptr.value - list.value) orelse return error.Overflow; |
| 109 | 109 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; |
| 110 | 110 | |
| 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 }); | |
| 112 | 112 | |
| 113 | 113 | const object = atom_ptr.file(elf_file).?.object; |
| 114 | 114 | 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 |
| 144 | 144 | const off = math.cast(usize, atom_ptr.value - list.value) orelse return error.Overflow; |
| 145 | 145 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; |
| 146 | 146 | |
| 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 }); | |
| 148 | 148 | |
| 149 | 149 | const object = atom_ptr.file(elf_file).?.object; |
| 150 | 150 | const code = try object.codeDecompressAlloc(elf_file, ref.index); |
| ... | ... | @@ -167,16 +167,10 @@ pub fn lastAtom(list: AtomList, elf_file: *Elf) *Atom { |
| 167 | 167 | return elf_file.atom(list.atoms.keys()[list.atoms.keys().len - 1]).?; |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | pub fn format( | |
| 171 | list: AtomList, | |
| 172 | comptime unused_fmt_string: []const u8, | |
| 173 | options: std.fmt.FormatOptions, | |
| 174 | writer: anytype, | |
| 175 | ) !void { | |
| 170 | pub fn format(list: AtomList, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 176 | 171 | _ = list; |
| 172 | _ = bw; | |
| 177 | 173 | _ = unused_fmt_string; |
| 178 | _ = options; | |
| 179 | _ = writer; | |
| 180 | 174 | @compileError("do not format AtomList directly"); |
| 181 | 175 | } |
| 182 | 176 | |
| ... | ... | @@ -186,25 +180,19 @@ pub fn fmt(list: AtomList, elf_file: *Elf) std.fmt.Formatter(format2) { |
| 186 | 180 | return .{ .data = .{ list, elf_file } }; |
| 187 | 181 | } |
| 188 | 182 | |
| 189 | fn format2( | |
| 190 | ctx: FormatCtx, | |
| 191 | comptime unused_fmt_string: []const u8, | |
| 192 | options: std.fmt.FormatOptions, | |
| 193 | writer: anytype, | |
| 194 | ) !void { | |
| 183 | fn format2(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 195 | 184 | _ = unused_fmt_string; |
| 196 | _ = options; | |
| 197 | 185 | 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})", .{ | |
| 199 | 187 | list.address(elf_file), list.output_section_index, |
| 200 | 188 | list.alignment.toByteUnits() orelse 0, list.size, |
| 201 | 189 | }); |
| 202 | try writer.writeAll(" : atoms{ "); | |
| 190 | try bw.writeAll(" : atoms{ "); | |
| 203 | 191 | 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(", "); | |
| 206 | 194 | } |
| 207 | try writer.writeAll(" }"); | |
| 195 | try bw.writeAll(" }"); | |
| 208 | 196 | } |
| 209 | 197 | |
| 210 | 198 | const assert = std.debug.assert; |
src/link/Elf/LinkerDefined.zig+4-10| ... | ... | @@ -449,23 +449,17 @@ const FormatContext = struct { |
| 449 | 449 | elf_file: *Elf, |
| 450 | 450 | }; |
| 451 | 451 | |
| 452 | fn formatSymtab( | |
| 453 | ctx: FormatContext, | |
| 454 | comptime unused_fmt_string: []const u8, | |
| 455 | options: std.fmt.FormatOptions, | |
| 456 | writer: anytype, | |
| 457 | ) !void { | |
| 452 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 458 | 453 | _ = unused_fmt_string; |
| 459 | _ = options; | |
| 460 | 454 | const self = ctx.self; |
| 461 | 455 | const elf_file = ctx.elf_file; |
| 462 | try writer.writeAll(" globals\n"); | |
| 456 | try bw.writeAll(" globals\n"); | |
| 463 | 457 | for (self.symbols.items, 0..) |sym, i| { |
| 464 | 458 | const ref = self.resolveSymbol(@intCast(i), elf_file); |
| 465 | 459 | 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)}); | |
| 467 | 461 | } else { |
| 468 | try writer.print(" {s} : unclaimed\n", .{sym.name(elf_file)}); | |
| 462 | try bw.print(" {s} : unclaimed\n", .{sym.name(elf_file)}); | |
| 469 | 463 | } |
| 470 | 464 | } |
| 471 | 465 | } |
src/link/Elf/Merge.zig+10-34| ... | ... | @@ -157,16 +157,10 @@ pub const Section = struct { |
| 157 | 157 | } |
| 158 | 158 | }; |
| 159 | 159 | |
| 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 { | |
| 166 | 161 | _ = msec; |
| 162 | _ = bw; | |
| 167 | 163 | _ = unused_fmt_string; |
| 168 | _ = options; | |
| 169 | _ = writer; | |
| 170 | 164 | @compileError("do not format directly"); |
| 171 | 165 | } |
| 172 | 166 | |
| ... | ... | @@ -182,17 +176,11 @@ pub const Section = struct { |
| 182 | 176 | elf_file: *Elf, |
| 183 | 177 | }; |
| 184 | 178 | |
| 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 { | |
| 192 | 180 | _ = unused_fmt_string; |
| 193 | 181 | const msec = ctx.msec; |
| 194 | 182 | 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", .{ | |
| 196 | 184 | msec.name(elf_file), |
| 197 | 185 | msec.address(elf_file), |
| 198 | 186 | msec.size, |
| ... | ... | @@ -202,7 +190,7 @@ pub const Section = struct { |
| 202 | 190 | msec.flags, |
| 203 | 191 | }); |
| 204 | 192 | for (msec.subsections.items) |msub| { |
| 205 | try writer.print(" {}\n", .{msub.fmt(elf_file)}); | |
| 193 | try bw.print(" {f}\n", .{msub.fmt(elf_file)}); | |
| 206 | 194 | } |
| 207 | 195 | } |
| 208 | 196 | |
| ... | ... | @@ -231,16 +219,10 @@ pub const Subsection = struct { |
| 231 | 219 | return msec.bytes.items[msub.string_index..][0..msub.size]; |
| 232 | 220 | } |
| 233 | 221 | |
| 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 { | |
| 240 | 223 | _ = msub; |
| 224 | _ = bw; | |
| 241 | 225 | _ = unused_fmt_string; |
| 242 | _ = options; | |
| 243 | _ = writer; | |
| 244 | 226 | @compileError("do not format directly"); |
| 245 | 227 | } |
| 246 | 228 | |
| ... | ... | @@ -256,22 +238,16 @@ pub const Subsection = struct { |
| 256 | 238 | elf_file: *Elf, |
| 257 | 239 | }; |
| 258 | 240 | |
| 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 { | |
| 266 | 242 | _ = unused_fmt_string; |
| 267 | 243 | const msub = ctx.msub; |
| 268 | 244 | const elf_file = ctx.elf_file; |
| 269 | try writer.print("@{x} : align({x}) : size({x})", .{ | |
| 245 | try bw.print("@{x} : align({x}) : size({x})", .{ | |
| 270 | 246 | msub.address(elf_file), |
| 271 | 247 | msub.alignment, |
| 272 | 248 | msub.size, |
| 273 | 249 | }); |
| 274 | if (!msub.alive) try writer.writeAll(" : [*]"); | |
| 250 | if (!msub.alive) try bw.writeAll(" : [*]"); | |
| 275 | 251 | } |
| 276 | 252 | |
| 277 | 253 | pub const Index = u32; |
src/link/Elf/Object.zig+47-90| ... | ... | @@ -281,7 +281,7 @@ fn initAtoms( |
| 281 | 281 | elf.SHT_GROUP => { |
| 282 | 282 | if (shdr.sh_info >= self.symtab.items.len) { |
| 283 | 283 | // 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()}); | |
| 285 | 285 | continue; |
| 286 | 286 | } |
| 287 | 287 | const group_info_sym = self.symtab.items[shdr.sh_info]; |
| ... | ... | @@ -448,7 +448,8 @@ fn parseEhFrame( |
| 448 | 448 | const fdes_start = self.fdes.items.len; |
| 449 | 449 | const cies_start = self.cies.items.len; |
| 450 | 450 | |
| 451 | var it = eh_frame.Iterator{ .data = raw }; | |
| 451 | var it: eh_frame.Iterator = undefined; | |
| 452 | it.br.initFixed(raw); | |
| 452 | 453 | while (try it.next()) |rec| { |
| 453 | 454 | const rel_range = filterRelocs(self.relocs.items[rel_start..][0..relocs.len], rec.offset, rec.size + 4); |
| 454 | 455 | switch (rec.tag) { |
| ... | ... | @@ -488,7 +489,7 @@ fn parseEhFrame( |
| 488 | 489 | if (cie.offset == cie_ptr) break @as(u32, @intCast(cie_index)); |
| 489 | 490 | } else { |
| 490 | 491 | // 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}", .{ | |
| 492 | 493 | self.fmtPath(), |
| 493 | 494 | fde.offset, |
| 494 | 495 | }); |
| ... | ... | @@ -582,7 +583,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { |
| 582 | 583 | if (sym.flags.import) { |
| 583 | 584 | if (sym.type(elf_file) != elf.STT_FUNC) |
| 584 | 585 | // 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", .{ | |
| 586 | 587 | self.fmtPath(), sym.name(elf_file), |
| 587 | 588 | }); |
| 588 | 589 | sym.flags.needs_plt = true; |
| ... | ... | @@ -796,7 +797,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 796 | 797 | if (!isNull(data[end .. end + sh_entsize])) { |
| 797 | 798 | var err = try diags.addErrorWithNotes(1); |
| 798 | 799 | 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) }); | |
| 800 | 801 | return error.LinkFailure; |
| 801 | 802 | } |
| 802 | 803 | end += sh_entsize; |
| ... | ... | @@ -811,7 +812,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 811 | 812 | if (shdr.sh_size % sh_entsize != 0) { |
| 812 | 813 | var err = try diags.addErrorWithNotes(1); |
| 813 | 814 | 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) }); | |
| 815 | 816 | return error.LinkFailure; |
| 816 | 817 | } |
| 817 | 818 | |
| ... | ... | @@ -889,7 +890,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 889 | 890 | var err = try diags.addErrorWithNotes(2); |
| 890 | 891 | try err.addMsg("invalid symbol value: {x}", .{esym.st_value}); |
| 891 | 892 | err.addNote("for symbol {s}", .{sym.name(elf_file)}); |
| 892 | err.addNote("in {}", .{self.fmtPath()}); | |
| 893 | err.addNote("in {f}", .{self.fmtPath()}); | |
| 893 | 894 | return error.LinkFailure; |
| 894 | 895 | }; |
| 895 | 896 | |
| ... | ... | @@ -914,7 +915,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 914 | 915 | const res = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse { |
| 915 | 916 | var err = try diags.addErrorWithNotes(1); |
| 916 | 917 | 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) }); | |
| 918 | 919 | return error.LinkFailure; |
| 919 | 920 | }; |
| 920 | 921 | |
| ... | ... | @@ -952,7 +953,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { |
| 952 | 953 | const is_tls = sym.type(elf_file) == elf.STT_TLS; |
| 953 | 954 | const name = if (is_tls) ".tls_common" else ".common"; |
| 954 | 955 | 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}); | |
| 956 | 957 | |
| 957 | 958 | var sh_flags: u32 = elf.SHF_ALLOC | elf.SHF_WRITE; |
| 958 | 959 | if (is_tls) sh_flags |= elf.SHF_TLS; |
| ... | ... | @@ -1191,28 +1192,26 @@ pub fn codeDecompressAlloc(self: *Object, elf_file: *Elf, atom_index: Atom.Index |
| 1191 | 1192 | const atom_ptr = self.atom(atom_index).?; |
| 1192 | 1193 | const shdr = atom_ptr.inputShdr(elf_file); |
| 1193 | 1194 | 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()); | |
| 1196 | 1198 | |
| 1197 | 1199 | 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)).*; | |
| 1199 | 1201 | switch (chdr.ch_type) { |
| 1200 | 1202 | .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; | |
| 1210 | 1209 | }, |
| 1211 | 1210 | else => @panic("TODO unhandled compression scheme"), |
| 1212 | 1211 | } |
| 1213 | 1212 | } |
| 1214 | 1213 | |
| 1215 | return data; | |
| 1214 | return br.storageBuffer(); | |
| 1216 | 1215 | } |
| 1217 | 1216 | |
| 1218 | 1217 | fn locals(self: *Object) []Symbol { |
| ... | ... | @@ -1432,16 +1431,10 @@ pub fn group(self: *Object, index: Elf.Group.Index) *Elf.Group { |
| 1432 | 1431 | return &self.groups.items[index]; |
| 1433 | 1432 | } |
| 1434 | 1433 | |
| 1435 | pub fn format( | |
| 1436 | self: *Object, | |
| 1437 | comptime unused_fmt_string: []const u8, | |
| 1438 | options: std.fmt.FormatOptions, | |
| 1439 | writer: anytype, | |
| 1440 | ) !void { | |
| 1434 | pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1441 | 1435 | _ = self; |
| 1436 | _ = bw; | |
| 1442 | 1437 | _ = unused_fmt_string; |
| 1443 | _ = options; | |
| 1444 | _ = writer; | |
| 1445 | 1438 | @compileError("do not format objects directly"); |
| 1446 | 1439 | } |
| 1447 | 1440 | |
| ... | ... | @@ -1457,28 +1450,22 @@ const FormatContext = struct { |
| 1457 | 1450 | elf_file: *Elf, |
| 1458 | 1451 | }; |
| 1459 | 1452 | |
| 1460 | fn formatSymtab( | |
| 1461 | ctx: FormatContext, | |
| 1462 | comptime unused_fmt_string: []const u8, | |
| 1463 | options: std.fmt.FormatOptions, | |
| 1464 | writer: anytype, | |
| 1465 | ) !void { | |
| 1453 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1466 | 1454 | _ = unused_fmt_string; |
| 1467 | _ = options; | |
| 1468 | 1455 | const object = ctx.object; |
| 1469 | 1456 | const elf_file = ctx.elf_file; |
| 1470 | try writer.writeAll(" locals\n"); | |
| 1457 | try bw.writeAll(" locals\n"); | |
| 1471 | 1458 | for (object.locals()) |sym| { |
| 1472 | try writer.print(" {}\n", .{sym.fmt(elf_file)}); | |
| 1459 | try bw.print(" {f}\n", .{sym.fmt(elf_file)}); | |
| 1473 | 1460 | } |
| 1474 | try writer.writeAll(" globals\n"); | |
| 1461 | try bw.writeAll(" globals\n"); | |
| 1475 | 1462 | for (object.globals(), 0..) |sym, i| { |
| 1476 | 1463 | const first_global = object.first_global.?; |
| 1477 | 1464 | const ref = object.resolveSymbol(@intCast(i + first_global), elf_file); |
| 1478 | 1465 | 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)}); | |
| 1480 | 1467 | } else { |
| 1481 | try writer.print(" {s} : unclaimed\n", .{sym.name(elf_file)}); | |
| 1468 | try bw.print(" {s} : unclaimed\n", .{sym.name(elf_file)}); | |
| 1482 | 1469 | } |
| 1483 | 1470 | } |
| 1484 | 1471 | } |
| ... | ... | @@ -1490,19 +1477,13 @@ pub fn fmtAtoms(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatAtoms) { |
| 1490 | 1477 | } }; |
| 1491 | 1478 | } |
| 1492 | 1479 | |
| 1493 | fn formatAtoms( | |
| 1494 | ctx: FormatContext, | |
| 1495 | comptime unused_fmt_string: []const u8, | |
| 1496 | options: std.fmt.FormatOptions, | |
| 1497 | writer: anytype, | |
| 1498 | ) !void { | |
| 1480 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1499 | 1481 | _ = unused_fmt_string; |
| 1500 | _ = options; | |
| 1501 | 1482 | const object = ctx.object; |
| 1502 | try writer.writeAll(" atoms\n"); | |
| 1483 | try bw.writeAll(" atoms\n"); | |
| 1503 | 1484 | for (object.atoms_indexes.items) |atom_index| { |
| 1504 | 1485 | 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)}); | |
| 1506 | 1487 | } |
| 1507 | 1488 | } |
| 1508 | 1489 | |
| ... | ... | @@ -1513,18 +1494,12 @@ pub fn fmtCies(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatCies) { |
| 1513 | 1494 | } }; |
| 1514 | 1495 | } |
| 1515 | 1496 | |
| 1516 | fn formatCies( | |
| 1517 | ctx: FormatContext, | |
| 1518 | comptime unused_fmt_string: []const u8, | |
| 1519 | options: std.fmt.FormatOptions, | |
| 1520 | writer: anytype, | |
| 1521 | ) !void { | |
| 1497 | fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1522 | 1498 | _ = unused_fmt_string; |
| 1523 | _ = options; | |
| 1524 | 1499 | const object = ctx.object; |
| 1525 | try writer.writeAll(" cies\n"); | |
| 1500 | try bw.writeAll(" cies\n"); | |
| 1526 | 1501 | 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) }); | |
| 1528 | 1503 | } |
| 1529 | 1504 | } |
| 1530 | 1505 | |
| ... | ... | @@ -1535,18 +1510,12 @@ pub fn fmtFdes(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatFdes) { |
| 1535 | 1510 | } }; |
| 1536 | 1511 | } |
| 1537 | 1512 | |
| 1538 | fn formatFdes( | |
| 1539 | ctx: FormatContext, | |
| 1540 | comptime unused_fmt_string: []const u8, | |
| 1541 | options: std.fmt.FormatOptions, | |
| 1542 | writer: anytype, | |
| 1543 | ) !void { | |
| 1513 | fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1544 | 1514 | _ = unused_fmt_string; |
| 1545 | _ = options; | |
| 1546 | 1515 | const object = ctx.object; |
| 1547 | try writer.writeAll(" fdes\n"); | |
| 1516 | try bw.writeAll(" fdes\n"); | |
| 1548 | 1517 | 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) }); | |
| 1550 | 1519 | } |
| 1551 | 1520 | } |
| 1552 | 1521 | |
| ... | ... | @@ -1557,26 +1526,20 @@ pub fn fmtGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatGroups) |
| 1557 | 1526 | } }; |
| 1558 | 1527 | } |
| 1559 | 1528 | |
| 1560 | fn formatGroups( | |
| 1561 | ctx: FormatContext, | |
| 1562 | comptime unused_fmt_string: []const u8, | |
| 1563 | options: std.fmt.FormatOptions, | |
| 1564 | writer: anytype, | |
| 1565 | ) !void { | |
| 1529 | fn formatGroups(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1566 | 1530 | _ = unused_fmt_string; |
| 1567 | _ = options; | |
| 1568 | 1531 | const object = ctx.object; |
| 1569 | 1532 | const elf_file = ctx.elf_file; |
| 1570 | try writer.writeAll(" groups\n"); | |
| 1533 | try bw.writeAll(" groups\n"); | |
| 1571 | 1534 | 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'); | |
| 1575 | 1538 | const g_members = g.members(elf_file); |
| 1576 | 1539 | for (g_members) |shndx| { |
| 1577 | 1540 | const atom_index = object.atoms_indexes.items[shndx]; |
| 1578 | 1541 | 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) }); | |
| 1580 | 1543 | } |
| 1581 | 1544 | } |
| 1582 | 1545 | } |
| ... | ... | @@ -1585,18 +1548,12 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) { |
| 1585 | 1548 | return .{ .data = self }; |
| 1586 | 1549 | } |
| 1587 | 1550 | |
| 1588 | fn formatPath( | |
| 1589 | object: Object, | |
| 1590 | comptime unused_fmt_string: []const u8, | |
| 1591 | options: std.fmt.FormatOptions, | |
| 1592 | writer: anytype, | |
| 1593 | ) !void { | |
| 1551 | fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1594 | 1552 | _ = unused_fmt_string; |
| 1595 | _ = options; | |
| 1596 | 1553 | if (object.archive) |ar| { |
| 1597 | try writer.print("{}({})", .{ ar.path, object.path }); | |
| 1554 | try bw.print("{f}({f})", .{ ar.path, object.path }); | |
| 1598 | 1555 | } else { |
| 1599 | try writer.print("{}", .{object.path}); | |
| 1556 | try bw.print("{f}", .{object.path}); | |
| 1600 | 1557 | } |
| 1601 | 1558 | } |
| 1602 | 1559 |
src/link/Elf/SharedObject.zig+6-18| ... | ... | @@ -509,16 +509,10 @@ pub fn setSymbolExtra(self: *SharedObject, index: u32, extra: Symbol.Extra) void |
| 509 | 509 | } |
| 510 | 510 | } |
| 511 | 511 | |
| 512 | pub fn format( | |
| 513 | self: SharedObject, | |
| 514 | comptime unused_fmt_string: []const u8, | |
| 515 | options: std.fmt.FormatOptions, | |
| 516 | writer: anytype, | |
| 517 | ) !void { | |
| 512 | pub fn format(self: SharedObject, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 518 | 513 | _ = self; |
| 514 | _ = bw; | |
| 519 | 515 | _ = unused_fmt_string; |
| 520 | _ = options; | |
| 521 | _ = writer; | |
| 522 | 516 | @compileError("unreachable"); |
| 523 | 517 | } |
| 524 | 518 | |
| ... | ... | @@ -534,23 +528,17 @@ const FormatContext = struct { |
| 534 | 528 | elf_file: *Elf, |
| 535 | 529 | }; |
| 536 | 530 | |
| 537 | fn formatSymtab( | |
| 538 | ctx: FormatContext, | |
| 539 | comptime unused_fmt_string: []const u8, | |
| 540 | options: std.fmt.FormatOptions, | |
| 541 | writer: anytype, | |
| 542 | ) !void { | |
| 531 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 543 | 532 | _ = unused_fmt_string; |
| 544 | _ = options; | |
| 545 | 533 | const shared = ctx.shared; |
| 546 | 534 | const elf_file = ctx.elf_file; |
| 547 | try writer.writeAll(" globals\n"); | |
| 535 | try bw.writeAll(" globals\n"); | |
| 548 | 536 | for (shared.symbols.items, 0..) |sym, i| { |
| 549 | 537 | const ref = shared.resolveSymbol(@intCast(i), elf_file); |
| 550 | 538 | 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)}); | |
| 552 | 540 | } else { |
| 553 | try writer.print(" {s} : unclaimed\n", .{sym.name(elf_file)}); | |
| 541 | try bw.print(" {s} : unclaimed\n", .{sym.name(elf_file)}); | |
| 554 | 542 | } |
| 555 | 543 | } |
| 556 | 544 | } |
src/link/Elf/Symbol.zig+15-33| ... | ... | @@ -316,16 +316,10 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 316 | 316 | out.st_size = esym.st_size; |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | pub fn format( | |
| 320 | symbol: Symbol, | |
| 321 | comptime unused_fmt_string: []const u8, | |
| 322 | options: std.fmt.FormatOptions, | |
| 323 | writer: anytype, | |
| 324 | ) !void { | |
| 319 | pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 325 | 320 | _ = symbol; |
| 321 | _ = bw; | |
| 326 | 322 | _ = unused_fmt_string; |
| 327 | _ = options; | |
| 328 | _ = writer; | |
| 329 | 323 | @compileError("do not format Symbol directly"); |
| 330 | 324 | } |
| 331 | 325 | |
| ... | ... | @@ -341,24 +335,18 @@ pub fn fmtName(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(formatName) { |
| 341 | 335 | } }; |
| 342 | 336 | } |
| 343 | 337 | |
| 344 | fn formatName( | |
| 345 | ctx: FormatContext, | |
| 346 | comptime unused_fmt_string: []const u8, | |
| 347 | options: std.fmt.FormatOptions, | |
| 348 | writer: anytype, | |
| 349 | ) !void { | |
| 350 | _ = options; | |
| 338 | fn formatName(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 351 | 339 | _ = unused_fmt_string; |
| 352 | 340 | const elf_file = ctx.elf_file; |
| 353 | 341 | const symbol = ctx.symbol; |
| 354 | try writer.writeAll(symbol.name(elf_file)); | |
| 342 | try bw.writeAll(symbol.name(elf_file)); | |
| 355 | 343 | switch (symbol.version_index.VERSION) { |
| 356 | 344 | @intFromEnum(elf.VER_NDX.LOCAL), @intFromEnum(elf.VER_NDX.GLOBAL) => {}, |
| 357 | 345 | else => { |
| 358 | 346 | const file_ptr = symbol.file(elf_file).?; |
| 359 | 347 | assert(file_ptr == .shared_object); |
| 360 | 348 | 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)}); | |
| 362 | 350 | }, |
| 363 | 351 | } |
| 364 | 352 | } |
| ... | ... | @@ -370,17 +358,11 @@ pub fn fmt(symbol: Symbol, elf_file: *Elf) std.fmt.Formatter(format2) { |
| 370 | 358 | } }; |
| 371 | 359 | } |
| 372 | 360 | |
| 373 | fn format2( | |
| 374 | ctx: FormatContext, | |
| 375 | comptime unused_fmt_string: []const u8, | |
| 376 | options: std.fmt.FormatOptions, | |
| 377 | writer: anytype, | |
| 378 | ) !void { | |
| 379 | _ = options; | |
| 361 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 380 | 362 | _ = unused_fmt_string; |
| 381 | 363 | const symbol = ctx.symbol; |
| 382 | 364 | const elf_file = ctx.elf_file; |
| 383 | try writer.print("%{d} : {s} : @{x}", .{ | |
| 365 | try bw.print("%{d} : {f} : @{x}", .{ | |
| 384 | 366 | symbol.esym_index, |
| 385 | 367 | symbol.fmtName(elf_file), |
| 386 | 368 | symbol.address(.{ .plt = false, .trampoline = false }, elf_file), |
| ... | ... | @@ -388,25 +370,25 @@ fn format2( |
| 388 | 370 | if (symbol.file(elf_file)) |file_ptr| { |
| 389 | 371 | if (symbol.isAbs(elf_file)) { |
| 390 | 372 | if (symbol.elfSym(elf_file).st_shndx == elf.SHN_UNDEF) { |
| 391 | try writer.writeAll(" : undef"); | |
| 373 | try bw.writeAll(" : undef"); | |
| 392 | 374 | } else { |
| 393 | try writer.writeAll(" : absolute"); | |
| 375 | try bw.writeAll(" : absolute"); | |
| 394 | 376 | } |
| 395 | 377 | } else if (symbol.outputShndx(elf_file)) |shndx| { |
| 396 | try writer.print(" : shdr({d})", .{shndx}); | |
| 378 | try bw.print(" : shdr({d})", .{shndx}); | |
| 397 | 379 | } |
| 398 | 380 | 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}); | |
| 400 | 382 | } |
| 401 | 383 | var buf: [2]u8 = .{'_'} ** 2; |
| 402 | 384 | if (symbol.flags.@"export") buf[0] = 'E'; |
| 403 | 385 | 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"); | |
| 406 | 388 | 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 }), | |
| 408 | 390 | } |
| 409 | } else try writer.writeAll(" : unresolved"); | |
| 391 | } else try bw.writeAll(" : unresolved"); | |
| 410 | 392 | } |
| 411 | 393 | |
| 412 | 394 | pub const Flags = packed struct { |
src/link/Elf/Thunk.zig+5-17| ... | ... | @@ -65,16 +65,10 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) usize { |
| 65 | 65 | }; |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | pub fn format( | |
| 69 | thunk: Thunk, | |
| 70 | comptime unused_fmt_string: []const u8, | |
| 71 | options: std.fmt.FormatOptions, | |
| 72 | writer: anytype, | |
| 73 | ) !void { | |
| 68 | pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 74 | 69 | _ = thunk; |
| 70 | _ = bw; | |
| 75 | 71 | _ = unused_fmt_string; |
| 76 | _ = options; | |
| 77 | _ = writer; | |
| 78 | 72 | @compileError("do not format Thunk directly"); |
| 79 | 73 | } |
| 80 | 74 | |
| ... | ... | @@ -90,20 +84,14 @@ const FormatContext = struct { |
| 90 | 84 | elf_file: *Elf, |
| 91 | 85 | }; |
| 92 | 86 | |
| 93 | fn format2( | |
| 94 | ctx: FormatContext, | |
| 95 | comptime unused_fmt_string: []const u8, | |
| 96 | options: std.fmt.FormatOptions, | |
| 97 | writer: anytype, | |
| 98 | ) !void { | |
| 99 | _ = options; | |
| 87 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 100 | 88 | _ = unused_fmt_string; |
| 101 | 89 | const thunk = ctx.thunk; |
| 102 | 90 | 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) }); | |
| 104 | 92 | for (thunk.symbols.keys()) |ref| { |
| 105 | 93 | 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 }); | |
| 107 | 95 | } |
| 108 | 96 | } |
| 109 | 97 |
src/link/Elf/ZigObject.zig+20-41| ... | ... | @@ -35,9 +35,6 @@ lazy_syms: LazySymbolTable = .{}, |
| 35 | 35 | /// Table of tracked `Nav`s. |
| 36 | 36 | navs: NavTable = .{}, |
| 37 | 37 | |
| 38 | /// TLS variables indexed by Atom.Index. | |
| 39 | tls_variables: TlsTable = .{}, | |
| 40 | ||
| 41 | 38 | /// Table of tracked `Uav`s. |
| 42 | 39 | uavs: UavTable = .{}, |
| 43 | 40 | |
| ... | ... | @@ -257,7 +254,6 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 257 | 254 | meta.exports.deinit(allocator); |
| 258 | 255 | } |
| 259 | 256 | self.uavs.deinit(allocator); |
| 260 | self.tls_variables.deinit(allocator); | |
| 261 | 257 | |
| 262 | 258 | if (self.dwarf) |*dwarf| { |
| 263 | 259 | dwarf.deinit(); |
| ... | ... | @@ -925,7 +921,7 @@ pub fn getNavVAddr( |
| 925 | 921 | const zcu = pt.zcu; |
| 926 | 922 | const ip = &zcu.intern_pool; |
| 927 | 923 | 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 }); | |
| 929 | 925 | const this_sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol( |
| 930 | 926 | elf_file, |
| 931 | 927 | nav.name.toSlice(ip), |
| ... | ... | @@ -1268,7 +1264,7 @@ fn updateNavCode( |
| 1268 | 1264 | const ip = &zcu.intern_pool; |
| 1269 | 1265 | const nav = ip.getNav(nav_index); |
| 1270 | 1266 | |
| 1271 | log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index }); | |
| 1267 | log.debug("updateNavCode {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); | |
| 1272 | 1268 | |
| 1273 | 1269 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 1274 | 1270 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| ... | ... | @@ -1302,7 +1298,7 @@ fn updateNavCode( |
| 1302 | 1298 | self.allocateAtom(atom_ptr, true, elf_file) catch |err| |
| 1303 | 1299 | return elf_file.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(err)}); |
| 1304 | 1300 | |
| 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 }); | |
| 1306 | 1302 | if (old_vaddr != atom_ptr.value) { |
| 1307 | 1303 | sym.value = 0; |
| 1308 | 1304 | esym.st_value = 0; |
| ... | ... | @@ -1347,7 +1343,7 @@ fn updateNavCode( |
| 1347 | 1343 | const file_offset = atom_ptr.offset(elf_file); |
| 1348 | 1344 | elf_file.base.file.?.pwriteAll(code, file_offset) catch |err| |
| 1349 | 1345 | 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 }); | |
| 1351 | 1347 | } |
| 1352 | 1348 | } |
| 1353 | 1349 | |
| ... | ... | @@ -1365,7 +1361,7 @@ fn updateTlv( |
| 1365 | 1361 | const gpa = zcu.gpa; |
| 1366 | 1362 | const nav = ip.getNav(nav_index); |
| 1367 | 1363 | |
| 1368 | log.debug("updateTlv {}({d})", .{ nav.fqn.fmt(ip), nav_index }); | |
| 1364 | log.debug("updateTlv {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); | |
| 1369 | 1365 | |
| 1370 | 1366 | const required_alignment = pt.navAlignment(nav_index); |
| 1371 | 1367 | |
| ... | ... | @@ -1386,9 +1382,6 @@ fn updateTlv( |
| 1386 | 1382 | atom_ptr.alignment = required_alignment; |
| 1387 | 1383 | atom_ptr.size = code.len; |
| 1388 | 1384 | |
| 1389 | const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index); | |
| 1390 | assert(!gop.found_existing); // TODO incremental updates | |
| 1391 | ||
| 1392 | 1385 | self.allocateAtom(atom_ptr, true, elf_file) catch |err| |
| 1393 | 1386 | return elf_file.base.cgFail(nav_index, "failed to allocate atom: {s}", .{@errorName(err)}); |
| 1394 | 1387 | sym.value = 0; |
| ... | ... | @@ -1424,7 +1417,7 @@ pub fn updateFunc( |
| 1424 | 1417 | const gpa = elf_file.base.comp.gpa; |
| 1425 | 1418 | const func = zcu.funcInfo(func_index); |
| 1426 | 1419 | |
| 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 }); | |
| 1428 | 1421 | |
| 1429 | 1422 | const sym_index = try self.getOrCreateMetadataForNav(zcu, func.owner_nav); |
| 1430 | 1423 | self.atom(self.symbol(sym_index).ref.index).?.freeRelocs(self); |
| ... | ... | @@ -1447,7 +1440,7 @@ pub fn updateFunc( |
| 1447 | 1440 | const code = code_buffer.items; |
| 1448 | 1441 | |
| 1449 | 1442 | 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}", .{ | |
| 1451 | 1444 | shndx, |
| 1452 | 1445 | elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name), |
| 1453 | 1446 | ip.getNav(func.owner_nav).fqn.fmt(ip), |
| ... | ... | @@ -1529,7 +1522,7 @@ pub fn updateNav( |
| 1529 | 1522 | const ip = &zcu.intern_pool; |
| 1530 | 1523 | const nav = ip.getNav(nav_index); |
| 1531 | 1524 | |
| 1532 | log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index }); | |
| 1525 | log.debug("updateNav {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); | |
| 1533 | 1526 | |
| 1534 | 1527 | const nav_init = switch (ip.indexToKey(nav.status.fully_resolved.val)) { |
| 1535 | 1528 | .func => .none, |
| ... | ... | @@ -1546,7 +1539,6 @@ pub fn updateNav( |
| 1546 | 1539 | defer debug_wip_nav.deinit(); |
| 1547 | 1540 | dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { |
| 1548 | 1541 | error.OutOfMemory => return error.OutOfMemory, |
| 1549 | error.Overflow => return error.Overflow, | |
| 1550 | 1542 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 1551 | 1543 | }; |
| 1552 | 1544 | } |
| ... | ... | @@ -1576,7 +1568,7 @@ pub fn updateNav( |
| 1576 | 1568 | const code = code_buffer.items; |
| 1577 | 1569 | |
| 1578 | 1570 | 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}", .{ | |
| 1580 | 1572 | shndx, |
| 1581 | 1573 | elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name), |
| 1582 | 1574 | nav.fqn.fmt(ip), |
| ... | ... | @@ -1588,7 +1580,6 @@ pub fn updateNav( |
| 1588 | 1580 | |
| 1589 | 1581 | if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) { |
| 1590 | 1582 | error.OutOfMemory => return error.OutOfMemory, |
| 1591 | error.Overflow => return error.Overflow, | |
| 1592 | 1583 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 1593 | 1584 | }; |
| 1594 | 1585 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); |
| ... | ... | @@ -1622,7 +1613,7 @@ fn updateLazySymbol( |
| 1622 | 1613 | defer code_buffer.deinit(gpa); |
| 1623 | 1614 | |
| 1624 | 1615 | 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}", .{ | |
| 1626 | 1617 | @tagName(sym.kind), |
| 1627 | 1618 | Type.fromInterned(sym.ty).fmt(pt), |
| 1628 | 1619 | }); |
| ... | ... | @@ -2207,25 +2198,19 @@ const FormatContext = struct { |
| 2207 | 2198 | elf_file: *Elf, |
| 2208 | 2199 | }; |
| 2209 | 2200 | |
| 2210 | fn formatSymtab( | |
| 2211 | ctx: FormatContext, | |
| 2212 | comptime unused_fmt_string: []const u8, | |
| 2213 | options: std.fmt.FormatOptions, | |
| 2214 | writer: anytype, | |
| 2215 | ) !void { | |
| 2201 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2216 | 2202 | _ = unused_fmt_string; |
| 2217 | _ = options; | |
| 2218 | 2203 | const self = ctx.self; |
| 2219 | 2204 | const elf_file = ctx.elf_file; |
| 2220 | try writer.writeAll(" locals\n"); | |
| 2205 | try bw.writeAll(" locals\n"); | |
| 2221 | 2206 | for (self.local_symbols.items) |index| { |
| 2222 | 2207 | 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)}); | |
| 2224 | 2209 | } |
| 2225 | try writer.writeAll(" globals\n"); | |
| 2210 | try bw.writeAll(" globals\n"); | |
| 2226 | 2211 | for (ctx.self.global_symbols.items) |index| { |
| 2227 | 2212 | 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)}); | |
| 2229 | 2214 | } |
| 2230 | 2215 | } |
| 2231 | 2216 | |
| ... | ... | @@ -2236,18 +2221,12 @@ pub fn fmtAtoms(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatAtoms) |
| 2236 | 2221 | } }; |
| 2237 | 2222 | } |
| 2238 | 2223 | |
| 2239 | fn formatAtoms( | |
| 2240 | ctx: FormatContext, | |
| 2241 | comptime unused_fmt_string: []const u8, | |
| 2242 | options: std.fmt.FormatOptions, | |
| 2243 | writer: anytype, | |
| 2244 | ) !void { | |
| 2224 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2245 | 2225 | _ = unused_fmt_string; |
| 2246 | _ = options; | |
| 2247 | try writer.writeAll(" atoms\n"); | |
| 2226 | try bw.writeAll(" atoms\n"); | |
| 2248 | 2227 | for (ctx.self.atoms_indexes.items) |atom_index| { |
| 2249 | 2228 | 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)}); | |
| 2251 | 2230 | } |
| 2252 | 2231 | } |
| 2253 | 2232 | |
| ... | ... | @@ -2285,7 +2264,7 @@ fn checkNavAllocated(pt: Zcu.PerThread, index: InternPool.Nav.Index, meta: AvMet |
| 2285 | 2264 | const zcu = pt.zcu; |
| 2286 | 2265 | const ip = &zcu.intern_pool; |
| 2287 | 2266 | 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!", .{ | |
| 2289 | 2268 | nav.fqn.fmt(ip), |
| 2290 | 2269 | index, |
| 2291 | 2270 | meta.symbol_index, |
| ... | ... | @@ -2298,7 +2277,7 @@ fn checkUavAllocated(pt: Zcu.PerThread, index: InternPool.Index, meta: AvMetadat |
| 2298 | 2277 | const zcu = pt.zcu; |
| 2299 | 2278 | const uav = Value.fromInterned(index); |
| 2300 | 2279 | 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!", .{ | |
| 2302 | 2281 | ty.fmt(pt), |
| 2303 | 2282 | index, |
| 2304 | 2283 | meta.symbol_index, |
src/link/Elf/eh_frame.zig+37-50| ... | ... | @@ -49,14 +49,12 @@ pub const Fde = struct { |
| 49 | 49 | |
| 50 | 50 | pub fn format( |
| 51 | 51 | fde: Fde, |
| 52 | bw: *std.io.BufferedWriter, | |
| 52 | 53 | comptime unused_fmt_string: []const u8, |
| 53 | options: std.fmt.FormatOptions, | |
| 54 | writer: *std.io.BufferedWriter, | |
| 55 | 54 | ) !void { |
| 56 | 55 | _ = fde; |
| 57 | 56 | _ = unused_fmt_string; |
| 58 | _ = options; | |
| 59 | _ = writer; | |
| 57 | _ = bw; | |
| 60 | 58 | @compileError("do not format FDEs directly"); |
| 61 | 59 | } |
| 62 | 60 | |
| ... | ... | @@ -74,24 +72,22 @@ pub const Fde = struct { |
| 74 | 72 | |
| 75 | 73 | fn format2( |
| 76 | 74 | ctx: FdeFormatContext, |
| 75 | bw: *std.io.BufferedWriter, | |
| 77 | 76 | comptime unused_fmt_string: []const u8, |
| 78 | options: std.fmt.FormatOptions, | |
| 79 | writer: *std.io.BufferedWriter, | |
| 80 | 77 | ) !void { |
| 81 | 78 | _ = unused_fmt_string; |
| 82 | _ = options; | |
| 83 | 79 | const fde = ctx.fde; |
| 84 | 80 | const elf_file = ctx.elf_file; |
| 85 | 81 | const base_addr = fde.address(elf_file); |
| 86 | 82 | const object = elf_file.file(fde.file_index).?.object; |
| 87 | 83 | 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}", .{ | |
| 89 | 85 | base_addr + fde.out_offset, |
| 90 | 86 | fde.calcSize(), |
| 91 | 87 | fde.cie_index, |
| 92 | 88 | atom_name, |
| 93 | 89 | }); |
| 94 | if (!fde.alive) try writer.writeAll(" : [*]"); | |
| 90 | if (!fde.alive) try bw.writeAll(" : [*]"); | |
| 95 | 91 | } |
| 96 | 92 | }; |
| 97 | 93 | |
| ... | ... | @@ -152,14 +148,12 @@ pub const Cie = struct { |
| 152 | 148 | |
| 153 | 149 | pub fn format( |
| 154 | 150 | cie: Cie, |
| 151 | bw: *std.io.BufferedWriter, | |
| 155 | 152 | comptime unused_fmt_string: []const u8, |
| 156 | options: std.fmt.FormatOptions, | |
| 157 | writer: *std.io.BufferedWriter, | |
| 158 | 153 | ) !void { |
| 159 | 154 | _ = cie; |
| 160 | 155 | _ = unused_fmt_string; |
| 161 | _ = options; | |
| 162 | _ = writer; | |
| 156 | _ = bw; | |
| 163 | 157 | @compileError("do not format CIEs directly"); |
| 164 | 158 | } |
| 165 | 159 | |
| ... | ... | @@ -177,26 +171,23 @@ pub const Cie = struct { |
| 177 | 171 | |
| 178 | 172 | fn format2( |
| 179 | 173 | ctx: CieFormatContext, |
| 174 | bw: *std.io.BufferedWriter, | |
| 180 | 175 | comptime unused_fmt_string: []const u8, |
| 181 | options: std.fmt.FormatOptions, | |
| 182 | writer: *std.io.BufferedWriter, | |
| 183 | 176 | ) !void { |
| 184 | 177 | _ = unused_fmt_string; |
| 185 | _ = options; | |
| 186 | 178 | const cie = ctx.cie; |
| 187 | 179 | const elf_file = ctx.elf_file; |
| 188 | 180 | const base_addr = cie.address(elf_file); |
| 189 | try writer.print("@{x} : size({x})", .{ | |
| 181 | try bw.print("@{x} : size({x})", .{ | |
| 190 | 182 | base_addr + cie.out_offset, |
| 191 | 183 | cie.calcSize(), |
| 192 | 184 | }); |
| 193 | if (!cie.alive) try writer.writeAll(" : [*]"); | |
| 185 | if (!cie.alive) try bw.writeAll(" : [*]"); | |
| 194 | 186 | } |
| 195 | 187 | }; |
| 196 | 188 | |
| 197 | 189 | pub const Iterator = struct { |
| 198 | data: []const u8, | |
| 199 | pos: usize = 0, | |
| 190 | br: std.io.BufferedReader, | |
| 200 | 191 | |
| 201 | 192 | pub const Record = struct { |
| 202 | 193 | tag: enum { fde, cie }, |
| ... | ... | @@ -205,22 +196,18 @@ pub const Iterator = struct { |
| 205 | 196 | }; |
| 206 | 197 | |
| 207 | 198 | 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; | |
| 209 | 200 | |
| 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"); | |
| 212 | 203 | |
| 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 = .{ | |
| 219 | 206 | .tag = if (id == 0) .cie else .fde, |
| 220 | .offset = it.pos, | |
| 207 | .offset = it.br.seek, | |
| 221 | 208 | .size = size, |
| 222 | 209 | }; |
| 223 | it.pos += size + 4; | |
| 210 | try it.br.discard(size); | |
| 224 | 211 | |
| 225 | 212 | return record; |
| 226 | 213 | } |
| ... | ... | @@ -316,7 +303,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: |
| 316 | 303 | const S = math.cast(i64, sym.address(.{}, elf_file)) orelse return error.Overflow; |
| 317 | 304 | const A = rel.r_addend; |
| 318 | 305 | |
| 319 | relocs_log.debug(" {s}: {x}: [{x} => {x}] ({s})", .{ | |
| 306 | relocs_log.debug(" {f}: {x}: [{x} => {x}] ({s})", .{ | |
| 320 | 307 | relocation.fmtRelocType(rel.r_type(), cpu_arch), |
| 321 | 308 | offset, |
| 322 | 309 | P, |
| ... | ... | @@ -332,7 +319,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: |
| 332 | 319 | } |
| 333 | 320 | } |
| 334 | 321 | |
| 335 | pub fn writeEhFrame(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { | |
| 322 | pub fn writeEhFrame(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { | |
| 336 | 323 | relocs_log.debug("{x}: .eh_frame", .{ |
| 337 | 324 | elf_file.sections.items(.shdr)[elf_file.section_indexes.eh_frame.?].sh_addr, |
| 338 | 325 | }); |
| ... | ... | @@ -356,7 +343,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { |
| 356 | 343 | }; |
| 357 | 344 | } |
| 358 | 345 | |
| 359 | try writer.writeAll(contents); | |
| 346 | try bw.writeAll(contents); | |
| 360 | 347 | } |
| 361 | 348 | } |
| 362 | 349 | |
| ... | ... | @@ -384,22 +371,22 @@ pub fn writeEhFrame(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { |
| 384 | 371 | }; |
| 385 | 372 | } |
| 386 | 373 | |
| 387 | try writer.writeAll(contents); | |
| 374 | try bw.writeAll(contents); | |
| 388 | 375 | } |
| 389 | 376 | } |
| 390 | 377 | |
| 391 | try writer.writeInt(u32, 0, .little); | |
| 378 | try bw.writeInt(u32, 0, .little); | |
| 392 | 379 | |
| 393 | 380 | if (has_reloc_errors) return error.RelocFailure; |
| 394 | 381 | } |
| 395 | 382 | |
| 396 | pub fn writeEhFrameRelocatable(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { | |
| 383 | pub fn writeEhFrameRelocatable(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { | |
| 397 | 384 | for (elf_file.objects.items) |index| { |
| 398 | 385 | const object = elf_file.file(index).?.object; |
| 399 | 386 | |
| 400 | 387 | for (object.cies.items) |cie| { |
| 401 | 388 | if (!cie.alive) continue; |
| 402 | try writer.writeAll(cie.data(elf_file)); | |
| 389 | try bw.writeAll(cie.data(elf_file)); | |
| 403 | 390 | } |
| 404 | 391 | } |
| 405 | 392 | |
| ... | ... | @@ -418,7 +405,7 @@ pub fn writeEhFrameRelocatable(elf_file: *Elf, writer: *std.io.BufferedWriter) ! |
| 418 | 405 | .little, |
| 419 | 406 | ); |
| 420 | 407 | |
| 421 | try writer.writeAll(contents); | |
| 408 | try bw.writeAll(contents); | |
| 422 | 409 | } |
| 423 | 410 | } |
| 424 | 411 | } |
| ... | ... | @@ -438,7 +425,7 @@ fn emitReloc(elf_file: *Elf, r_offset: u64, sym: *const Symbol, rel: elf.Elf64_R |
| 438 | 425 | }, |
| 439 | 426 | } |
| 440 | 427 | |
| 441 | relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{ | |
| 428 | relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{ | |
| 442 | 429 | relocation.fmtRelocType(r_type, cpu_arch), |
| 443 | 430 | r_offset, |
| 444 | 431 | r_sym, |
| ... | ... | @@ -495,14 +482,14 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, relocs: *std.ArrayList(elf.Elf64_Rela) |
| 495 | 482 | } |
| 496 | 483 | } |
| 497 | 484 | |
| 498 | pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { | |
| 485 | pub fn writeEhFrameHdr(elf_file: *Elf, bw: *std.io.BufferedWriter) !void { | |
| 499 | 486 | const comp = elf_file.base.comp; |
| 500 | 487 | const gpa = comp.gpa; |
| 501 | 488 | |
| 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); | |
| 506 | 493 | |
| 507 | 494 | const shdrs = elf_file.sections.items(.shdr); |
| 508 | 495 | 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 { |
| 513 | 500 | const sym = zo.symbol(zo.eh_frame_index orelse break :existing_size 0); |
| 514 | 501 | break :existing_size sym.atom(elf_file).?.size; |
| 515 | 502 | }; |
| 516 | try writer.writeInt( | |
| 503 | try bw.writeInt( | |
| 517 | 504 | u32, |
| 518 | 505 | @as(u32, @bitCast(@as( |
| 519 | 506 | i32, |
| ... | ... | @@ -521,7 +508,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { |
| 521 | 508 | ))), |
| 522 | 509 | .little, |
| 523 | 510 | ); |
| 524 | try writer.writeInt(u32, num_fdes, .little); | |
| 511 | try bw.writeInt(u32, num_fdes, .little); | |
| 525 | 512 | |
| 526 | 513 | const Entry = struct { |
| 527 | 514 | init_addr: u32, |
| ... | ... | @@ -561,7 +548,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: *std.io.BufferedWriter) !void { |
| 561 | 548 | } |
| 562 | 549 | |
| 563 | 550 | 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)); | |
| 565 | 552 | } |
| 566 | 553 | |
| 567 | 554 | const eh_frame_hdr_header_size: usize = 12; |
| ... | ... | @@ -607,11 +594,11 @@ const riscv = struct { |
| 607 | 594 | fn reportInvalidReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela) !void { |
| 608 | 595 | const diags = &elf_file.base.comp.link_diags; |
| 609 | 596 | 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}", .{ | |
| 611 | 598 | relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch), |
| 612 | 599 | rel.r_offset, |
| 613 | 600 | }); |
| 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()}); | |
| 615 | 602 | return error.RelocFailure; |
| 616 | 603 | } |
| 617 | 604 |
src/link/Elf/file.zig+5-11| ... | ... | @@ -14,19 +14,13 @@ pub const File = union(enum) { |
| 14 | 14 | return .{ .data = file }; |
| 15 | 15 | } |
| 16 | 16 | |
| 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 { | |
| 23 | 18 | _ = unused_fmt_string; |
| 24 | _ = options; | |
| 25 | 19 | 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}), | |
| 30 | 24 | } |
| 31 | 25 | } |
| 32 | 26 |
src/link/Elf/gc.zig+5-11| ... | ... | @@ -111,7 +111,7 @@ fn markLive(atom: *Atom, elf_file: *Elf) void { |
| 111 | 111 | const target_sym = elf_file.symbol(ref) orelse continue; |
| 112 | 112 | const target_atom = target_sym.atom(elf_file) orelse continue; |
| 113 | 113 | 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 }); | |
| 115 | 115 | if (markAtom(target_atom)) markLive(target_atom, elf_file); |
| 116 | 116 | } |
| 117 | 117 | } |
| ... | ... | @@ -128,7 +128,7 @@ fn markLive(atom: *Atom, elf_file: *Elf) void { |
| 128 | 128 | } |
| 129 | 129 | const target_atom = target_sym.atom(elf_file) orelse continue; |
| 130 | 130 | 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 }); | |
| 132 | 132 | if (markAtom(target_atom)) markLive(target_atom, elf_file); |
| 133 | 133 | } |
| 134 | 134 | } |
| ... | ... | @@ -170,7 +170,7 @@ pub fn dumpPrunedAtoms(elf_file: *Elf) !void { |
| 170 | 170 | for (file.atoms()) |atom_index| { |
| 171 | 171 | const atom = file.atom(atom_index) orelse continue; |
| 172 | 172 | 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", .{ | |
| 174 | 174 | atom.name(elf_file), |
| 175 | 175 | atom.file(elf_file).?.fmtPath(), |
| 176 | 176 | }); |
| ... | ... | @@ -185,15 +185,9 @@ const Level = struct { |
| 185 | 185 | self.value += 1; |
| 186 | 186 | } |
| 187 | 187 | |
| 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 { | |
| 194 | 189 | _ = unused_fmt_string; |
| 195 | _ = options; | |
| 196 | try writer.writeByteNTimes(' ', self.value); | |
| 190 | try bw.splatByteAll(' ', self.value); | |
| 197 | 191 | } |
| 198 | 192 | }; |
| 199 | 193 |
src/link/Elf/relocatable.zig+21-23| ... | ... | @@ -31,7 +31,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 31 | 31 | try elf_file.allocateNonAllocSections(); |
| 32 | 32 | |
| 33 | 33 | if (build_options.enable_logging) { |
| 34 | state_log.debug("{}", .{elf_file.dumpState()}); | |
| 34 | state_log.debug("{f}", .{elf_file.dumpState()}); | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | try elf_file.writeMergeSections(); |
| ... | ... | @@ -96,36 +96,35 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 96 | 96 | }; |
| 97 | 97 | |
| 98 | 98 | 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}); | |
| 101 | 101 | } |
| 102 | 102 | |
| 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); | |
| 106 | 106 | |
| 107 | 107 | // Write magic |
| 108 | try buffer.writer().writeAll(elf.ARMAG); | |
| 108 | try bw.writeAll(elf.ARMAG); | |
| 109 | 109 | |
| 110 | 110 | // Write symtab |
| 111 | try ar_symtab.write(.p64, elf_file, buffer.writer()); | |
| 111 | try ar_symtab.write(.p64, elf_file, &bw); | |
| 112 | 112 | |
| 113 | 113 | // Write strtab |
| 114 | 114 | 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); | |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | // Write object files |
| 120 | 120 | 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); | |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | assert(buffer.items.len == total_size); | |
| 126 | ||
| 125 | assert(bw.end == bw.buffer.len); | |
| 127 | 126 | 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); | |
| 129 | 128 | |
| 130 | 129 | if (diags.hasErrors()) return error.LinkFailure; |
| 131 | 130 | } |
| ... | ... | @@ -170,7 +169,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { |
| 170 | 169 | try elf_file.allocateNonAllocSections(); |
| 171 | 170 | |
| 172 | 171 | if (build_options.enable_logging) { |
| 173 | state_log.debug("{}", .{elf_file.dumpState()}); | |
| 172 | state_log.debug("{f}", .{elf_file.dumpState()}); | |
| 174 | 173 | } |
| 175 | 174 | |
| 176 | 175 | try writeAtoms(elf_file); |
| ... | ... | @@ -407,17 +406,16 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 407 | 406 | }; |
| 408 | 407 | const shdr = slice.items(.shdr)[shndx]; |
| 409 | 408 | 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); | |
| 415 | 413 | log.debug("writing .eh_frame from 0x{x} to 0x{x}", .{ |
| 416 | 414 | shdr.sh_offset + existing_size, |
| 417 | 415 | shdr.sh_offset + sh_size, |
| 418 | 416 | }); |
| 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); | |
| 421 | 419 | } |
| 422 | 420 | if (elf_file.section_indexes.eh_frame_rela) |shndx| { |
| 423 | 421 | 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 |
| 148 | 148 | } }; |
| 149 | 149 | } |
| 150 | 150 | |
| 151 | fn formatRelocType( | |
| 152 | ctx: FormatRelocTypeCtx, | |
| 153 | comptime unused_fmt_string: []const u8, | |
| 154 | options: std.fmt.FormatOptions, | |
| 155 | writer: anytype, | |
| 156 | ) !void { | |
| 151 | fn formatRelocType(ctx: FormatRelocTypeCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 157 | 152 | _ = unused_fmt_string; |
| 158 | _ = options; | |
| 159 | 153 | const r_type = ctx.r_type; |
| 160 | 154 | 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)))}), | |
| 164 | 158 | else => unreachable, |
| 165 | 159 | } |
| 166 | 160 | } |
src/link/Elf/synthetic_sections.zig+111-131| ... | ... | @@ -94,115 +94,115 @@ pub const DynamicSection = struct { |
| 94 | 94 | return nentries * @sizeOf(elf.Elf64_Dyn); |
| 95 | 95 | } |
| 96 | 96 | |
| 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 { | |
| 98 | 98 | const shdrs = elf_file.sections.items(.shdr); |
| 99 | 99 | |
| 100 | 100 | // NEEDED |
| 101 | 101 | 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 }); | |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | 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 }); | |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | // RUNPATH |
| 110 | 110 | // TODO add option in Options to revert to old RPATH tag |
| 111 | 111 | 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 }); | |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | 115 | // INIT |
| 116 | 116 | if (elf_file.sectionByName(".init")) |shndx| { |
| 117 | 117 | 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 }); | |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | 121 | // FINI |
| 122 | 122 | if (elf_file.sectionByName(".fini")) |shndx| { |
| 123 | 123 | 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 }); | |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | // INIT_ARRAY |
| 128 | 128 | if (elf_file.sectionByName(".init_array")) |shndx| { |
| 129 | 129 | 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 }); | |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | // FINI_ARRAY |
| 135 | 135 | if (elf_file.sectionByName(".fini_array")) |shndx| { |
| 136 | 136 | 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 }); | |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | 141 | // RELA |
| 142 | 142 | if (elf_file.section_indexes.rela_dyn) |shndx| { |
| 143 | 143 | 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 }); | |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | // JMPREL |
| 150 | 150 | if (elf_file.section_indexes.rela_plt) |shndx| { |
| 151 | 151 | 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 }); | |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | // PLTGOT |
| 158 | 158 | if (elf_file.section_indexes.got_plt) |shndx| { |
| 159 | 159 | 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 }); | |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | { |
| 164 | 164 | assert(elf_file.section_indexes.hash != null); |
| 165 | 165 | 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 }); | |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | if (elf_file.section_indexes.gnu_hash) |shndx| { |
| 170 | 170 | 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 }); | |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | 174 | // TEXTREL |
| 175 | 175 | 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 }); | |
| 177 | 177 | } |
| 178 | 178 | |
| 179 | 179 | // SYMTAB + SYMENT |
| 180 | 180 | { |
| 181 | 181 | assert(elf_file.section_indexes.dynsymtab != null); |
| 182 | 182 | 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 }); | |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | // STRTAB + STRSZ |
| 188 | 188 | { |
| 189 | 189 | assert(elf_file.section_indexes.dynstrtab != null); |
| 190 | 190 | 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 }); | |
| 193 | 193 | } |
| 194 | 194 | |
| 195 | 195 | // VERSYM |
| 196 | 196 | if (elf_file.section_indexes.versym) |shndx| { |
| 197 | 197 | 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 }); | |
| 199 | 199 | } |
| 200 | 200 | |
| 201 | 201 | // VERNEED + VERNEEDNUM |
| 202 | 202 | if (elf_file.section_indexes.verneed) |shndx| { |
| 203 | 203 | 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{ | |
| 206 | 206 | .d_tag = elf.DT_VERNEEDNUM, |
| 207 | 207 | .d_val = elf_file.verneed.verneed.items.len, |
| 208 | 208 | }); |
| ... | ... | @@ -210,18 +210,18 @@ pub const DynamicSection = struct { |
| 210 | 210 | |
| 211 | 211 | // FLAGS |
| 212 | 212 | 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 }); | |
| 214 | 214 | } |
| 215 | 215 | // FLAGS_1 |
| 216 | 216 | 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 }); | |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | // 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 }); | |
| 222 | 222 | |
| 223 | 223 | // 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 }); | |
| 225 | 225 | } |
| 226 | 226 | }; |
| 227 | 227 | |
| ... | ... | @@ -360,7 +360,7 @@ pub const GotSection = struct { |
| 360 | 360 | return s; |
| 361 | 361 | } |
| 362 | 362 | |
| 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 { | |
| 364 | 364 | const comp = elf_file.base.comp; |
| 365 | 365 | const is_dyn_lib = elf_file.isEffectivelyDynLib(); |
| 366 | 366 | const apply_relocs = true; // TODO add user option for this |
| ... | ... | @@ -381,47 +381,47 @@ pub const GotSection = struct { |
| 381 | 381 | } |
| 382 | 382 | break :blk value; |
| 383 | 383 | }; |
| 384 | try writeInt(value, elf_file, writer); | |
| 384 | try writeInt(value, elf_file, bw); | |
| 385 | 385 | }, |
| 386 | 386 | .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); | |
| 389 | 389 | }, |
| 390 | 390 | .tlsgd => { |
| 391 | 391 | 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); | |
| 394 | 394 | } 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); | |
| 396 | 396 | const offset = symbol.?.address(.{}, elf_file) - elf_file.dtpAddress(); |
| 397 | try writeInt(offset, elf_file, writer); | |
| 397 | try writeInt(offset, elf_file, bw); | |
| 398 | 398 | } |
| 399 | 399 | }, |
| 400 | 400 | .gottp => { |
| 401 | 401 | if (symbol.?.flags.import) { |
| 402 | try writeInt(0, elf_file, writer); | |
| 402 | try writeInt(0, elf_file, bw); | |
| 403 | 403 | } else if (is_dyn_lib) { |
| 404 | 404 | const offset = if (apply_relocs) |
| 405 | 405 | symbol.?.address(.{}, elf_file) - elf_file.tlsAddress() |
| 406 | 406 | else |
| 407 | 407 | 0; |
| 408 | try writeInt(offset, elf_file, writer); | |
| 408 | try writeInt(offset, elf_file, bw); | |
| 409 | 409 | } else { |
| 410 | 410 | const offset = symbol.?.address(.{}, elf_file) - elf_file.tpAddress(); |
| 411 | try writeInt(offset, elf_file, writer); | |
| 411 | try writeInt(offset, elf_file, bw); | |
| 412 | 412 | } |
| 413 | 413 | }, |
| 414 | 414 | .tlsdesc => { |
| 415 | 415 | 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); | |
| 418 | 418 | } else { |
| 419 | try writeInt(0, elf_file, writer); | |
| 419 | try writeInt(0, elf_file, bw); | |
| 420 | 420 | const offset = if (apply_relocs) |
| 421 | 421 | symbol.?.address(.{}, elf_file) - elf_file.tlsAddress() |
| 422 | 422 | else |
| 423 | 423 | 0; |
| 424 | try writeInt(offset, elf_file, writer); | |
| 424 | try writeInt(offset, elf_file, bw); | |
| 425 | 425 | } |
| 426 | 426 | }, |
| 427 | 427 | } |
| ... | ... | @@ -615,20 +615,14 @@ pub const GotSection = struct { |
| 615 | 615 | return .{ .data = .{ .got = got, .elf_file = elf_file } }; |
| 616 | 616 | } |
| 617 | 617 | |
| 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 { | |
| 625 | 619 | _ = unused_fmt_string; |
| 626 | 620 | const got = ctx.got; |
| 627 | 621 | const elf_file = ctx.elf_file; |
| 628 | try writer.writeAll("GOT\n"); | |
| 622 | try bw.writeAll("GOT\n"); | |
| 629 | 623 | for (got.entries.items) |entry| { |
| 630 | 624 | 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", .{ | |
| 632 | 626 | entry.cell_index, |
| 633 | 627 | entry.address(elf_file), |
| 634 | 628 | entry.ref, |
| ... | ... | @@ -678,11 +672,11 @@ pub const PltSection = struct { |
| 678 | 672 | }; |
| 679 | 673 | } |
| 680 | 674 | |
| 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 { | |
| 682 | 676 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 683 | 677 | 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), | |
| 686 | 680 | else => return error.UnsupportedCpuArch, |
| 687 | 681 | } |
| 688 | 682 | } |
| ... | ... | @@ -703,7 +697,7 @@ pub const PltSection = struct { |
| 703 | 697 | const r_sym: u64 = extra.dynamic; |
| 704 | 698 | const r_type = relocation.encode(.jump_slot, cpu_arch); |
| 705 | 699 | |
| 706 | relocs_log.debug(" {s}: [{x} => {d}({s})] + 0", .{ | |
| 700 | relocs_log.debug(" {f}: [{x} => {d}({s})] + 0", .{ | |
| 707 | 701 | relocation.fmtRelocType(r_type, cpu_arch), |
| 708 | 702 | r_offset, |
| 709 | 703 | r_sym, |
| ... | ... | @@ -758,20 +752,14 @@ pub const PltSection = struct { |
| 758 | 752 | return .{ .data = .{ .plt = plt, .elf_file = elf_file } }; |
| 759 | 753 | } |
| 760 | 754 | |
| 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 { | |
| 768 | 756 | _ = unused_fmt_string; |
| 769 | 757 | const plt = ctx.plt; |
| 770 | 758 | const elf_file = ctx.elf_file; |
| 771 | try writer.writeAll("PLT\n"); | |
| 759 | try bw.writeAll("PLT\n"); | |
| 772 | 760 | for (plt.symbols.items, 0..) |ref, i| { |
| 773 | 761 | 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", .{ | |
| 775 | 763 | i, |
| 776 | 764 | symbol.pltAddress(elf_file), |
| 777 | 765 | ref, |
| ... | ... | @@ -782,7 +770,7 @@ pub const PltSection = struct { |
| 782 | 770 | } |
| 783 | 771 | |
| 784 | 772 | 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 { | |
| 786 | 774 | const shdrs = elf_file.sections.items(.shdr); |
| 787 | 775 | const plt_addr = shdrs[elf_file.section_indexes.plt.?].sh_addr; |
| 788 | 776 | const got_plt_addr = shdrs[elf_file.section_indexes.got_plt.?].sh_addr; |
| ... | ... | @@ -796,8 +784,8 @@ pub const PltSection = struct { |
| 796 | 784 | mem.writeInt(i32, preamble[8..][0..4], @as(i32, @intCast(disp)), .little); |
| 797 | 785 | disp = @as(i64, @intCast(got_plt_addr + 16)) - @as(i64, @intCast(plt_addr + 14)) - 4; |
| 798 | 786 | 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); | |
| 801 | 789 | |
| 802 | 790 | for (plt.symbols.items, 0..) |ref, i| { |
| 803 | 791 | const sym = elf_file.symbol(ref).?; |
| ... | ... | @@ -811,13 +799,13 @@ pub const PltSection = struct { |
| 811 | 799 | }; |
| 812 | 800 | mem.writeInt(i32, entry[6..][0..4], @as(i32, @intCast(i)), .little); |
| 813 | 801 | mem.writeInt(i32, entry[12..][0..4], @as(i32, @intCast(disp)), .little); |
| 814 | try writer.writeAll(&entry); | |
| 802 | try bw.writeAll(&entry); | |
| 815 | 803 | } |
| 816 | 804 | } |
| 817 | 805 | }; |
| 818 | 806 | |
| 819 | 807 | 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 { | |
| 821 | 809 | { |
| 822 | 810 | const shdrs = elf_file.sections.items(.shdr); |
| 823 | 811 | const plt_addr: i64 = @intCast(shdrs[elf_file.section_indexes.plt.?].sh_addr); |
| ... | ... | @@ -845,7 +833,7 @@ pub const PltSection = struct { |
| 845 | 833 | }; |
| 846 | 834 | comptime assert(preamble.len == 8); |
| 847 | 835 | for (preamble) |inst| { |
| 848 | try writer.writeInt(u32, inst.toU32(), .little); | |
| 836 | try bw.writeInt(u32, inst.toU32(), .little); | |
| 849 | 837 | } |
| 850 | 838 | } |
| 851 | 839 | |
| ... | ... | @@ -864,7 +852,7 @@ pub const PltSection = struct { |
| 864 | 852 | }; |
| 865 | 853 | comptime assert(insts.len == 4); |
| 866 | 854 | for (insts) |inst| { |
| 867 | try writer.writeInt(u32, inst.toU32(), .little); | |
| 855 | try bw.writeInt(u32, inst.toU32(), .little); | |
| 868 | 856 | } |
| 869 | 857 | } |
| 870 | 858 | } |
| ... | ... | @@ -883,22 +871,22 @@ pub const GotPltSection = struct { |
| 883 | 871 | return preamble_size + elf_file.plt.symbols.items.len * 8; |
| 884 | 872 | } |
| 885 | 873 | |
| 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 { | |
| 887 | 875 | _ = got_plt; |
| 888 | 876 | { |
| 889 | 877 | // [0]: _DYNAMIC |
| 890 | 878 | 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); | |
| 892 | 880 | } |
| 893 | 881 | // [1]: 0x0 |
| 894 | 882 | // [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); | |
| 897 | 885 | if (elf_file.section_indexes.plt) |shndx| { |
| 898 | 886 | const plt_addr = elf_file.sections.items(.shdr)[shndx].sh_addr; |
| 899 | 887 | for (0..elf_file.plt.symbols.items.len) |_| { |
| 900 | 888 | // [N]: .plt |
| 901 | try writer.writeInt(u64, plt_addr, .little); | |
| 889 | try bw.writeInt(u64, plt_addr, .little); | |
| 902 | 890 | } |
| 903 | 891 | } |
| 904 | 892 | } |
| ... | ... | @@ -934,11 +922,11 @@ pub const PltGotSection = struct { |
| 934 | 922 | }; |
| 935 | 923 | } |
| 936 | 924 | |
| 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 { | |
| 938 | 926 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 939 | 927 | 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), | |
| 942 | 930 | else => return error.UnsupportedCpuArch, |
| 943 | 931 | } |
| 944 | 932 | } |
| ... | ... | @@ -970,7 +958,7 @@ pub const PltGotSection = struct { |
| 970 | 958 | } |
| 971 | 959 | |
| 972 | 960 | 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 { | |
| 974 | 962 | for (plt_got.symbols.items) |ref| { |
| 975 | 963 | const sym = elf_file.symbol(ref).?; |
| 976 | 964 | const target_addr = sym.gotAddress(elf_file); |
| ... | ... | @@ -982,13 +970,13 @@ pub const PltGotSection = struct { |
| 982 | 970 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, |
| 983 | 971 | }; |
| 984 | 972 | mem.writeInt(i32, entry[6..][0..4], @as(i32, @intCast(disp)), .little); |
| 985 | try writer.writeAll(&entry); | |
| 973 | try bw.writeAll(&entry); | |
| 986 | 974 | } |
| 987 | 975 | } |
| 988 | 976 | }; |
| 989 | 977 | |
| 990 | 978 | 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 { | |
| 992 | 980 | for (plt_got.symbols.items) |ref| { |
| 993 | 981 | const sym = elf_file.symbol(ref).?; |
| 994 | 982 | const target_addr = sym.gotAddress(elf_file); |
| ... | ... | @@ -1003,7 +991,7 @@ pub const PltGotSection = struct { |
| 1003 | 991 | }; |
| 1004 | 992 | comptime assert(insts.len == 4); |
| 1005 | 993 | for (insts) |inst| { |
| 1006 | try writer.writeInt(u32, inst.toU32(), .little); | |
| 994 | try bw.writeInt(u32, inst.toU32(), .little); | |
| 1007 | 995 | } |
| 1008 | 996 | } |
| 1009 | 997 | } |
| ... | ... | @@ -1167,23 +1155,23 @@ pub const DynsymSection = struct { |
| 1167 | 1155 | return @as(u32, @intCast(dynsym.entries.items.len + 1)); |
| 1168 | 1156 | } |
| 1169 | 1157 | |
| 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); | |
| 1172 | 1160 | for (dynsym.entries.items) |entry| { |
| 1173 | 1161 | const sym = elf_file.symbol(entry.ref).?; |
| 1174 | 1162 | var out_sym: elf.Elf64_Sym = Elf.null_sym; |
| 1175 | 1163 | sym.setOutputSym(elf_file, &out_sym); |
| 1176 | 1164 | out_sym.st_name = entry.off; |
| 1177 | try writer.writeStruct(out_sym); | |
| 1165 | try bw.writeStruct(out_sym); | |
| 1178 | 1166 | } |
| 1179 | 1167 | } |
| 1180 | 1168 | }; |
| 1181 | 1169 | |
| 1182 | 1170 | pub const HashSection = struct { |
| 1183 | buffer: std.ArrayListUnmanaged(u8) = .empty, | |
| 1171 | buffer: []u32 = &.{}, | |
| 1184 | 1172 | |
| 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); | |
| 1187 | 1175 | } |
| 1188 | 1176 | |
| 1189 | 1177 | pub fn generate(hs: *HashSection, elf_file: *Elf) !void { |
| ... | ... | @@ -1193,30 +1181,25 @@ pub const HashSection = struct { |
| 1193 | 1181 | const gpa = comp.gpa; |
| 1194 | 1182 | const nsyms = elf_file.dynsym.count(); |
| 1195 | 1183 | |
| 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)); | |
| 1199 | 1186 | |
| 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]; | |
| 1202 | 1191 | @memset(chains, 0); |
| 1203 | 1192 | |
| 1204 | 1193 | for (elf_file.dynsym.entries.items, 1..) |entry, i| { |
| 1205 | 1194 | 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)); | |
| 1209 | 1198 | } |
| 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; | |
| 1216 | 1199 | } |
| 1217 | 1200 | |
| 1218 | 1201 | pub inline fn size(hs: HashSection) usize { |
| 1219 | return hs.buffer.items.len; | |
| 1202 | return @sizeOf(u32) * hs.buffer.len; | |
| 1220 | 1203 | } |
| 1221 | 1204 | |
| 1222 | 1205 | pub fn hasher(name: [:0]const u8) u32 { |
| ... | ... | @@ -1266,17 +1249,14 @@ pub const GnuHashSection = struct { |
| 1266 | 1249 | return header_size + hash.num_bloom * 8 + hash.num_buckets * 4 + hash.num_exports * 4; |
| 1267 | 1250 | } |
| 1268 | 1251 | |
| 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 { | |
| 1270 | 1253 | const exports = getExports(elf_file); |
| 1271 | 1254 | const export_off = elf_file.dynsym.count() - hash.num_exports; |
| 1272 | 1255 | |
| 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); | |
| 1280 | 1260 | |
| 1281 | 1261 | const comp = elf_file.base.comp; |
| 1282 | 1262 | const gpa = comp.gpa; |
| ... | ... | @@ -1300,7 +1280,7 @@ pub const GnuHashSection = struct { |
| 1300 | 1280 | bloom[idx] |= @as(u64, 1) << @as(u6, @intCast((h >> bloom_shift) % 64)); |
| 1301 | 1281 | } |
| 1302 | 1282 | |
| 1303 | try cwriter.writeAll(mem.sliceAsBytes(bloom)); | |
| 1283 | try br.writeAll(mem.sliceAsBytes(bloom)); | |
| 1304 | 1284 | |
| 1305 | 1285 | // Fill in the hash bucket indices |
| 1306 | 1286 | const buckets = try gpa.alloc(u32, hash.num_buckets); |
| ... | ... | @@ -1313,7 +1293,7 @@ pub const GnuHashSection = struct { |
| 1313 | 1293 | } |
| 1314 | 1294 | } |
| 1315 | 1295 | |
| 1316 | try cwriter.writeAll(mem.sliceAsBytes(buckets)); | |
| 1296 | try br.writeAll(mem.sliceAsBytes(buckets)); | |
| 1317 | 1297 | |
| 1318 | 1298 | // Finally, write the hash table |
| 1319 | 1299 | const table = try gpa.alloc(u32, hash.num_exports); |
| ... | ... | @@ -1329,9 +1309,9 @@ pub const GnuHashSection = struct { |
| 1329 | 1309 | } |
| 1330 | 1310 | } |
| 1331 | 1311 | |
| 1332 | try cwriter.writeAll(mem.sliceAsBytes(table)); | |
| 1312 | try br.writeAll(mem.sliceAsBytes(table)); | |
| 1333 | 1313 | |
| 1334 | assert(counting.bytes_written == hash.size()); | |
| 1314 | assert(br.count == hash.size()); | |
| 1335 | 1315 | } |
| 1336 | 1316 | |
| 1337 | 1317 | pub fn hasher(name: [:0]const u8) u32 { |
| ... | ... | @@ -1478,9 +1458,9 @@ pub const VerneedSection = struct { |
| 1478 | 1458 | return vern.verneed.items.len * @sizeOf(elf.Elf64_Verneed) + vern.vernaux.items.len * @sizeOf(elf.Vernaux); |
| 1479 | 1459 | } |
| 1480 | 1460 | |
| 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)); | |
| 1484 | 1464 | } |
| 1485 | 1465 | }; |
| 1486 | 1466 | |
| ... | ... | @@ -1506,11 +1486,11 @@ pub const GroupSection = struct { |
| 1506 | 1486 | return (members.len + 1) * @sizeOf(u32); |
| 1507 | 1487 | } |
| 1508 | 1488 | |
| 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 { | |
| 1510 | 1490 | const cg = cgs.group(elf_file); |
| 1511 | 1491 | const object = cg.file(elf_file).object; |
| 1512 | 1492 | 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); | |
| 1514 | 1494 | for (members) |shndx| { |
| 1515 | 1495 | const shdr = object.shdrs.items[shndx]; |
| 1516 | 1496 | switch (shdr.sh_type) { |
| ... | ... | @@ -1522,26 +1502,26 @@ pub const GroupSection = struct { |
| 1522 | 1502 | atom.output_section_index == rela_shdr.sh_info) |
| 1523 | 1503 | break rela_shndx; |
| 1524 | 1504 | } else unreachable; |
| 1525 | try writer.writeInt(u32, @intCast(rela_shndx), .little); | |
| 1505 | try bw.writeInt(u32, @intCast(rela_shndx), .little); | |
| 1526 | 1506 | }, |
| 1527 | 1507 | else => { |
| 1528 | 1508 | const atom_index = object.atoms_indexes.items[shndx]; |
| 1529 | 1509 | 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); | |
| 1531 | 1511 | }, |
| 1532 | 1512 | } |
| 1533 | 1513 | } |
| 1534 | 1514 | } |
| 1535 | 1515 | }; |
| 1536 | 1516 | |
| 1537 | fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void { | |
| 1517 | fn writeInt(value: anytype, elf_file: *Elf, bw: *std.io.BufferedWriter) anyerror!void { | |
| 1538 | 1518 | const entry_size = elf_file.archPtrWidthBytes(); |
| 1539 | 1519 | const target = elf_file.getTarget(); |
| 1540 | 1520 | const endian = target.cpu.arch.endian(); |
| 1541 | 1521 | 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), | |
| 1545 | 1525 | else => unreachable, |
| 1546 | 1526 | } |
| 1547 | 1527 | } |
src/link/LdScript.zig+1-1| ... | ... | @@ -41,7 +41,7 @@ pub fn parse( |
| 41 | 41 | try line_col.append(gpa, .{ .line = line, .column = column }); |
| 42 | 42 | switch (tok.id) { |
| 43 | 43 | .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})", .{ | |
| 45 | 45 | std.fmt.fmtSliceEscapeLower(tok.get(data)), line, column, |
| 46 | 46 | }); |
| 47 | 47 | }, |
src/link/MachO.zig+148-178| ... | ... | @@ -41,9 +41,9 @@ data_in_code_cmd: macho.linkedit_data_command = .{ .cmd = .DATA_IN_CODE }, |
| 41 | 41 | uuid_cmd: macho.uuid_command = .{ .uuid = [_]u8{0} ** 16 }, |
| 42 | 42 | codesig_cmd: macho.linkedit_data_command = .{ .cmd = .CODE_SIGNATURE }, |
| 43 | 43 | |
| 44 | pagezero_seg_index: ?u8 = null, | |
| 45 | text_seg_index: ?u8 = null, | |
| 46 | linkedit_seg_index: ?u8 = null, | |
| 44 | pagezero_seg_index: ?u4 = null, | |
| 45 | text_seg_index: ?u4 = null, | |
| 46 | linkedit_seg_index: ?u4 = null, | |
| 47 | 47 | text_sect_index: ?u8 = null, |
| 48 | 48 | data_sect_index: ?u8 = null, |
| 49 | 49 | got_sect_index: ?u8 = null, |
| ... | ... | @@ -76,10 +76,10 @@ unwind_info: UnwindInfo = .{}, |
| 76 | 76 | data_in_code: DataInCode = .{}, |
| 77 | 77 | |
| 78 | 78 | /// Tracked loadable segments during incremental linking. |
| 79 | zig_text_seg_index: ?u8 = null, | |
| 80 | zig_const_seg_index: ?u8 = null, | |
| 81 | zig_data_seg_index: ?u8 = null, | |
| 82 | zig_bss_seg_index: ?u8 = null, | |
| 79 | zig_text_seg_index: ?u4 = null, | |
| 80 | zig_const_seg_index: ?u4 = null, | |
| 81 | zig_data_seg_index: ?u4 = null, | |
| 82 | zig_bss_seg_index: ?u4 = null, | |
| 83 | 83 | |
| 84 | 84 | /// Tracked section headers with incremental updates to Zig object. |
| 85 | 85 | zig_text_sect_index: ?u8 = null, |
| ... | ... | @@ -543,7 +543,7 @@ pub fn flush( |
| 543 | 543 | self.allocateSyntheticSymbols(); |
| 544 | 544 | |
| 545 | 545 | if (build_options.enable_logging) { |
| 546 | state_log.debug("{}", .{self.dumpState()}); | |
| 546 | state_log.debug("{f}", .{self.dumpState()}); | |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | 549 | // Beyond this point, everything has been allocated a virtual address and we can resolve |
| ... | ... | @@ -591,6 +591,7 @@ pub fn flush( |
| 591 | 591 | error.NoSpaceLeft => unreachable, |
| 592 | 592 | error.OutOfMemory => return error.OutOfMemory, |
| 593 | 593 | error.LinkFailure => return error.LinkFailure, |
| 594 | else => unreachable, | |
| 594 | 595 | }; |
| 595 | 596 | try self.writeHeader(ncmds, sizeofcmds); |
| 596 | 597 | self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()) catch |err| switch (err) { |
| ... | ... | @@ -677,12 +678,12 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { |
| 677 | 678 | |
| 678 | 679 | try argv.append("-platform_version"); |
| 679 | 680 | 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})); | |
| 681 | 682 | |
| 682 | 683 | if (self.sdk_version) |ver| { |
| 683 | 684 | try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor })); |
| 684 | 685 | } 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})); | |
| 686 | 687 | } |
| 687 | 688 | |
| 688 | 689 | if (comp.sysroot) |syslibroot| { |
| ... | ... | @@ -863,7 +864,7 @@ pub fn classifyInputFile(self: *MachO, input: link.Input) !void { |
| 863 | 864 | |
| 864 | 865 | const path, const file = input.pathAndFile().?; |
| 865 | 866 | // 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}); | |
| 867 | 868 | |
| 868 | 869 | const fh = try self.addFileHandle(file); |
| 869 | 870 | var buffer: [Archive.SARMAG]u8 = undefined; |
| ... | ... | @@ -1074,7 +1075,7 @@ fn accessLibPath( |
| 1074 | 1075 | |
| 1075 | 1076 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 1076 | 1077 | 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 }); | |
| 1078 | 1079 | try checked_paths.append(try arena.dupe(u8, test_path.items)); |
| 1079 | 1080 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| 1080 | 1081 | error.FileNotFound => continue, |
| ... | ... | @@ -1097,7 +1098,7 @@ fn accessFrameworkPath( |
| 1097 | 1098 | |
| 1098 | 1099 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 1099 | 1100 | 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}", .{ | |
| 1101 | 1102 | search_dir, |
| 1102 | 1103 | name, |
| 1103 | 1104 | name, |
| ... | ... | @@ -1178,9 +1179,9 @@ fn parseDependentDylibs(self: *MachO) !void { |
| 1178 | 1179 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 1179 | 1180 | test_path.clearRetainingCapacity(); |
| 1180 | 1181 | 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 }); | |
| 1182 | 1183 | } else { |
| 1183 | try test_path.writer().print("{s}{s}", .{ path, ext }); | |
| 1184 | try test_path.print("{s}{s}", .{ path, ext }); | |
| 1184 | 1185 | } |
| 1185 | 1186 | try checked_paths.append(try arena.dupe(u8, test_path.items)); |
| 1186 | 1187 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| ... | ... | @@ -1591,7 +1592,7 @@ fn reportUndefs(self: *MachO) !void { |
| 1591 | 1592 | const ref = refs.items[inote]; |
| 1592 | 1593 | const file = self.getFile(ref.file).?; |
| 1593 | 1594 | 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) }); | |
| 1595 | 1596 | } |
| 1596 | 1597 | |
| 1597 | 1598 | if (refs.items.len > max_notes) { |
| ... | ... | @@ -2131,7 +2132,7 @@ fn initSegments(self: *MachO) !void { |
| 2131 | 2132 | |
| 2132 | 2133 | mem.sort(Entry, entries.items, self, Entry.lessThan); |
| 2133 | 2134 | |
| 2134 | const backlinks = try gpa.alloc(u8, entries.items.len); | |
| 2135 | const backlinks = try gpa.alloc(u4, entries.items.len); | |
| 2135 | 2136 | defer gpa.free(backlinks); |
| 2136 | 2137 | for (entries.items, 0..) |entry, i| { |
| 2137 | 2138 | backlinks[entry.index] = @intCast(i); |
| ... | ... | @@ -2145,7 +2146,7 @@ fn initSegments(self: *MachO) !void { |
| 2145 | 2146 | self.segments.appendAssumeCapacity(segments[sorted.index]); |
| 2146 | 2147 | } |
| 2147 | 2148 | |
| 2148 | for (&[_]*?u8{ | |
| 2149 | for (&[_]*?u4{ | |
| 2149 | 2150 | &self.pagezero_seg_index, |
| 2150 | 2151 | &self.text_seg_index, |
| 2151 | 2152 | &self.linkedit_seg_index, |
| ... | ... | @@ -2163,7 +2164,7 @@ fn initSegments(self: *MachO) !void { |
| 2163 | 2164 | for (slice.items(.header), slice.items(.segment_id)) |header, *seg_id| { |
| 2164 | 2165 | const segname = header.segName(); |
| 2165 | 2166 | 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); | |
| 2167 | 2168 | const protection = getSegmentProt(segname); |
| 2168 | 2169 | try self.segments.append(gpa, .{ |
| 2169 | 2170 | .cmdsize = @sizeOf(macho.segment_command_64), |
| ... | ... | @@ -2526,10 +2527,9 @@ fn writeThunkWorker(self: *MachO, thunk: Thunk) void { |
| 2526 | 2527 | |
| 2527 | 2528 | const doWork = struct { |
| 2528 | 2529 | 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); | |
| 2533 | 2533 | } |
| 2534 | 2534 | }.doWork; |
| 2535 | 2535 | 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 { |
| 2556 | 2556 | |
| 2557 | 2557 | const doWork = struct { |
| 2558 | 2558 | 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); | |
| 2560 | 2561 | switch (tag) { |
| 2561 | 2562 | .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), | |
| 2568 | 2569 | } |
| 2569 | 2570 | } |
| 2570 | 2571 | }.doWork; |
| ... | ... | @@ -2605,8 +2606,9 @@ fn updateLazyBindSizeWorker(self: *MachO) void { |
| 2605 | 2606 | try macho_file.lazy_bind_section.updateSize(macho_file); |
| 2606 | 2607 | const sect_id = macho_file.stubs_helper_sect_index.?; |
| 2607 | 2608 | 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); | |
| 2610 | 2612 | } |
| 2611 | 2613 | }.doWork; |
| 2612 | 2614 | doWork(self) catch |err| |
| ... | ... | @@ -2665,23 +2667,21 @@ fn writeDyldInfo(self: *MachO) !void { |
| 2665 | 2667 | needed_size += cmd.lazy_bind_size; |
| 2666 | 2668 | needed_size += cmd.export_size; |
| 2667 | 2669 | |
| 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); | |
| 2671 | 2674 | |
| 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); | |
| 2685 | 2685 | } |
| 2686 | 2686 | |
| 2687 | 2687 | pub fn writeDataInCode(self: *MachO) !void { |
| ... | ... | @@ -2689,22 +2689,30 @@ pub fn writeDataInCode(self: *MachO) !void { |
| 2689 | 2689 | defer tracy.end(); |
| 2690 | 2690 | const gpa = self.base.comp.gpa; |
| 2691 | 2691 | 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); | |
| 2696 | 2700 | } |
| 2697 | 2701 | |
| 2698 | 2702 | fn writeIndsymtab(self: *MachO) !void { |
| 2699 | 2703 | const tracy = trace(@src()); |
| 2700 | 2704 | defer tracy.end(); |
| 2705 | ||
| 2701 | 2706 | const gpa = self.base.comp.gpa; |
| 2702 | 2707 | 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); | |
| 2708 | 2716 | } |
| 2709 | 2717 | |
| 2710 | 2718 | pub fn writeSymtabToFile(self: *MachO) !void { |
| ... | ... | @@ -2814,15 +2822,13 @@ fn calcSymtabSize(self: *MachO) !void { |
| 2814 | 2822 | } |
| 2815 | 2823 | } |
| 2816 | 2824 | |
| 2817 | fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { | |
| 2825 | fn writeLoadCommands(self: *MachO) anyerror!struct { usize, usize, u64 } { | |
| 2818 | 2826 | const comp = self.base.comp; |
| 2819 | 2827 | 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); | |
| 2823 | 2828 | |
| 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); | |
| 2826 | 2832 | |
| 2827 | 2833 | var ncmds: usize = 0; |
| 2828 | 2834 | |
| ... | ... | @@ -2831,26 +2837,26 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2831 | 2837 | const slice = self.sections.slice(); |
| 2832 | 2838 | var sect_id: usize = 0; |
| 2833 | 2839 | for (self.segments.items) |seg| { |
| 2834 | try writer.writeStruct(seg); | |
| 2840 | try bw.writeStruct(seg); | |
| 2835 | 2841 | for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| { |
| 2836 | try writer.writeStruct(header); | |
| 2842 | try bw.writeStruct(header); | |
| 2837 | 2843 | } |
| 2838 | 2844 | sect_id += seg.nsects; |
| 2839 | 2845 | } |
| 2840 | 2846 | ncmds += self.segments.items.len; |
| 2841 | 2847 | } |
| 2842 | 2848 | |
| 2843 | try writer.writeStruct(self.dyld_info_cmd); | |
| 2849 | try bw.writeStruct(self.dyld_info_cmd); | |
| 2844 | 2850 | ncmds += 1; |
| 2845 | try writer.writeStruct(self.function_starts_cmd); | |
| 2851 | try bw.writeStruct(self.function_starts_cmd); | |
| 2846 | 2852 | ncmds += 1; |
| 2847 | try writer.writeStruct(self.data_in_code_cmd); | |
| 2853 | try bw.writeStruct(self.data_in_code_cmd); | |
| 2848 | 2854 | ncmds += 1; |
| 2849 | try writer.writeStruct(self.symtab_cmd); | |
| 2855 | try bw.writeStruct(self.symtab_cmd); | |
| 2850 | 2856 | ncmds += 1; |
| 2851 | try writer.writeStruct(self.dysymtab_cmd); | |
| 2857 | try bw.writeStruct(self.dysymtab_cmd); | |
| 2852 | 2858 | ncmds += 1; |
| 2853 | try load_commands.writeDylinkerLC(writer); | |
| 2859 | try load_commands.writeDylinkerLC(&bw); | |
| 2854 | 2860 | ncmds += 1; |
| 2855 | 2861 | |
| 2856 | 2862 | if (self.getInternalObject()) |obj| { |
| ... | ... | @@ -2861,7 +2867,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2861 | 2867 | 0 |
| 2862 | 2868 | else |
| 2863 | 2869 | @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{ | |
| 2865 | 2871 | .entryoff = entryoff, |
| 2866 | 2872 | .stacksize = self.base.stack_size, |
| 2867 | 2873 | }); |
| ... | ... | @@ -2870,35 +2876,35 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2870 | 2876 | } |
| 2871 | 2877 | |
| 2872 | 2878 | if (self.base.isDynLib()) { |
| 2873 | try load_commands.writeDylibIdLC(self, writer); | |
| 2879 | try load_commands.writeDylibIdLC(self, &bw); | |
| 2874 | 2880 | ncmds += 1; |
| 2875 | 2881 | } |
| 2876 | 2882 | |
| 2877 | 2883 | for (self.rpath_list) |rpath| { |
| 2878 | try load_commands.writeRpathLC(rpath, writer); | |
| 2884 | try load_commands.writeRpathLC(&bw, rpath); | |
| 2879 | 2885 | ncmds += 1; |
| 2880 | 2886 | } |
| 2881 | 2887 | if (comp.config.any_sanitize_thread) { |
| 2882 | 2888 | const path = try comp.tsan_lib.?.full_object_path.toString(gpa); |
| 2883 | 2889 | defer gpa.free(path); |
| 2884 | 2890 | const rpath = std.fs.path.dirname(path) orelse "."; |
| 2885 | try load_commands.writeRpathLC(rpath, writer); | |
| 2891 | try load_commands.writeRpathLC(&bw, rpath); | |
| 2886 | 2892 | ncmds += 1; |
| 2887 | 2893 | } |
| 2888 | 2894 | |
| 2889 | try writer.writeStruct(macho.source_version_command{ .version = 0 }); | |
| 2895 | try bw.writeStruct(macho.source_version_command{ .version = 0 }); | |
| 2890 | 2896 | ncmds += 1; |
| 2891 | 2897 | |
| 2892 | 2898 | 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); | |
| 2894 | 2900 | ncmds += 1; |
| 2895 | 2901 | } else { |
| 2896 | try load_commands.writeVersionMinLC(self.platform, self.sdk_version, writer); | |
| 2902 | try load_commands.writeVersionMinLC(&bw, self.platform, self.sdk_version); | |
| 2897 | 2903 | ncmds += 1; |
| 2898 | 2904 | } |
| 2899 | 2905 | |
| 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); | |
| 2902 | 2908 | ncmds += 1; |
| 2903 | 2909 | |
| 2904 | 2910 | for (self.dylibs.items) |index| { |
| ... | ... | @@ -2916,20 +2922,19 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2916 | 2922 | .timestamp = dylib_id.timestamp, |
| 2917 | 2923 | .current_version = dylib_id.current_version, |
| 2918 | 2924 | .compatibility_version = dylib_id.compatibility_version, |
| 2919 | }, writer); | |
| 2925 | }, &bw); | |
| 2920 | 2926 | ncmds += 1; |
| 2921 | 2927 | } |
| 2922 | 2928 | |
| 2923 | 2929 | if (self.requiresCodeSig()) { |
| 2924 | try writer.writeStruct(self.codesig_cmd); | |
| 2930 | try bw.writeStruct(self.codesig_cmd); | |
| 2925 | 2931 | ncmds += 1; |
| 2926 | 2932 | } |
| 2927 | 2933 | |
| 2928 | assert(stream.pos == needed_size); | |
| 2934 | assert(bw.end == bw.buffer.len); | |
| 2935 | try self.pwriteAll(bw.buffer, @sizeOf(macho.mach_header_64)); | |
| 2929 | 2936 | |
| 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 }; | |
| 2933 | 2938 | } |
| 2934 | 2939 | |
| 2935 | 2940 | fn writeHeader(self: *MachO, ncmds: usize, sizeofcmds: usize) !void { |
| ... | ... | @@ -3012,27 +3017,28 @@ pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void { |
| 3012 | 3017 | } |
| 3013 | 3018 | |
| 3014 | 3019 | pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void { |
| 3020 | const gpa = self.base.comp.gpa; | |
| 3015 | 3021 | const seg = self.getTextSegment(); |
| 3016 | 3022 | const offset = self.codesig_cmd.dataoff; |
| 3017 | 3023 | |
| 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); | |
| 3021 | 3027 | try code_sig.writeAdhocSignature(self, .{ |
| 3022 | 3028 | .file = self.base.file.?, |
| 3023 | 3029 | .exec_seg_base = seg.fileoff, |
| 3024 | 3030 | .exec_seg_limit = seg.filesize, |
| 3025 | 3031 | .file_size = offset, |
| 3026 | 3032 | .dylib = self.base.isDynLib(), |
| 3027 | }, buffer.writer()); | |
| 3028 | assert(buffer.items.len == code_sig.size()); | |
| 3033 | }, &bw); | |
| 3029 | 3034 | |
| 3030 | 3035 | log.debug("writing code signature from 0x{x} to 0x{x}", .{ |
| 3031 | 3036 | offset, |
| 3032 | offset + buffer.items.len, | |
| 3037 | offset + bw.end, | |
| 3033 | 3038 | }); |
| 3034 | 3039 | |
| 3035 | try self.pwriteAll(buffer.items, offset); | |
| 3040 | assert(bw.end == bw.buffer.len); | |
| 3041 | try self.pwriteAll(bw.buffer, offset); | |
| 3036 | 3042 | } |
| 3037 | 3043 | |
| 3038 | 3044 | pub fn updateFunc( |
| ... | ... | @@ -3341,7 +3347,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3341 | 3347 | } |
| 3342 | 3348 | |
| 3343 | 3349 | 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 { | |
| 3345 | 3351 | const sect = &macho_file.sections.items(.header)[sect_id]; |
| 3346 | 3352 | const seg = macho_file.segments.items[seg_id]; |
| 3347 | 3353 | sect.addr = seg.vmaddr; |
| ... | ... | @@ -3600,7 +3606,7 @@ inline fn requiresThunks(self: MachO) bool { |
| 3600 | 3606 | } |
| 3601 | 3607 | |
| 3602 | 3608 | pub fn isZigSegment(self: MachO, seg_id: u8) bool { |
| 3603 | inline for (&[_]?u8{ | |
| 3609 | inline for (&[_]?u4{ | |
| 3604 | 3610 | self.zig_text_seg_index, |
| 3605 | 3611 | self.zig_const_seg_index, |
| 3606 | 3612 | self.zig_data_seg_index, |
| ... | ... | @@ -3648,9 +3654,9 @@ pub fn addSegment(self: *MachO, name: []const u8, opts: struct { |
| 3648 | 3654 | fileoff: u64 = 0, |
| 3649 | 3655 | filesize: u64 = 0, |
| 3650 | 3656 | prot: macho.vm_prot_t = macho.PROT.NONE, |
| 3651 | }) error{OutOfMemory}!u8 { | |
| 3657 | }) error{OutOfMemory}!u4 { | |
| 3652 | 3658 | 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); | |
| 3654 | 3660 | try self.segments.append(gpa, .{ |
| 3655 | 3661 | .segname = makeStaticString(name), |
| 3656 | 3662 | .vmaddr = opts.vmaddr, |
| ... | ... | @@ -3700,9 +3706,9 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 3700 | 3706 | return buf; |
| 3701 | 3707 | } |
| 3702 | 3708 | |
| 3703 | pub fn getSegmentByName(self: MachO, segname: []const u8) ?u8 { | |
| 3709 | pub fn getSegmentByName(self: MachO, segname: []const u8) ?u4 { | |
| 3704 | 3710 | 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); | |
| 3706 | 3712 | } else return null; |
| 3707 | 3713 | } |
| 3708 | 3714 | |
| ... | ... | @@ -3791,7 +3797,7 @@ pub fn reportParseError2( |
| 3791 | 3797 | const diags = &self.base.comp.link_diags; |
| 3792 | 3798 | var err = try diags.addErrorWithNotes(1); |
| 3793 | 3799 | 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()}); | |
| 3795 | 3801 | } |
| 3796 | 3802 | |
| 3797 | 3803 | fn reportMissingDependencyError( |
| ... | ... | @@ -3806,7 +3812,7 @@ fn reportMissingDependencyError( |
| 3806 | 3812 | var err = try diags.addErrorWithNotes(2 + checked_paths.len); |
| 3807 | 3813 | try err.addMsg(format, args); |
| 3808 | 3814 | 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()}); | |
| 3810 | 3816 | for (checked_paths) |p| { |
| 3811 | 3817 | err.addNote("tried {s}", .{p}); |
| 3812 | 3818 | } |
| ... | ... | @@ -3823,7 +3829,7 @@ fn reportDependencyError( |
| 3823 | 3829 | var err = try diags.addErrorWithNotes(2); |
| 3824 | 3830 | try err.addMsg(format, args); |
| 3825 | 3831 | 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()}); | |
| 3827 | 3833 | } |
| 3828 | 3834 | |
| 3829 | 3835 | fn reportDuplicates(self: *MachO) error{ HasDuplicates, OutOfMemory }!void { |
| ... | ... | @@ -3853,12 +3859,12 @@ fn reportDuplicates(self: *MachO) error{ HasDuplicates, OutOfMemory }!void { |
| 3853 | 3859 | |
| 3854 | 3860 | var err = try diags.addErrorWithNotes(nnotes + 1); |
| 3855 | 3861 | 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()}); | |
| 3857 | 3863 | |
| 3858 | 3864 | var inote: usize = 0; |
| 3859 | 3865 | while (inote < @min(notes.items.len, max_notes)) : (inote += 1) { |
| 3860 | 3866 | const file = self.getFile(notes.items[inote]).?; |
| 3861 | err.addNote("defined by {}", .{file.fmtPath()}); | |
| 3867 | err.addNote("defined by {f}", .{file.fmtPath()}); | |
| 3862 | 3868 | } |
| 3863 | 3869 | |
| 3864 | 3870 | if (notes.items.len > max_notes) { |
| ... | ... | @@ -3904,31 +3910,25 @@ pub fn dumpState(self: *MachO) std.fmt.Formatter(fmtDumpState) { |
| 3904 | 3910 | return .{ .data = self }; |
| 3905 | 3911 | } |
| 3906 | 3912 | |
| 3907 | fn fmtDumpState( | |
| 3908 | self: *MachO, | |
| 3909 | comptime unused_fmt_string: []const u8, | |
| 3910 | options: std.fmt.FormatOptions, | |
| 3911 | writer: anytype, | |
| 3912 | ) !void { | |
| 3913 | _ = options; | |
| 3913 | fn fmtDumpState(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 3914 | 3914 | _ = unused_fmt_string; |
| 3915 | 3915 | 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", .{ | |
| 3918 | 3918 | zo.fmtAtoms(self), |
| 3919 | 3919 | zo.fmtSymtab(self), |
| 3920 | 3920 | }); |
| 3921 | 3921 | } |
| 3922 | 3922 | for (self.objects.items) |index| { |
| 3923 | 3923 | const object = self.getFile(index).?.object; |
| 3924 | try writer.print("object({d}) : {} : has_debug({})", .{ | |
| 3924 | try bw.print("object({d}) : {f} : has_debug({})", .{ | |
| 3925 | 3925 | index, |
| 3926 | 3926 | object.fmtPath(), |
| 3927 | 3927 | object.hasDebugInfo(), |
| 3928 | 3928 | }); |
| 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", .{ | |
| 3932 | 3932 | object.fmtAtoms(self), |
| 3933 | 3933 | object.fmtCies(self), |
| 3934 | 3934 | object.fmtFdes(self), |
| ... | ... | @@ -3938,48 +3938,42 @@ fn fmtDumpState( |
| 3938 | 3938 | } |
| 3939 | 3939 | for (self.dylibs.items) |index| { |
| 3940 | 3940 | const dylib = self.getFile(index).?.dylib; |
| 3941 | try writer.print("dylib({d}) : {} : needed({}) : weak({})", .{ | |
| 3941 | try bw.print("dylib({d}) : {f} : needed({}) : weak({})", .{ | |
| 3942 | 3942 | index, |
| 3943 | 3943 | @as(Path, dylib.path), |
| 3944 | 3944 | dylib.needed, |
| 3945 | 3945 | dylib.weak, |
| 3946 | 3946 | }); |
| 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)}); | |
| 3950 | 3950 | } |
| 3951 | 3951 | 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) }); | |
| 3954 | 3954 | } |
| 3955 | try writer.writeAll("thunks\n"); | |
| 3955 | try bw.writeAll("thunks\n"); | |
| 3956 | 3956 | 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) }); | |
| 3958 | 3958 | } |
| 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()}); | |
| 3966 | 3966 | } |
| 3967 | 3967 | |
| 3968 | 3968 | fn fmtSections(self: *MachO) std.fmt.Formatter(formatSections) { |
| 3969 | 3969 | return .{ .data = self }; |
| 3970 | 3970 | } |
| 3971 | 3971 | |
| 3972 | fn formatSections( | |
| 3973 | self: *MachO, | |
| 3974 | comptime unused_fmt_string: []const u8, | |
| 3975 | options: std.fmt.FormatOptions, | |
| 3976 | writer: anytype, | |
| 3977 | ) !void { | |
| 3978 | _ = options; | |
| 3972 | fn formatSections(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 3979 | 3973 | _ = unused_fmt_string; |
| 3980 | 3974 | const slice = self.sections.slice(); |
| 3981 | 3975 | for (slice.items(.header), slice.items(.segment_id), 0..) |header, seg_id, i| { |
| 3982 | try writer.print( | |
| 3976 | try bw.print( | |
| 3983 | 3977 | "sect({d}) : seg({d}) : {s},{s} : @{x} ({x}) : align({x}) : size({x}) : relocs({x};{d})\n", |
| 3984 | 3978 | .{ |
| 3985 | 3979 | i, seg_id, header.segName(), header.sectName(), header.addr, header.offset, |
| ... | ... | @@ -3993,16 +3987,10 @@ fn fmtSegments(self: *MachO) std.fmt.Formatter(formatSegments) { |
| 3993 | 3987 | return .{ .data = self }; |
| 3994 | 3988 | } |
| 3995 | 3989 | |
| 3996 | fn formatSegments( | |
| 3997 | self: *MachO, | |
| 3998 | comptime unused_fmt_string: []const u8, | |
| 3999 | options: std.fmt.FormatOptions, | |
| 4000 | writer: anytype, | |
| 4001 | ) !void { | |
| 4002 | _ = options; | |
| 3990 | fn formatSegments(self: *MachO, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 4003 | 3991 | _ = unused_fmt_string; |
| 4004 | 3992 | 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", .{ | |
| 4006 | 3994 | i, seg.segName(), seg.vmaddr, seg.vmaddr + seg.vmsize, |
| 4007 | 3995 | seg.fileoff, seg.fileoff + seg.filesize, |
| 4008 | 3996 | }); |
| ... | ... | @@ -4013,13 +4001,7 @@ pub fn fmtSectType(tt: u8) std.fmt.Formatter(formatSectType) { |
| 4013 | 4001 | return .{ .data = tt }; |
| 4014 | 4002 | } |
| 4015 | 4003 | |
| 4016 | fn formatSectType( | |
| 4017 | tt: u8, | |
| 4018 | comptime unused_fmt_string: []const u8, | |
| 4019 | options: std.fmt.FormatOptions, | |
| 4020 | writer: anytype, | |
| 4021 | ) !void { | |
| 4022 | _ = options; | |
| 4004 | fn formatSectType(tt: u8, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 4023 | 4005 | _ = unused_fmt_string; |
| 4024 | 4006 | const name = switch (tt) { |
| 4025 | 4007 | macho.S_REGULAR => "REGULAR", |
| ... | ... | @@ -4044,9 +4026,9 @@ fn formatSectType( |
| 4044 | 4026 | macho.S_THREAD_LOCAL_VARIABLE_POINTERS => "THREAD_LOCAL_VARIABLE_POINTERS", |
| 4045 | 4027 | macho.S_THREAD_LOCAL_INIT_FUNCTION_POINTERS => "THREAD_LOCAL_INIT_FUNCTION_POINTERS", |
| 4046 | 4028 | 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}), | |
| 4048 | 4030 | }; |
| 4049 | try writer.print("{s}", .{name}); | |
| 4031 | try bw.print("{s}", .{name}); | |
| 4050 | 4032 | } |
| 4051 | 4033 | |
| 4052 | 4034 | const is_hot_update_compatible = switch (builtin.target.os.tag) { |
| ... | ... | @@ -4058,7 +4040,7 @@ const default_entry_symbol_name = "_main"; |
| 4058 | 4040 | |
| 4059 | 4041 | const Section = struct { |
| 4060 | 4042 | header: macho.section_64, |
| 4061 | segment_id: u8, | |
| 4043 | segment_id: u4, | |
| 4062 | 4044 | atoms: std.ArrayListUnmanaged(Ref) = .empty, |
| 4063 | 4045 | free_list: std.ArrayListUnmanaged(Atom.Index) = .empty, |
| 4064 | 4046 | last_atom_index: Atom.Index = 0, |
| ... | ... | @@ -4288,17 +4270,11 @@ pub const Platform = struct { |
| 4288 | 4270 | cpu_arch: std.Target.Cpu.Arch, |
| 4289 | 4271 | }; |
| 4290 | 4272 | |
| 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 { | |
| 4297 | 4274 | _ = 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) }); | |
| 4300 | 4276 | if (ctx.platform.abi != .none) { |
| 4301 | try writer.print("-{s}", .{@tagName(ctx.platform.abi)}); | |
| 4277 | try bw.print("-{s}", .{@tagName(ctx.platform.abi)}); | |
| 4302 | 4278 | } |
| 4303 | 4279 | } |
| 4304 | 4280 | |
| ... | ... | @@ -4390,7 +4366,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi |
| 4390 | 4366 | // The file/property is also available with vendored libc. |
| 4391 | 4367 | fn readSdkVersionFromSettings(arena: Allocator, dir: []const u8) ![]const u8 { |
| 4392 | 4368 | 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))); | |
| 4394 | 4370 | const parsed = try std.json.parseFromSlice(std.json.Value, arena, contents, .{}); |
| 4395 | 4371 | if (parsed.value.object.get("MinimalDisplayName")) |ver| return ver.string; |
| 4396 | 4372 | return error.SdkVersionFailure; |
| ... | ... | @@ -4406,7 +4382,7 @@ fn parseSdkVersion(raw: []const u8) ?std.SemanticVersion { |
| 4406 | 4382 | }; |
| 4407 | 4383 | |
| 4408 | 4384 | const parseNext = struct { |
| 4409 | fn parseNext(it: anytype) ?u16 { | |
| 4385 | fn parseNext(it: *std.mem.SplitIterator(u8, .any)) ?u16 { | |
| 4410 | 4386 | const nn = it.next() orelse return null; |
| 4411 | 4387 | return std.fmt.parseInt(u16, nn, 10) catch null; |
| 4412 | 4388 | } |
| ... | ... | @@ -4507,15 +4483,9 @@ pub const Ref = struct { |
| 4507 | 4483 | }; |
| 4508 | 4484 | } |
| 4509 | 4485 | |
| 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 { | |
| 4516 | 4487 | _ = 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 }); | |
| 4519 | 4489 | } |
| 4520 | 4490 | }; |
| 4521 | 4491 | |
| ... | ... | @@ -5315,7 +5285,7 @@ fn createThunks(macho_file: *MachO, sect_id: u8) !void { |
| 5315 | 5285 | try scanThunkRelocs(thunk_index, gpa, atoms[start..i], macho_file); |
| 5316 | 5286 | thunk.value = advanceSection(header, thunk.size(), .@"4"); |
| 5317 | 5287 | |
| 5318 | log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) }); | |
| 5288 | log.debug("thunk({d}) : {f}", .{ thunk_index, thunk.fmt(macho_file) }); | |
| 5319 | 5289 | } |
| 5320 | 5290 | } |
| 5321 | 5291 |
src/link/MachO/Archive.zig+25-58| ... | ... | @@ -29,7 +29,7 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File |
| 29 | 29 | pos += @sizeOf(ar_hdr); |
| 30 | 30 | |
| 31 | 31 | 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}'", .{ | |
| 33 | 33 | std.fmt.fmtSliceEscapeLower(ARFMAG), std.fmt.fmtSliceEscapeLower(&hdr.ar_fmag), |
| 34 | 34 | }); |
| 35 | 35 | } |
| ... | ... | @@ -71,53 +71,29 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File |
| 71 | 71 | .mtime = hdr.date() catch 0, |
| 72 | 72 | }; |
| 73 | 73 | |
| 74 | log.debug("extracting object '{}' from archive '{}'", .{ object.path, path }); | |
| 74 | log.debug("extracting object '{f}' from archive '{f}'", .{ object.path, path }); | |
| 75 | 75 | |
| 76 | 76 | try self.objects.append(gpa, object); |
| 77 | 77 | } |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | 80 | pub fn writeHeader( |
| 81 | bw: *std.io.BufferedWriter, | |
| 81 | 82 | object_name: []const u8, |
| 82 | 83 | object_size: usize, |
| 83 | 84 | 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'; | |
| 100 | 89 | @memcpy(&hdr.ar_fmag, ARFMAG); |
| 101 | ||
| 102 | 90 | 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; | |
| 103 | 92 | 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); | |
| 121 | 97 | } |
| 122 | 98 | |
| 123 | 99 | // Archive files start with the ARMAG identifying string. Then follows a |
| ... | ... | @@ -201,12 +177,12 @@ pub const ArSymtab = struct { |
| 201 | 177 | return ptr_width + ar.entries.items.len * 2 * ptr_width + ptr_width + mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width); |
| 202 | 178 | } |
| 203 | 179 | |
| 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 { | |
| 205 | 181 | const ptr_width = ptrWidth(format); |
| 206 | 182 | // Header |
| 207 | try writeHeader(SYMDEF, ar.size(format), format, writer); | |
| 183 | try writeHeader(bw, SYMDEF, ar.size(format), format); | |
| 208 | 184 | // 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); | |
| 210 | 186 | // Symtab entries |
| 211 | 187 | for (ar.entries.items) |entry| { |
| 212 | 188 | const file_off = switch (macho_file.getFile(entry.file).?) { |
| ... | ... | @@ -215,19 +191,16 @@ pub const ArSymtab = struct { |
| 215 | 191 | else => unreachable, |
| 216 | 192 | }; |
| 217 | 193 | // Name offset |
| 218 | try writeInt(format, entry.off, writer); | |
| 194 | try writeInt(bw, format, entry.off); | |
| 219 | 195 | // File offset |
| 220 | try writeInt(format, file_off, writer); | |
| 196 | try writeInt(bw, format, file_off); | |
| 221 | 197 | } |
| 222 | 198 | // Strtab size |
| 223 | 199 | 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); | |
| 226 | 201 | // 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); | |
| 231 | 204 | } |
| 232 | 205 | |
| 233 | 206 | const FormatContext = struct { |
| ... | ... | @@ -239,20 +212,14 @@ pub const ArSymtab = struct { |
| 239 | 212 | return .{ .data = .{ .ar = ar, .macho_file = macho_file } }; |
| 240 | 213 | } |
| 241 | 214 | |
| 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 { | |
| 248 | 216 | _ = unused_fmt_string; |
| 249 | _ = options; | |
| 250 | 217 | const ar = ctx.ar; |
| 251 | 218 | const macho_file = ctx.macho_file; |
| 252 | 219 | for (ar.entries.items, 0..) |entry, i| { |
| 253 | 220 | const name = ar.strtab.getAssumeExists(entry.off); |
| 254 | 221 | 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() }); | |
| 256 | 223 | } |
| 257 | 224 | } |
| 258 | 225 | |
| ... | ... | @@ -282,10 +249,10 @@ pub fn ptrWidth(format: Format) usize { |
| 282 | 249 | }; |
| 283 | 250 | } |
| 284 | 251 | |
| 285 | pub fn writeInt(format: Format, value: u64, writer: anytype) !void { | |
| 252 | pub fn writeInt(bw: *std.io.BufferedWriter, format: Format, value: u64) anyerror!void { | |
| 286 | 253 | 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), | |
| 289 | 256 | } |
| 290 | 257 | } |
| 291 | 258 |
src/link/MachO/Atom.zig+59-67| ... | ... | @@ -580,8 +580,10 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { |
| 580 | 580 | |
| 581 | 581 | relocs_log.debug("{x}: {s}", .{ self.value, name }); |
| 582 | 582 | |
| 583 | var bw: std.io.BufferedWriter = undefined; | |
| 584 | bw.initFixed(buffer); | |
| 585 | ||
| 583 | 586 | var has_error = false; |
| 584 | var stream = std.io.fixedBufferStream(buffer); | |
| 585 | 587 | var i: usize = 0; |
| 586 | 588 | while (i < relocs.len) : (i += 1) { |
| 587 | 589 | const rel = relocs[i]; |
| ... | ... | @@ -592,30 +594,28 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { |
| 592 | 594 | if (rel.getTargetSymbol(self, macho_file).getFile(macho_file) == null) continue; |
| 593 | 595 | } |
| 594 | 596 | |
| 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, | |
| 619 | 619 | }; |
| 620 | 620 | } |
| 621 | 621 | |
| ... | ... | @@ -638,8 +638,8 @@ fn resolveRelocInner( |
| 638 | 638 | subtractor: ?Relocation, |
| 639 | 639 | code: []u8, |
| 640 | 640 | macho_file: *MachO, |
| 641 | writer: anytype, | |
| 642 | ) ResolveError!void { | |
| 641 | bw: *std.io.BufferedWriter, | |
| 642 | ) anyerror!void { | |
| 643 | 643 | const t = &macho_file.base.comp.root_mod.resolved_target.result; |
| 644 | 644 | const cpu_arch = t.cpu.arch; |
| 645 | 645 | const rel_offset = math.cast(usize, rel.offset - self.off) orelse return error.Overflow; |
| ... | ... | @@ -653,7 +653,7 @@ fn resolveRelocInner( |
| 653 | 653 | const divExact = struct { |
| 654 | 654 | fn divExact(atom: Atom, r: Relocation, num: u12, den: u12, ctx: *MachO) !u12 { |
| 655 | 655 | 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}", .{ | |
| 657 | 657 | atom.getName(ctx), |
| 658 | 658 | r.fmtPretty(ctx.getTarget().cpu.arch), |
| 659 | 659 | r.offset, |
| ... | ... | @@ -664,14 +664,14 @@ fn resolveRelocInner( |
| 664 | 664 | }.divExact; |
| 665 | 665 | |
| 666 | 666 | switch (rel.tag) { |
| 667 | .local => relocs_log.debug(" {x}<+{d}>: {}: [=> {x}] atom({d})", .{ | |
| 667 | .local => relocs_log.debug(" {x}<+{d}>: {f}: [=> {x}] atom({d})", .{ | |
| 668 | 668 | P, |
| 669 | 669 | rel_offset, |
| 670 | 670 | rel.fmtPretty(cpu_arch), |
| 671 | 671 | S + A - SUB, |
| 672 | 672 | rel.getTargetAtom(self, macho_file).atom_index, |
| 673 | 673 | }), |
| 674 | .@"extern" => relocs_log.debug(" {x}<+{d}>: {}: [=> {x}] G({x}) ({s})", .{ | |
| 674 | .@"extern" => relocs_log.debug(" {x}<+{d}>: {f}: [=> {x}] G({x}) ({s})", .{ | |
| 675 | 675 | P, |
| 676 | 676 | rel_offset, |
| 677 | 677 | rel.fmtPretty(cpu_arch), |
| ... | ... | @@ -690,14 +690,14 @@ fn resolveRelocInner( |
| 690 | 690 | if (rel.tag == .@"extern") { |
| 691 | 691 | const sym = rel.getTargetSymbol(self, macho_file); |
| 692 | 692 | if (sym.isTlvInit(macho_file)) { |
| 693 | try writer.writeInt(u64, @intCast(S - TLS), .little); | |
| 693 | try bw.writeInt(u64, @intCast(S - TLS), .little); | |
| 694 | 694 | return; |
| 695 | 695 | } |
| 696 | 696 | if (sym.flags.import) return; |
| 697 | 697 | } |
| 698 | try writer.writeInt(u64, @bitCast(S + A - SUB), .little); | |
| 698 | try bw.writeInt(u64, @bitCast(S + A - SUB), .little); | |
| 699 | 699 | } 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); | |
| 701 | 701 | } else unreachable; |
| 702 | 702 | }, |
| 703 | 703 | |
| ... | ... | @@ -705,7 +705,7 @@ fn resolveRelocInner( |
| 705 | 705 | assert(rel.tag == .@"extern"); |
| 706 | 706 | assert(rel.meta.length == 2); |
| 707 | 707 | assert(rel.meta.pcrel); |
| 708 | try writer.writeInt(i32, @intCast(G + A - P), .little); | |
| 708 | try bw.writeInt(i32, @intCast(G + A - P), .little); | |
| 709 | 709 | }, |
| 710 | 710 | |
| 711 | 711 | .branch => { |
| ... | ... | @@ -714,7 +714,7 @@ fn resolveRelocInner( |
| 714 | 714 | assert(rel.tag == .@"extern"); |
| 715 | 715 | |
| 716 | 716 | 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), | |
| 718 | 718 | .aarch64 => { |
| 719 | 719 | const disp: i28 = math.cast(i28, S + A - P) orelse blk: { |
| 720 | 720 | const thunk = self.getThunk(macho_file); |
| ... | ... | @@ -732,10 +732,10 @@ fn resolveRelocInner( |
| 732 | 732 | assert(rel.meta.length == 2); |
| 733 | 733 | assert(rel.meta.pcrel); |
| 734 | 734 | 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); | |
| 736 | 736 | } else { |
| 737 | 737 | 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); | |
| 739 | 739 | } |
| 740 | 740 | }, |
| 741 | 741 | |
| ... | ... | @@ -746,17 +746,17 @@ fn resolveRelocInner( |
| 746 | 746 | const sym = rel.getTargetSymbol(self, macho_file); |
| 747 | 747 | if (sym.getSectionFlags().tlv_ptr) { |
| 748 | 748 | 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); | |
| 750 | 750 | } else { |
| 751 | 751 | 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); | |
| 753 | 753 | } |
| 754 | 754 | }, |
| 755 | 755 | |
| 756 | 756 | .signed, .signed1, .signed2, .signed4 => { |
| 757 | 757 | assert(rel.meta.length == 2); |
| 758 | 758 | assert(rel.meta.pcrel); |
| 759 | try writer.writeInt(i32, @intCast(S + A - P), .little); | |
| 759 | try bw.writeInt(i32, @intCast(S + A - P), .little); | |
| 760 | 760 | }, |
| 761 | 761 | |
| 762 | 762 | .page, |
| ... | ... | @@ -808,7 +808,7 @@ fn resolveRelocInner( |
| 808 | 808 | 2 => try divExact(self, rel, @truncate(target), 4, macho_file), |
| 809 | 809 | 3 => try divExact(self, rel, @truncate(target), 8, macho_file), |
| 810 | 810 | }; |
| 811 | try writer.writeInt(u32, inst.toU32(), .little); | |
| 811 | try bw.writeInt(u32, inst.toU32(), .little); | |
| 812 | 812 | } |
| 813 | 813 | }, |
| 814 | 814 | |
| ... | ... | @@ -886,7 +886,7 @@ fn resolveRelocInner( |
| 886 | 886 | .sf = @as(u1, @truncate(reg_info.size)), |
| 887 | 887 | }, |
| 888 | 888 | }; |
| 889 | try writer.writeInt(u32, inst.toU32(), .little); | |
| 889 | try bw.writeInt(u32, inst.toU32(), .little); | |
| 890 | 890 | }, |
| 891 | 891 | } |
| 892 | 892 | } |
| ... | ... | @@ -900,19 +900,19 @@ const x86_64 = struct { |
| 900 | 900 | switch (old_inst.encoding.mnemonic) { |
| 901 | 901 | .mov => { |
| 902 | 902 | 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 }); | |
| 904 | 904 | encode(&.{inst}, code) catch return error.RelaxFail; |
| 905 | 905 | }, |
| 906 | 906 | else => |x| { |
| 907 | 907 | 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}", .{ | |
| 909 | 909 | self.getName(macho_file), |
| 910 | 910 | self.getAddress(macho_file), |
| 911 | 911 | rel.offset, |
| 912 | 912 | rel.fmtPretty(.x86_64), |
| 913 | 913 | }); |
| 914 | 914 | 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()}); | |
| 916 | 916 | return error.RelaxFailUnexpectedInstruction; |
| 917 | 917 | }, |
| 918 | 918 | } |
| ... | ... | @@ -924,7 +924,7 @@ const x86_64 = struct { |
| 924 | 924 | switch (old_inst.encoding.mnemonic) { |
| 925 | 925 | .mov => { |
| 926 | 926 | 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 }); | |
| 928 | 928 | encode(&.{inst}, code) catch return error.RelaxFail; |
| 929 | 929 | }, |
| 930 | 930 | else => return error.RelaxFail, |
| ... | ... | @@ -938,11 +938,9 @@ const x86_64 = struct { |
| 938 | 938 | } |
| 939 | 939 | |
| 940 | 940 | 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, .{}); | |
| 946 | 944 | } |
| 947 | 945 | |
| 948 | 946 | 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 |
| 1003 | 1001 | } |
| 1004 | 1002 | |
| 1005 | 1003 | switch (rel.tag) { |
| 1006 | .local => relocs_log.debug(" {}: [{x} => {d}({s},{s})] + {x}", .{ | |
| 1004 | .local => relocs_log.debug(" {f}: [{x} => {d}({s},{s})] + {x}", .{ | |
| 1007 | 1005 | rel.fmtPretty(cpu_arch), |
| 1008 | 1006 | r_address, |
| 1009 | 1007 | r_symbolnum, |
| ... | ... | @@ -1011,7 +1009,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r |
| 1011 | 1009 | macho_file.sections.items(.header)[r_symbolnum - 1].sectName(), |
| 1012 | 1010 | addend, |
| 1013 | 1011 | }), |
| 1014 | .@"extern" => relocs_log.debug(" {}: [{x} => {d}({s})] + {x}", .{ | |
| 1012 | .@"extern" => relocs_log.debug(" {f}: [{x} => {d}({s})] + {x}", .{ | |
| 1015 | 1013 | rel.fmtPretty(cpu_arch), |
| 1016 | 1014 | r_address, |
| 1017 | 1015 | r_symbolnum, |
| ... | ... | @@ -1142,33 +1140,27 @@ const FormatContext = struct { |
| 1142 | 1140 | macho_file: *MachO, |
| 1143 | 1141 | }; |
| 1144 | 1142 | |
| 1145 | fn format2( | |
| 1146 | ctx: FormatContext, | |
| 1147 | comptime unused_fmt_string: []const u8, | |
| 1148 | options: std.fmt.FormatOptions, | |
| 1149 | writer: anytype, | |
| 1150 | ) !void { | |
| 1151 | _ = options; | |
| 1143 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1152 | 1144 | _ = unused_fmt_string; |
| 1153 | 1145 | const atom = ctx.atom; |
| 1154 | 1146 | const macho_file = ctx.macho_file; |
| 1155 | 1147 | 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})", .{ | |
| 1157 | 1149 | atom.atom_index, atom.getName(macho_file), atom.getAddress(macho_file), |
| 1158 | 1150 | atom.out_n_sect, atom.alignment, atom.size, |
| 1159 | 1151 | atom.getRelocs(macho_file).len, atom.getExtra(macho_file).thunk, |
| 1160 | 1152 | }); |
| 1161 | if (!atom.isAlive()) try writer.writeAll(" : [*]"); | |
| 1153 | if (!atom.isAlive()) try bw.writeAll(" : [*]"); | |
| 1162 | 1154 | if (atom.getUnwindRecords(macho_file).len > 0) { |
| 1163 | try writer.writeAll(" : unwind{ "); | |
| 1155 | try bw.writeAll(" : unwind{ "); | |
| 1164 | 1156 | const extra = atom.getExtra(macho_file); |
| 1165 | 1157 | for (atom.getUnwindRecords(macho_file), extra.unwind_index..) |index, i| { |
| 1166 | 1158 | 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(", "); | |
| 1170 | 1162 | } |
| 1171 | try writer.writeAll(" }"); | |
| 1163 | try bw.writeAll(" }"); | |
| 1172 | 1164 | } |
| 1173 | 1165 | } |
| 1174 | 1166 |
src/link/MachO/CodeSignature.zig+13-9| ... | ... | @@ -247,7 +247,7 @@ pub fn deinit(self: *CodeSignature, allocator: Allocator) void { |
| 247 | 247 | pub fn addEntitlements(self: *CodeSignature, allocator: Allocator, path: []const u8) !void { |
| 248 | 248 | const file = try fs.cwd().openFile(path, .{}); |
| 249 | 249 | defer file.close(); |
| 250 | const inner = try file.readToEndAlloc(allocator, std.math.maxInt(u32)); | |
| 250 | const inner = try file.readToEndAlloc(allocator, .unlimited); | |
| 251 | 251 | self.entitlements = .{ .inner = inner }; |
| 252 | 252 | } |
| 253 | 253 | |
| ... | ... | @@ -304,10 +304,12 @@ pub fn writeAdhocSignature( |
| 304 | 304 | var hash: [hash_size]u8 = undefined; |
| 305 | 305 | |
| 306 | 306 | 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, .{}); | |
| 311 | 313 | self.code_directory.addSpecialHash(req.slotType(), hash); |
| 312 | 314 | |
| 313 | 315 | try blobs.append(.{ .requirements = req }); |
| ... | ... | @@ -316,10 +318,12 @@ pub fn writeAdhocSignature( |
| 316 | 318 | } |
| 317 | 319 | |
| 318 | 320 | 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, .{}); | |
| 323 | 327 | self.code_directory.addSpecialHash(ents.slotType(), hash); |
| 324 | 328 | |
| 325 | 329 | try blobs.append(.{ .entitlements = ents }); |
src/link/MachO/DebugSymbols.zig+12-16| ... | ... | @@ -269,18 +269,15 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 269 | 269 | |
| 270 | 270 | fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, usize } { |
| 271 | 271 | 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); | |
| 278 | 275 | |
| 279 | 276 | var ncmds: usize = 0; |
| 280 | 277 | |
| 281 | 278 | // UUID comes first presumably to speed up lookup by the consumer like lldb. |
| 282 | 279 | @memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid); |
| 283 | try writer.writeStruct(self.uuid_cmd); | |
| 280 | try bw.writeStruct(self.uuid_cmd); | |
| 284 | 281 | ncmds += 1; |
| 285 | 282 | |
| 286 | 283 | // Segment and section load commands |
| ... | ... | @@ -293,11 +290,11 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u |
| 293 | 290 | var out_seg = seg; |
| 294 | 291 | out_seg.fileoff = 0; |
| 295 | 292 | out_seg.filesize = 0; |
| 296 | try writer.writeStruct(out_seg); | |
| 293 | try bw.writeStruct(out_seg); | |
| 297 | 294 | for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| { |
| 298 | 295 | var out_header = header; |
| 299 | 296 | out_header.offset = 0; |
| 300 | try writer.writeStruct(out_header); | |
| 297 | try bw.writeStruct(out_header); | |
| 301 | 298 | } |
| 302 | 299 | sect_id += seg.nsects; |
| 303 | 300 | } |
| ... | ... | @@ -306,23 +303,22 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u |
| 306 | 303 | // Next, commit DSYM's __LINKEDIT and __DWARF segments headers. |
| 307 | 304 | sect_id = 0; |
| 308 | 305 | for (self.segments.items) |seg| { |
| 309 | try writer.writeStruct(seg); | |
| 306 | try bw.writeStruct(seg); | |
| 310 | 307 | for (self.sections.items[sect_id..][0..seg.nsects]) |header| { |
| 311 | try writer.writeStruct(header); | |
| 308 | try bw.writeStruct(header); | |
| 312 | 309 | } |
| 313 | 310 | sect_id += seg.nsects; |
| 314 | 311 | } |
| 315 | 312 | ncmds += self.segments.items.len; |
| 316 | 313 | } |
| 317 | 314 | |
| 318 | try writer.writeStruct(self.symtab_cmd); | |
| 315 | try bw.writeStruct(self.symtab_cmd); | |
| 319 | 316 | ncmds += 1; |
| 320 | 317 | |
| 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)); | |
| 324 | 320 | |
| 325 | return .{ ncmds, buffer.len }; | |
| 321 | return .{ ncmds, bw.end }; | |
| 326 | 322 | } |
| 327 | 323 | |
| 328 | 324 | fn 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 { |
| 81 | 81 | .dwarf64 => 12, |
| 82 | 82 | } + cuh_length; |
| 83 | 83 | while (p.pos < end_pos) { |
| 84 | const di_code = try p.readUleb128(u64); | |
| 84 | const di_code = try p.readLeb128(u64); | |
| 85 | 85 | if (di_code == 0) return error.UnexpectedEndOfFile; |
| 86 | 86 | if (di_code == code) return; |
| 87 | 87 | |
| ... | ... | @@ -174,14 +174,14 @@ pub const InfoReader = struct { |
| 174 | 174 | dw.FORM.block1 => try p.readByte(), |
| 175 | 175 | dw.FORM.block2 => try p.readInt(u16), |
| 176 | 176 | dw.FORM.block4 => try p.readInt(u32), |
| 177 | dw.FORM.block => try p.readUleb128(u64), | |
| 177 | dw.FORM.block => try p.readLeb128(u64), | |
| 178 | 178 | else => unreachable, |
| 179 | 179 | }; |
| 180 | 180 | return p.readNBytes(len); |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | pub fn readExprLoc(p: *InfoReader) ![]const u8 { |
| 184 | const len: u64 = try p.readUleb128(u64); | |
| 184 | const len: u64 = try p.readLeb128(u64); | |
| 185 | 185 | return p.readNBytes(len); |
| 186 | 186 | } |
| 187 | 187 | |
| ... | ... | @@ -191,8 +191,8 @@ pub const InfoReader = struct { |
| 191 | 191 | dw.FORM.data2, dw.FORM.ref2 => try p.readInt(u16), |
| 192 | 192 | dw.FORM.data4, dw.FORM.ref4 => try p.readInt(u32), |
| 193 | 193 | 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)), | |
| 196 | 196 | else => return error.UnhandledConstantForm, |
| 197 | 197 | }; |
| 198 | 198 | } |
| ... | ... | @@ -203,7 +203,7 @@ pub const InfoReader = struct { |
| 203 | 203 | dw.FORM.strx2, dw.FORM.addrx2 => try p.readInt(u16), |
| 204 | 204 | dw.FORM.strx3, dw.FORM.addrx3 => error.UnhandledForm, |
| 205 | 205 | 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), | |
| 207 | 207 | else => return error.UnhandledIndexForm, |
| 208 | 208 | }; |
| 209 | 209 | } |
| ... | ... | @@ -272,20 +272,11 @@ pub const InfoReader = struct { |
| 272 | 272 | }; |
| 273 | 273 | } |
| 274 | 274 | |
| 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); | |
| 289 | 280 | } |
| 290 | 281 | |
| 291 | 282 | pub fn seekTo(p: *InfoReader, off: u64) !void { |
| ... | ... | @@ -307,10 +298,10 @@ pub const AbbrevReader = struct { |
| 307 | 298 | |
| 308 | 299 | pub fn readDecl(p: *AbbrevReader) !?AbbrevDecl { |
| 309 | 300 | const pos = p.pos; |
| 310 | const code = try p.readUleb128(Code); | |
| 301 | const code = try p.readLeb128(Code); | |
| 311 | 302 | if (code == 0) return null; |
| 312 | 303 | |
| 313 | const tag = try p.readUleb128(Tag); | |
| 304 | const tag = try p.readLeb128(Tag); | |
| 314 | 305 | const has_children = (try p.readByte()) > 0; |
| 315 | 306 | return .{ |
| 316 | 307 | .code = code, |
| ... | ... | @@ -323,8 +314,8 @@ pub const AbbrevReader = struct { |
| 323 | 314 | |
| 324 | 315 | pub fn readAttr(p: *AbbrevReader) !?AbbrevAttr { |
| 325 | 316 | 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); | |
| 328 | 319 | return if (at == 0 and form == 0) null else .{ |
| 329 | 320 | .at = at, |
| 330 | 321 | .form = form, |
| ... | ... | @@ -339,12 +330,11 @@ pub const AbbrevReader = struct { |
| 339 | 330 | return p.bytes()[p.pos]; |
| 340 | 331 | } |
| 341 | 332 | |
| 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); | |
| 348 | 338 | } |
| 349 | 339 | |
| 350 | 340 | 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 { |
| 61 | 61 | const file = macho_file.getFileHandle(self.file_handle); |
| 62 | 62 | const offset = self.offset; |
| 63 | 63 | |
| 64 | log.debug("parsing dylib from binary: {}", .{@as(Path, self.path)}); | |
| 64 | log.debug("parsing dylib from binary: {f}", .{@as(Path, self.path)}); | |
| 65 | 65 | |
| 66 | 66 | var header_buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined; |
| 67 | 67 | { |
| ... | ... | @@ -140,7 +140,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void { |
| 140 | 140 | |
| 141 | 141 | if (self.platform) |platform| { |
| 142 | 142 | 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}", .{ | |
| 144 | 144 | platform.fmtTarget(macho_file.getTarget().cpu.arch), |
| 145 | 145 | }); |
| 146 | 146 | return error.InvalidTarget; |
| ... | ... | @@ -148,7 +148,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void { |
| 148 | 148 | // TODO: this can cause the CI to fail so I'm commenting this check out so that |
| 149 | 149 | // I can work out the rest of the changes first |
| 150 | 150 | // 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}", .{ | |
| 152 | 152 | // macho_file.platform.fmtTarget(macho_file.getTarget().cpu.arch), |
| 153 | 153 | // macho_file.platform.version, |
| 154 | 154 | // platform.version, |
| ... | ... | @@ -158,46 +158,6 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void { |
| 158 | 158 | } |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | const 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 | ||
| 201 | 161 | pub fn addExport(self: *Dylib, allocator: Allocator, name: []const u8, flags: Export.Flags) !void { |
| 202 | 162 | try self.exports.append(allocator, .{ |
| 203 | 163 | .name = try self.addString(allocator, name), |
| ... | ... | @@ -207,16 +167,16 @@ pub fn addExport(self: *Dylib, allocator: Allocator, name: []const u8, flags: Ex |
| 207 | 167 | |
| 208 | 168 | fn parseTrieNode( |
| 209 | 169 | self: *Dylib, |
| 210 | it: *TrieIterator, | |
| 170 | br: *std.io.BufferedReader, | |
| 211 | 171 | allocator: Allocator, |
| 212 | 172 | arena: Allocator, |
| 213 | 173 | prefix: []const u8, |
| 214 | 174 | ) !void { |
| 215 | 175 | const tracy = trace(@src()); |
| 216 | 176 | defer tracy.end(); |
| 217 | const size = try it.readUleb128(); | |
| 177 | const size = try br.takeLeb128(u64); | |
| 218 | 178 | if (size > 0) { |
| 219 | const flags = try it.readUleb128(); | |
| 179 | const flags = try br.takeLeb128(u8); | |
| 220 | 180 | const kind = flags & macho.EXPORT_SYMBOL_FLAGS_KIND_MASK; |
| 221 | 181 | const out_flags = Export.Flags{ |
| 222 | 182 | .abs = kind == macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE, |
| ... | ... | @@ -224,29 +184,28 @@ fn parseTrieNode( |
| 224 | 184 | .weak = flags & macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION != 0, |
| 225 | 185 | }; |
| 226 | 186 | 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); | |
| 229 | 189 | try self.addExport(allocator, if (name.len > 0) name else prefix, out_flags); |
| 230 | 190 | } 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 | |
| 233 | 193 | try self.addExport(allocator, prefix, out_flags); |
| 234 | 194 | } else { |
| 235 | _ = try it.readUleb128(); // VM offset | |
| 195 | _ = try br.takeLeb128(u64); // VM offset | |
| 236 | 196 | try self.addExport(allocator, prefix, out_flags); |
| 237 | 197 | } |
| 238 | 198 | } |
| 239 | 199 | |
| 240 | const nedges = try it.readByte(); | |
| 241 | ||
| 200 | const nedges = try br.takeByte(); | |
| 242 | 201 | 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); | |
| 245 | 204 | 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; | |
| 250 | 209 | } |
| 251 | 210 | } |
| 252 | 211 | |
| ... | ... | @@ -257,8 +216,9 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void { |
| 257 | 216 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 258 | 217 | defer arena.deinit(); |
| 259 | 218 | |
| 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(), ""); | |
| 262 | 222 | } |
| 263 | 223 | |
| 264 | 224 | fn parseTbd(self: *Dylib, macho_file: *MachO) !void { |
| ... | ... | @@ -267,7 +227,7 @@ fn parseTbd(self: *Dylib, macho_file: *MachO) !void { |
| 267 | 227 | |
| 268 | 228 | const gpa = macho_file.base.comp.gpa; |
| 269 | 229 | |
| 270 | log.debug("parsing dylib from stub: {}", .{self.path}); | |
| 230 | log.debug("parsing dylib from stub: {f}", .{self.path}); | |
| 271 | 231 | |
| 272 | 232 | const file = macho_file.getFileHandle(self.file_handle); |
| 273 | 233 | var lib_stub = LibStub.loadFromFile(gpa, file) catch |err| { |
| ... | ... | @@ -716,24 +676,18 @@ const FormatContext = struct { |
| 716 | 676 | macho_file: *MachO, |
| 717 | 677 | }; |
| 718 | 678 | |
| 719 | fn formatSymtab( | |
| 720 | ctx: FormatContext, | |
| 721 | comptime unused_fmt_string: []const u8, | |
| 722 | options: std.fmt.FormatOptions, | |
| 723 | writer: anytype, | |
| 724 | ) !void { | |
| 679 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 725 | 680 | _ = unused_fmt_string; |
| 726 | _ = options; | |
| 727 | 681 | const dylib = ctx.dylib; |
| 728 | 682 | const macho_file = ctx.macho_file; |
| 729 | try writer.writeAll(" globals\n"); | |
| 683 | try bw.writeAll(" globals\n"); | |
| 730 | 684 | for (dylib.symbols.items, 0..) |sym, i| { |
| 731 | 685 | const ref = dylib.getSymbolRef(@intCast(i), macho_file); |
| 732 | 686 | if (ref.getFile(macho_file) == null) { |
| 733 | 687 | // 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)}); | |
| 735 | 689 | } 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)}); | |
| 737 | 691 | } |
| 738 | 692 | } |
| 739 | 693 | } |
src/link/MachO/InternalObject.zig+8-20| ... | ... | @@ -261,7 +261,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil |
| 261 | 261 | |
| 262 | 262 | sect.offset = @intCast(self.objc_methnames.items.len); |
| 263 | 263 | 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; | |
| 265 | 265 | |
| 266 | 266 | const name_str = try self.addString(gpa, "ltmp"); |
| 267 | 267 | const sym_index = try self.addSymbol(gpa); |
| ... | ... | @@ -848,18 +848,12 @@ pub fn fmtAtoms(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(for |
| 848 | 848 | } }; |
| 849 | 849 | } |
| 850 | 850 | |
| 851 | fn formatAtoms( | |
| 852 | ctx: FormatContext, | |
| 853 | comptime unused_fmt_string: []const u8, | |
| 854 | options: std.fmt.FormatOptions, | |
| 855 | writer: anytype, | |
| 856 | ) !void { | |
| 851 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 857 | 852 | _ = unused_fmt_string; |
| 858 | _ = options; | |
| 859 | try writer.writeAll(" atoms\n"); | |
| 853 | try bw.writeAll(" atoms\n"); | |
| 860 | 854 | for (ctx.self.getAtoms()) |atom_index| { |
| 861 | 855 | 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)}); | |
| 863 | 857 | } |
| 864 | 858 | } |
| 865 | 859 | |
| ... | ... | @@ -870,24 +864,18 @@ pub fn fmtSymtab(self: *InternalObject, macho_file: *MachO) std.fmt.Formatter(fo |
| 870 | 864 | } }; |
| 871 | 865 | } |
| 872 | 866 | |
| 873 | fn formatSymtab( | |
| 874 | ctx: FormatContext, | |
| 875 | comptime unused_fmt_string: []const u8, | |
| 876 | options: std.fmt.FormatOptions, | |
| 877 | writer: anytype, | |
| 878 | ) !void { | |
| 867 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 879 | 868 | _ = unused_fmt_string; |
| 880 | _ = options; | |
| 881 | 869 | const macho_file = ctx.macho_file; |
| 882 | 870 | const self = ctx.self; |
| 883 | try writer.writeAll(" symbols\n"); | |
| 871 | try bw.writeAll(" symbols\n"); | |
| 884 | 872 | for (self.symbols.items, 0..) |sym, i| { |
| 885 | 873 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 886 | 874 | if (ref.getFile(macho_file) == null) { |
| 887 | 875 | // 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)}); | |
| 889 | 877 | } 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)}); | |
| 891 | 879 | } |
| 892 | 880 | } |
| 893 | 881 | } |
src/link/MachO/Object.zig+39-92| ... | ... | @@ -72,7 +72,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void { |
| 72 | 72 | const tracy = trace(@src()); |
| 73 | 73 | defer tracy.end(); |
| 74 | 74 | |
| 75 | log.debug("parsing {}", .{self.fmtPath()}); | |
| 75 | log.debug("parsing {f}", .{self.fmtPath()}); | |
| 76 | 76 | |
| 77 | 77 | const gpa = macho_file.base.comp.gpa; |
| 78 | 78 | const handle = macho_file.getFileHandle(self.file_handle); |
| ... | ... | @@ -239,7 +239,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void { |
| 239 | 239 | |
| 240 | 240 | if (self.platform) |platform| { |
| 241 | 241 | 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}", .{ | |
| 243 | 243 | platform.fmtTarget(cpu_arch), |
| 244 | 244 | }); |
| 245 | 245 | return error.InvalidTarget; |
| ... | ... | @@ -247,7 +247,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void { |
| 247 | 247 | // TODO: this causes the CI to fail so I'm commenting this check out so that |
| 248 | 248 | // I can work out the rest of the changes first |
| 249 | 249 | // 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}", .{ | |
| 251 | 251 | // macho_file.platform.fmtTarget(macho_file.getTarget().cpu.arch), |
| 252 | 252 | // macho_file.platform.version, |
| 253 | 253 | // platform.version, |
| ... | ... | @@ -1065,7 +1065,8 @@ fn initEhFrameRecords(self: *Object, allocator: Allocator, sect_id: u8, file: Fi |
| 1065 | 1065 | } |
| 1066 | 1066 | } |
| 1067 | 1067 | |
| 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); | |
| 1069 | 1070 | while (try it.next()) |rec| { |
| 1070 | 1071 | switch (rec.tag) { |
| 1071 | 1072 | .cie => try self.cies.append(allocator, .{ |
| ... | ... | @@ -1694,11 +1695,11 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void { |
| 1694 | 1695 | }; |
| 1695 | 1696 | } |
| 1696 | 1697 | |
| 1697 | pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void { | |
| 1698 | pub fn writeAr(self: Object, bw: *std.io.BufferedWriter, ar_format: Archive.Format, macho_file: *MachO) !void { | |
| 1698 | 1699 | // Header |
| 1699 | 1700 | const size = try macho_file.cast(usize, self.output_ar_state.size); |
| 1700 | 1701 | 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); | |
| 1702 | 1703 | // Data |
| 1703 | 1704 | const file = macho_file.getFileHandle(self.file_handle); |
| 1704 | 1705 | // TODO try using copyRangeAll |
| ... | ... | @@ -1707,7 +1708,7 @@ pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writ |
| 1707 | 1708 | defer gpa.free(data); |
| 1708 | 1709 | const amt = try file.preadAll(data, self.offset); |
| 1709 | 1710 | if (amt != size) return error.InputOutput; |
| 1710 | try writer.writeAll(data); | |
| 1711 | try bw.writeAll(data); | |
| 1711 | 1712 | } |
| 1712 | 1713 | |
| 1713 | 1714 | pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void { |
| ... | ... | @@ -1861,7 +1862,7 @@ pub fn writeAtomsRelocatable(self: *Object, macho_file: *MachO) !void { |
| 1861 | 1862 | } |
| 1862 | 1863 | gpa.free(sections_data); |
| 1863 | 1864 | } |
| 1864 | @memset(sections_data, &[0]u8{}); | |
| 1865 | @memset(sections_data, &.{}); | |
| 1865 | 1866 | const file = macho_file.getFileHandle(self.file_handle); |
| 1866 | 1867 | |
| 1867 | 1868 | for (headers, 0..) |header, n_sect| { |
| ... | ... | @@ -2512,16 +2513,10 @@ pub fn readSectionData(self: Object, allocator: Allocator, file: File.Handle, n_ |
| 2512 | 2513 | return data; |
| 2513 | 2514 | } |
| 2514 | 2515 | |
| 2515 | pub fn format( | |
| 2516 | self: *Object, | |
| 2517 | comptime unused_fmt_string: []const u8, | |
| 2518 | options: std.fmt.FormatOptions, | |
| 2519 | writer: anytype, | |
| 2520 | ) !void { | |
| 2516 | pub fn format(self: *Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2521 | 2517 | _ = self; |
| 2518 | _ = bw; | |
| 2522 | 2519 | _ = unused_fmt_string; |
| 2523 | _ = options; | |
| 2524 | _ = writer; | |
| 2525 | 2520 | @compileError("do not format objects directly"); |
| 2526 | 2521 | } |
| 2527 | 2522 | |
| ... | ... | @@ -2537,20 +2532,14 @@ pub fn fmtAtoms(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatAtoms |
| 2537 | 2532 | } }; |
| 2538 | 2533 | } |
| 2539 | 2534 | |
| 2540 | fn formatAtoms( | |
| 2541 | ctx: FormatContext, | |
| 2542 | comptime unused_fmt_string: []const u8, | |
| 2543 | options: std.fmt.FormatOptions, | |
| 2544 | writer: anytype, | |
| 2545 | ) !void { | |
| 2535 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2546 | 2536 | _ = unused_fmt_string; |
| 2547 | _ = options; | |
| 2548 | 2537 | const object = ctx.object; |
| 2549 | 2538 | const macho_file = ctx.macho_file; |
| 2550 | try writer.writeAll(" atoms\n"); | |
| 2539 | try bw.writeAll(" atoms\n"); | |
| 2551 | 2540 | for (object.getAtoms()) |atom_index| { |
| 2552 | 2541 | 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)}); | |
| 2554 | 2543 | } |
| 2555 | 2544 | } |
| 2556 | 2545 | |
| ... | ... | @@ -2561,18 +2550,12 @@ pub fn fmtCies(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatCies) |
| 2561 | 2550 | } }; |
| 2562 | 2551 | } |
| 2563 | 2552 | |
| 2564 | fn formatCies( | |
| 2565 | ctx: FormatContext, | |
| 2566 | comptime unused_fmt_string: []const u8, | |
| 2567 | options: std.fmt.FormatOptions, | |
| 2568 | writer: anytype, | |
| 2569 | ) !void { | |
| 2553 | fn formatCies(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2570 | 2554 | _ = unused_fmt_string; |
| 2571 | _ = options; | |
| 2572 | 2555 | const object = ctx.object; |
| 2573 | try writer.writeAll(" cies\n"); | |
| 2556 | try bw.writeAll(" cies\n"); | |
| 2574 | 2557 | 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) }); | |
| 2576 | 2559 | } |
| 2577 | 2560 | } |
| 2578 | 2561 | |
| ... | ... | @@ -2583,18 +2566,12 @@ pub fn fmtFdes(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatFdes) |
| 2583 | 2566 | } }; |
| 2584 | 2567 | } |
| 2585 | 2568 | |
| 2586 | fn formatFdes( | |
| 2587 | ctx: FormatContext, | |
| 2588 | comptime unused_fmt_string: []const u8, | |
| 2589 | options: std.fmt.FormatOptions, | |
| 2590 | writer: anytype, | |
| 2591 | ) !void { | |
| 2569 | fn formatFdes(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2592 | 2570 | _ = unused_fmt_string; |
| 2593 | _ = options; | |
| 2594 | 2571 | const object = ctx.object; |
| 2595 | try writer.writeAll(" fdes\n"); | |
| 2572 | try bw.writeAll(" fdes\n"); | |
| 2596 | 2573 | 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) }); | |
| 2598 | 2575 | } |
| 2599 | 2576 | } |
| 2600 | 2577 | |
| ... | ... | @@ -2605,19 +2582,13 @@ pub fn fmtUnwindRecords(self: *Object, macho_file: *MachO) std.fmt.Formatter(for |
| 2605 | 2582 | } }; |
| 2606 | 2583 | } |
| 2607 | 2584 | |
| 2608 | fn formatUnwindRecords( | |
| 2609 | ctx: FormatContext, | |
| 2610 | comptime unused_fmt_string: []const u8, | |
| 2611 | options: std.fmt.FormatOptions, | |
| 2612 | writer: anytype, | |
| 2613 | ) !void { | |
| 2585 | fn formatUnwindRecords(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2614 | 2586 | _ = unused_fmt_string; |
| 2615 | _ = options; | |
| 2616 | 2587 | const object = ctx.object; |
| 2617 | 2588 | const macho_file = ctx.macho_file; |
| 2618 | try writer.writeAll(" unwind records\n"); | |
| 2589 | try bw.writeAll(" unwind records\n"); | |
| 2619 | 2590 | 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) }); | |
| 2621 | 2592 | } |
| 2622 | 2593 | } |
| 2623 | 2594 | |
| ... | ... | @@ -2628,34 +2599,28 @@ pub fn fmtSymtab(self: *Object, macho_file: *MachO) std.fmt.Formatter(formatSymt |
| 2628 | 2599 | } }; |
| 2629 | 2600 | } |
| 2630 | 2601 | |
| 2631 | fn formatSymtab( | |
| 2632 | ctx: FormatContext, | |
| 2633 | comptime unused_fmt_string: []const u8, | |
| 2634 | options: std.fmt.FormatOptions, | |
| 2635 | writer: anytype, | |
| 2636 | ) !void { | |
| 2602 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2637 | 2603 | _ = unused_fmt_string; |
| 2638 | _ = options; | |
| 2639 | 2604 | const object = ctx.object; |
| 2640 | 2605 | const macho_file = ctx.macho_file; |
| 2641 | try writer.writeAll(" symbols\n"); | |
| 2606 | try bw.writeAll(" symbols\n"); | |
| 2642 | 2607 | for (object.symbols.items, 0..) |sym, i| { |
| 2643 | 2608 | const ref = object.getSymbolRef(@intCast(i), macho_file); |
| 2644 | 2609 | if (ref.getFile(macho_file) == null) { |
| 2645 | 2610 | // 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)}); | |
| 2647 | 2612 | } 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)}); | |
| 2649 | 2614 | } |
| 2650 | 2615 | } |
| 2651 | 2616 | for (object.stab_files.items) |sf| { |
| 2652 | try writer.print(" stabs({s},{s},{s})\n", .{ | |
| 2617 | try bw.print(" stabs({s},{s},{s})\n", .{ | |
| 2653 | 2618 | sf.getCompDir(object.*), |
| 2654 | 2619 | sf.getTuName(object.*), |
| 2655 | 2620 | sf.getOsoPath(object.*), |
| 2656 | 2621 | }); |
| 2657 | 2622 | for (sf.stabs.items) |stab| { |
| 2658 | try writer.print(" {}", .{stab.fmt(object.*)}); | |
| 2623 | try bw.print(" {f}", .{stab.fmt(object.*)}); | |
| 2659 | 2624 | } |
| 2660 | 2625 | } |
| 2661 | 2626 | } |
| ... | ... | @@ -2664,20 +2629,14 @@ pub fn fmtPath(self: Object) std.fmt.Formatter(formatPath) { |
| 2664 | 2629 | return .{ .data = self }; |
| 2665 | 2630 | } |
| 2666 | 2631 | |
| 2667 | fn formatPath( | |
| 2668 | object: Object, | |
| 2669 | comptime unused_fmt_string: []const u8, | |
| 2670 | options: std.fmt.FormatOptions, | |
| 2671 | writer: anytype, | |
| 2672 | ) !void { | |
| 2632 | fn formatPath(object: Object, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 2673 | 2633 | _ = unused_fmt_string; |
| 2674 | _ = options; | |
| 2675 | 2634 | 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(), | |
| 2678 | 2637 | }); |
| 2679 | 2638 | } else { |
| 2680 | try writer.print("{}", .{@as(Path, object.path)}); | |
| 2639 | try bw.print("{f}", .{object.path}); | |
| 2681 | 2640 | } |
| 2682 | 2641 | } |
| 2683 | 2642 | |
| ... | ... | @@ -2731,16 +2690,10 @@ const StabFile = struct { |
| 2731 | 2690 | return object.symbols.items[index]; |
| 2732 | 2691 | } |
| 2733 | 2692 | |
| 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 { | |
| 2740 | 2694 | _ = stab; |
| 2695 | _ = bw; | |
| 2741 | 2696 | _ = unused_fmt_string; |
| 2742 | _ = options; | |
| 2743 | _ = writer; | |
| 2744 | 2697 | @compileError("do not format stabs directly"); |
| 2745 | 2698 | } |
| 2746 | 2699 | |
| ... | ... | @@ -2750,22 +2703,16 @@ const StabFile = struct { |
| 2750 | 2703 | return .{ .data = .{ stab, object } }; |
| 2751 | 2704 | } |
| 2752 | 2705 | |
| 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 { | |
| 2759 | 2707 | _ = unused_fmt_string; |
| 2760 | _ = options; | |
| 2761 | 2708 | const stab, const object = ctx; |
| 2762 | 2709 | const sym = stab.getSymbol(object).?; |
| 2763 | 2710 | if (stab.is_func) { |
| 2764 | try writer.print("func({d})", .{stab.index.?}); | |
| 2711 | try bw.print("func({d})", .{stab.index.?}); | |
| 2765 | 2712 | } else if (sym.visibility == .global) { |
| 2766 | try writer.print("gsym({d})", .{stab.index.?}); | |
| 2713 | try bw.print("gsym({d})", .{stab.index.?}); | |
| 2767 | 2714 | } else { |
| 2768 | try writer.print("stsym({d})", .{stab.index.?}); | |
| 2715 | try bw.print("stsym({d})", .{stab.index.?}); | |
| 2769 | 2716 | } |
| 2770 | 2717 | } |
| 2771 | 2718 | }; |
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 |
| 76 | 76 | return .{ .data = .{ rel, cpu_arch } }; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | fn formatPretty( | |
| 80 | ctx: FormatCtx, | |
| 81 | comptime unused_fmt_string: []const u8, | |
| 82 | options: std.fmt.FormatOptions, | |
| 83 | writer: anytype, | |
| 84 | ) !void { | |
| 85 | _ = options; | |
| 79 | fn formatPretty(ctx: FormatCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 86 | 80 | _ = unused_fmt_string; |
| 87 | 81 | const rel, const cpu_arch = ctx; |
| 88 | const str = switch (rel.type) { | |
| 82 | try bw.writeAll(switch (rel.type) { | |
| 89 | 83 | .signed => "X86_64_RELOC_SIGNED", |
| 90 | 84 | .signed1 => "X86_64_RELOC_SIGNED_1", |
| 91 | 85 | .signed2 => "X86_64_RELOC_SIGNED_2", |
| ... | ... | @@ -118,8 +112,7 @@ fn formatPretty( |
| 118 | 112 | .aarch64 => "ARM64_RELOC_UNSIGNED", |
| 119 | 113 | else => unreachable, |
| 120 | 114 | }, |
| 121 | }; | |
| 122 | try writer.writeAll(str); | |
| 115 | }); | |
| 123 | 116 | } |
| 124 | 117 | |
| 125 | 118 | pub 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 |
| 286 | 286 | } |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | pub fn format( | |
| 290 | symbol: Symbol, | |
| 291 | comptime unused_fmt_string: []const u8, | |
| 292 | options: std.fmt.FormatOptions, | |
| 293 | writer: anytype, | |
| 294 | ) !void { | |
| 289 | pub fn format(symbol: Symbol, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 295 | 290 | _ = symbol; |
| 291 | _ = bw; | |
| 296 | 292 | _ = unused_fmt_string; |
| 297 | _ = options; | |
| 298 | _ = writer; | |
| 299 | 293 | @compileError("do not format symbols directly"); |
| 300 | 294 | } |
| 301 | 295 | |
| ... | ... | @@ -311,26 +305,20 @@ pub fn fmt(symbol: Symbol, macho_file: *MachO) std.fmt.Formatter(format2) { |
| 311 | 305 | } }; |
| 312 | 306 | } |
| 313 | 307 | |
| 314 | fn format2( | |
| 315 | ctx: FormatContext, | |
| 316 | comptime unused_fmt_string: []const u8, | |
| 317 | options: std.fmt.FormatOptions, | |
| 318 | writer: anytype, | |
| 319 | ) !void { | |
| 320 | _ = options; | |
| 308 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 321 | 309 | _ = unused_fmt_string; |
| 322 | 310 | const symbol = ctx.symbol; |
| 323 | try writer.print("%{d} : {s} : @{x}", .{ | |
| 311 | try bw.print("%{d} : {s} : @{x}", .{ | |
| 324 | 312 | symbol.nlist_idx, |
| 325 | 313 | symbol.getName(ctx.macho_file), |
| 326 | 314 | symbol.getAddress(.{}, ctx.macho_file), |
| 327 | 315 | }); |
| 328 | 316 | if (symbol.getFile(ctx.macho_file)) |file| { |
| 329 | 317 | 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)}); | |
| 331 | 319 | } |
| 332 | 320 | 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}); | |
| 334 | 322 | } |
| 335 | 323 | var buf: [3]u8 = .{'_'} ** 3; |
| 336 | 324 | if (symbol.flags.@"export") buf[0] = 'E'; |
| ... | ... | @@ -340,16 +328,16 @@ fn format2( |
| 340 | 328 | .hidden => buf[2] = 'H', |
| 341 | 329 | .global => buf[2] = 'G', |
| 342 | 330 | } |
| 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"); | |
| 346 | 334 | 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}), | |
| 351 | 339 | } |
| 352 | } else try writer.writeAll(" : unresolved"); | |
| 340 | } else try bw.writeAll(" : unresolved"); | |
| 353 | 341 | } |
| 354 | 342 | |
| 355 | 343 | pub 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 { |
| 20 | 20 | return thunk.getAddress(macho_file) + thunk.symbols.getIndex(ref).? * trampoline_size; |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void { | |
| 23 | pub fn write(thunk: Thunk, macho_file: *MachO, bw: *std.io.BufferedWriter) !void { | |
| 24 | 24 | for (thunk.symbols.keys(), 0..) |ref, i| { |
| 25 | 25 | const sym = ref.getSymbol(macho_file).?; |
| 26 | 26 | const saddr = thunk.getAddress(macho_file) + i * trampoline_size; |
| 27 | 27 | const taddr = sym.getAddress(.{}, macho_file); |
| 28 | 28 | 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); | |
| 30 | 30 | 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); | |
| 33 | 33 | } |
| 34 | 34 | } |
| 35 | 35 | |
| ... | ... | @@ -61,16 +61,10 @@ pub fn writeSymtab(thunk: Thunk, macho_file: *MachO, ctx: anytype) void { |
| 61 | 61 | } |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | pub fn format( | |
| 65 | thunk: Thunk, | |
| 66 | comptime unused_fmt_string: []const u8, | |
| 67 | options: std.fmt.FormatOptions, | |
| 68 | writer: anytype, | |
| 69 | ) !void { | |
| 64 | pub fn format(thunk: Thunk, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 70 | 65 | _ = thunk; |
| 66 | _ = bw; | |
| 71 | 67 | _ = unused_fmt_string; |
| 72 | _ = options; | |
| 73 | _ = writer; | |
| 74 | 68 | @compileError("do not format Thunk directly"); |
| 75 | 69 | } |
| 76 | 70 | |
| ... | ... | @@ -86,20 +80,14 @@ const FormatContext = struct { |
| 86 | 80 | macho_file: *MachO, |
| 87 | 81 | }; |
| 88 | 82 | |
| 89 | fn format2( | |
| 90 | ctx: FormatContext, | |
| 91 | comptime unused_fmt_string: []const u8, | |
| 92 | options: std.fmt.FormatOptions, | |
| 93 | writer: anytype, | |
| 94 | ) !void { | |
| 95 | _ = options; | |
| 83 | fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 96 | 84 | _ = unused_fmt_string; |
| 97 | 85 | const thunk = ctx.thunk; |
| 98 | 86 | 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() }); | |
| 100 | 88 | for (thunk.symbols.keys()) |ref| { |
| 101 | 89 | 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 }); | |
| 103 | 91 | } |
| 104 | 92 | } |
| 105 | 93 |
src/link/MachO/UnwindInfo.zig+32-68| ... | ... | @@ -133,7 +133,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 133 | 133 | for (info.records.items) |ref| { |
| 134 | 134 | const rec = ref.getUnwindRecord(macho_file); |
| 135 | 135 | 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}", .{ | |
| 137 | 137 | rec.getAtomAddress(macho_file), |
| 138 | 138 | rec.getAtomAddress(macho_file) + rec.length, |
| 139 | 139 | atom.getName(macho_file), |
| ... | ... | @@ -202,7 +202,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 202 | 202 | if (i >= max_common_encodings) break; |
| 203 | 203 | if (slice[i].count < 2) continue; |
| 204 | 204 | 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 }); | |
| 206 | 206 | } |
| 207 | 207 | } |
| 208 | 208 | |
| ... | ... | @@ -255,7 +255,7 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { |
| 255 | 255 | page.kind = .compressed; |
| 256 | 256 | } |
| 257 | 257 | |
| 258 | log.debug("{}", .{page.fmt(info.*)}); | |
| 258 | log.debug("{f}", .{page.fmt(info.*)}); | |
| 259 | 259 | |
| 260 | 260 | try info.pages.append(gpa, page); |
| 261 | 261 | } |
| ... | ... | @@ -289,13 +289,10 @@ pub fn calcSize(info: UnwindInfo) usize { |
| 289 | 289 | return total_size; |
| 290 | 290 | } |
| 291 | 291 | |
| 292 | pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { | |
| 292 | pub fn write(info: UnwindInfo, macho_file: *MachO, bw: *std.io.BufferedWriter) anyerror!void { | |
| 293 | 293 | const seg = macho_file.getTextSegment(); |
| 294 | 294 | const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?]; |
| 295 | 295 | |
| 296 | var stream = std.io.fixedBufferStream(buffer); | |
| 297 | const writer = stream.writer(); | |
| 298 | ||
| 299 | 296 | const common_encodings_offset: u32 = @sizeOf(macho.unwind_info_section_header); |
| 300 | 297 | const common_encodings_count: u32 = info.common_encodings_count; |
| 301 | 298 | 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 { |
| 303 | 300 | const indexes_offset: u32 = personalities_offset + personalities_count * @sizeOf(u32); |
| 304 | 301 | const indexes_count: u32 = @as(u32, @intCast(info.pages.items.len + 1)); |
| 305 | 302 | |
| 306 | try writer.writeStruct(macho.unwind_info_section_header{ | |
| 303 | try bw.writeStruct(macho.unwind_info_section_header{ | |
| 307 | 304 | .commonEncodingsArraySectionOffset = common_encodings_offset, |
| 308 | 305 | .commonEncodingsArrayCount = common_encodings_count, |
| 309 | 306 | .personalityArraySectionOffset = personalities_offset, |
| ... | ... | @@ -312,11 +309,11 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 312 | 309 | .indexCount = indexes_count, |
| 313 | 310 | }); |
| 314 | 311 | |
| 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])); | |
| 316 | 313 | |
| 317 | 314 | for (info.personalities[0..info.personalities_count]) |ref| { |
| 318 | 315 | 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); | |
| 320 | 317 | } |
| 321 | 318 | |
| 322 | 319 | 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 { |
| 325 | 322 | for (info.pages.items, 0..) |page, i| { |
| 326 | 323 | assert(page.count > 0); |
| 327 | 324 | 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{ | |
| 329 | 326 | .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), |
| 330 | 327 | .secondLevelPagesSectionOffset = @as(u32, @intCast(pages_base_offset + i * second_level_page_bytes)), |
| 331 | 328 | .lsdaIndexArraySectionOffset = lsda_base_offset + |
| ... | ... | @@ -335,7 +332,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 335 | 332 | |
| 336 | 333 | const last_rec = info.records.items[info.records.items.len - 1].getUnwindRecord(macho_file); |
| 337 | 334 | 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{ | |
| 339 | 336 | .functionOffset = sentinel_address, |
| 340 | 337 | .secondLevelPagesSectionOffset = 0, |
| 341 | 338 | .lsdaIndexArraySectionOffset = lsda_base_offset + |
| ... | ... | @@ -344,23 +341,20 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 344 | 341 | |
| 345 | 342 | for (info.lsdas.items) |index| { |
| 346 | 343 | 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{ | |
| 348 | 345 | .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), |
| 349 | 346 | .lsdaOffset = @as(u32, @intCast(rec.getLsdaAddress(macho_file) - seg.vmaddr)), |
| 350 | 347 | }); |
| 351 | 348 | } |
| 352 | 349 | |
| 353 | 350 | 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); | |
| 361 | 355 | } |
| 362 | 356 | |
| 363 | @memset(buffer[stream.pos..], 0); | |
| 357 | @memset(bw.unusedCapacitySlice(), 0); | |
| 364 | 358 | } |
| 365 | 359 | |
| 366 | 360 | fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 { |
| ... | ... | @@ -455,15 +449,9 @@ pub const Encoding = extern struct { |
| 455 | 449 | return enc.enc == other.enc; |
| 456 | 450 | } |
| 457 | 451 | |
| 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 { | |
| 464 | 453 | _ = 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}); | |
| 467 | 455 | } |
| 468 | 456 | }; |
| 469 | 457 | |
| ... | ... | @@ -517,16 +505,10 @@ pub const Record = struct { |
| 517 | 505 | return lsda.getAddress(macho_file) + rec.lsda_offset; |
| 518 | 506 | } |
| 519 | 507 | |
| 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 { | |
| 526 | 509 | _ = rec; |
| 510 | _ = bw; | |
| 527 | 511 | _ = unused_fmt_string; |
| 528 | _ = options; | |
| 529 | _ = writer; | |
| 530 | 512 | @compileError("do not format UnwindInfo.Records directly"); |
| 531 | 513 | } |
| 532 | 514 | |
| ... | ... | @@ -542,22 +524,16 @@ pub const Record = struct { |
| 542 | 524 | macho_file: *MachO, |
| 543 | 525 | }; |
| 544 | 526 | |
| 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 { | |
| 551 | 528 | _ = unused_fmt_string; |
| 552 | _ = options; | |
| 553 | 529 | const rec = ctx.rec; |
| 554 | 530 | const macho_file = ctx.macho_file; |
| 555 | try writer.print("{x} : len({x})", .{ | |
| 531 | try bw.print("{x} : len({x})", .{ | |
| 556 | 532 | rec.enc.enc, rec.length, |
| 557 | 533 | }); |
| 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(" : [*]"); | |
| 561 | 537 | } |
| 562 | 538 | |
| 563 | 539 | pub const Index = u32; |
| ... | ... | @@ -613,16 +589,10 @@ const Page = struct { |
| 613 | 589 | return null; |
| 614 | 590 | } |
| 615 | 591 | |
| 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 { | |
| 622 | 593 | _ = page; |
| 594 | _ = bw; | |
| 623 | 595 | _ = unused_format_string; |
| 624 | _ = options; | |
| 625 | _ = writer; | |
| 626 | 596 | @compileError("do not format Page directly; use page.fmt()"); |
| 627 | 597 | } |
| 628 | 598 | |
| ... | ... | @@ -631,23 +601,17 @@ const Page = struct { |
| 631 | 601 | info: UnwindInfo, |
| 632 | 602 | }; |
| 633 | 603 | |
| 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 { | |
| 641 | 605 | _ = 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", .{ | |
| 645 | 609 | ctx.page.start, |
| 646 | 610 | ctx.page.start + ctx.page.count, |
| 647 | 611 | }); |
| 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}); | |
| 649 | 613 | 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 }); | |
| 651 | 615 | } |
| 652 | 616 | } |
| 653 | 617 |
src/link/MachO/ZigObject.zig+16-30| ... | ... | @@ -317,12 +317,12 @@ pub fn updateArSize(self: *ZigObject) void { |
| 317 | 317 | self.output_ar_state.size = self.data.items.len; |
| 318 | 318 | } |
| 319 | 319 | |
| 320 | pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !void { | |
| 320 | pub fn writeAr(self: ZigObject, bw: *std.io.BufferedWriter, ar_format: Archive.Format) anyerror!void { | |
| 321 | 321 | // Header |
| 322 | 322 | 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); | |
| 324 | 324 | // Data |
| 325 | try writer.writeAll(self.data.items); | |
| 325 | try bw.writeAll(self.data.items); | |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | 328 | pub fn claimUnresolved(self: *ZigObject, macho_file: *MachO) void { |
| ... | ... | @@ -618,7 +618,7 @@ pub fn getNavVAddr( |
| 618 | 618 | const zcu = pt.zcu; |
| 619 | 619 | const ip = &zcu.intern_pool; |
| 620 | 620 | 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 }); | |
| 622 | 622 | const sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol( |
| 623 | 623 | macho_file, |
| 624 | 624 | nav.name.toSlice(ip), |
| ... | ... | @@ -884,7 +884,6 @@ pub fn updateNav( |
| 884 | 884 | defer debug_wip_nav.deinit(); |
| 885 | 885 | dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { |
| 886 | 886 | error.OutOfMemory => return error.OutOfMemory, |
| 887 | error.Overflow => return error.Overflow, | |
| 888 | 887 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 889 | 888 | }; |
| 890 | 889 | } |
| ... | ... | @@ -921,7 +920,6 @@ pub fn updateNav( |
| 921 | 920 | |
| 922 | 921 | if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) { |
| 923 | 922 | error.OutOfMemory => return error.OutOfMemory, |
| 924 | error.Overflow => return error.Overflow, | |
| 925 | 923 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 926 | 924 | }; |
| 927 | 925 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); |
| ... | ... | @@ -943,7 +941,7 @@ fn updateNavCode( |
| 943 | 941 | const ip = &zcu.intern_pool; |
| 944 | 942 | const nav = ip.getNav(nav_index); |
| 945 | 943 | |
| 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 }); | |
| 947 | 945 | |
| 948 | 946 | const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 949 | 947 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| ... | ... | @@ -981,7 +979,7 @@ fn updateNavCode( |
| 981 | 979 | if (need_realloc) { |
| 982 | 980 | atom.grow(macho_file) catch |err| |
| 983 | 981 | 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 }); | |
| 985 | 983 | if (old_vaddr != atom.value) { |
| 986 | 984 | sym.value = 0; |
| 987 | 985 | nlist.n_value = 0; |
| ... | ... | @@ -1023,7 +1021,7 @@ fn updateTlv( |
| 1023 | 1021 | const ip = &pt.zcu.intern_pool; |
| 1024 | 1022 | const nav = ip.getNav(nav_index); |
| 1025 | 1023 | |
| 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 }); | |
| 1027 | 1025 | |
| 1028 | 1026 | // 1. Lower TLV initializer |
| 1029 | 1027 | const init_sym_index = try self.createTlvInitializer( |
| ... | ... | @@ -1351,7 +1349,7 @@ fn updateLazySymbol( |
| 1351 | 1349 | defer code_buffer.deinit(gpa); |
| 1352 | 1350 | |
| 1353 | 1351 | 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}", .{ | |
| 1355 | 1353 | @tagName(lazy_sym.kind), |
| 1356 | 1354 | Type.fromInterned(lazy_sym.ty).fmt(pt), |
| 1357 | 1355 | }); |
| ... | ... | @@ -1430,7 +1428,7 @@ pub fn deleteExport( |
| 1430 | 1428 | } orelse return; |
| 1431 | 1429 | const nlist_index = metadata.@"export"(self, name.toSlice(&zcu.intern_pool)) orelse return; |
| 1432 | 1430 | |
| 1433 | log.debug("deleting export '{}'", .{name.fmt(&zcu.intern_pool)}); | |
| 1431 | log.debug("deleting export '{f}'", .{name.fmt(&zcu.intern_pool)}); | |
| 1434 | 1432 | |
| 1435 | 1433 | const nlist = &self.symtab.items(.nlist)[nlist_index.*]; |
| 1436 | 1434 | self.symtab.items(.size)[nlist_index.*] = 0; |
| ... | ... | @@ -1690,24 +1688,18 @@ const FormatContext = struct { |
| 1690 | 1688 | macho_file: *MachO, |
| 1691 | 1689 | }; |
| 1692 | 1690 | |
| 1693 | fn formatSymtab( | |
| 1694 | ctx: FormatContext, | |
| 1695 | comptime unused_fmt_string: []const u8, | |
| 1696 | options: std.fmt.FormatOptions, | |
| 1697 | writer: anytype, | |
| 1698 | ) !void { | |
| 1691 | fn formatSymtab(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1699 | 1692 | _ = unused_fmt_string; |
| 1700 | _ = options; | |
| 1701 | try writer.writeAll(" symbols\n"); | |
| 1693 | try bw.writeAll(" symbols\n"); | |
| 1702 | 1694 | const self = ctx.self; |
| 1703 | 1695 | const macho_file = ctx.macho_file; |
| 1704 | 1696 | for (self.symbols.items, 0..) |sym, i| { |
| 1705 | 1697 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 1706 | 1698 | if (ref.getFile(macho_file) == null) { |
| 1707 | 1699 | // 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)}); | |
| 1709 | 1701 | } 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)}); | |
| 1711 | 1703 | } |
| 1712 | 1704 | } |
| 1713 | 1705 | } |
| ... | ... | @@ -1719,20 +1711,14 @@ pub fn fmtAtoms(self: *ZigObject, macho_file: *MachO) std.fmt.Formatter(formatAt |
| 1719 | 1711 | } }; |
| 1720 | 1712 | } |
| 1721 | 1713 | |
| 1722 | fn formatAtoms( | |
| 1723 | ctx: FormatContext, | |
| 1724 | comptime unused_fmt_string: []const u8, | |
| 1725 | options: std.fmt.FormatOptions, | |
| 1726 | writer: anytype, | |
| 1727 | ) !void { | |
| 1714 | fn formatAtoms(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) anyerror!void { | |
| 1728 | 1715 | _ = unused_fmt_string; |
| 1729 | _ = options; | |
| 1730 | 1716 | const self = ctx.self; |
| 1731 | 1717 | const macho_file = ctx.macho_file; |
| 1732 | try writer.writeAll(" atoms\n"); | |
| 1718 | try bw.writeAll(" atoms\n"); | |
| 1733 | 1719 | for (self.getAtoms()) |atom_index| { |
| 1734 | 1720 | 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)}); | |
| 1736 | 1722 | } |
| 1737 | 1723 | } |
| 1738 | 1724 |
src/link/MachO/dead_strip.zig+3-9| ... | ... | @@ -117,7 +117,7 @@ fn mark(roots: []*Atom, objects: []const File.Index, macho_file: *MachO) void { |
| 117 | 117 | fn markLive(atom: *Atom, macho_file: *MachO) void { |
| 118 | 118 | assert(atom.visited.load(.seq_cst)); |
| 119 | 119 | atom.setAlive(true); |
| 120 | track_live_log.debug("{}marking live atom({d},{s})", .{ | |
| 120 | track_live_log.debug("{f}marking live atom({d},{s})", .{ | |
| 121 | 121 | track_live_level, |
| 122 | 122 | atom.atom_index, |
| 123 | 123 | atom.getName(macho_file), |
| ... | ... | @@ -196,15 +196,9 @@ const Level = struct { |
| 196 | 196 | self.value += 1; |
| 197 | 197 | } |
| 198 | 198 | |
| 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 { | |
| 205 | 200 | _ = unused_fmt_string; |
| 206 | _ = options; | |
| 207 | try writer.writeByteNTimes(' ', self.value); | |
| 201 | try bw.splatByteAll(' ', self.value); | |
| 208 | 202 | } |
| 209 | 203 | }; |
| 210 | 204 |
src/link/MachO/dyld_info/Rebase.zig+45-45| ... | ... | @@ -3,7 +3,7 @@ buffer: std.ArrayListUnmanaged(u8) = .empty, |
| 3 | 3 | |
| 4 | 4 | pub const Entry = struct { |
| 5 | 5 | offset: u64, |
| 6 | segment_id: u8, | |
| 6 | segment_id: u4, | |
| 7 | 7 | |
| 8 | 8 | pub fn lessThan(ctx: void, entry: Entry, other: Entry) bool { |
| 9 | 9 | _ = ctx; |
| ... | ... | @@ -110,33 +110,35 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void { |
| 110 | 110 | fn finalize(rebase: *Rebase, gpa: Allocator) !void { |
| 111 | 111 | if (rebase.entries.items.len == 0) return; |
| 112 | 112 | |
| 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(); | |
| 114 | 116 | |
| 115 | 117 | log.debug("rebase opcodes", .{}); |
| 116 | 118 | |
| 117 | 119 | std.mem.sort(Entry, rebase.entries.items, {}, Entry.lessThan); |
| 118 | 120 | |
| 119 | try setTypePointer(writer); | |
| 121 | try setTypePointer(bw); | |
| 120 | 122 | |
| 121 | 123 | var start: usize = 0; |
| 122 | 124 | var seg_id: ?u8 = null; |
| 123 | 125 | for (rebase.entries.items, 0..) |entry, i| { |
| 124 | 126 | 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); | |
| 126 | 128 | seg_id = entry.segment_id; |
| 127 | 129 | start = i; |
| 128 | 130 | } |
| 129 | 131 | |
| 130 | try finalizeSegment(rebase.entries.items[start..], writer); | |
| 131 | try done(writer); | |
| 132 | try finalizeSegment(rebase.entries.items[start..], bw); | |
| 133 | try done(bw); | |
| 132 | 134 | } |
| 133 | 135 | |
| 134 | fn finalizeSegment(entries: []const Entry, writer: anytype) !void { | |
| 136 | fn finalizeSegment(entries: []const Entry, bw: *std.io.BufferedWriter) anyerror!void { | |
| 135 | 137 | if (entries.len == 0) return; |
| 136 | 138 | |
| 137 | 139 | const segment_id = entries[0].segment_id; |
| 138 | 140 | var offset = entries[0].offset; |
| 139 | try setSegmentOffset(segment_id, offset, writer); | |
| 141 | try setSegmentOffset(segment_id, offset, bw); | |
| 140 | 142 | |
| 141 | 143 | var count: usize = 0; |
| 142 | 144 | var skip: u64 = 0; |
| ... | ... | @@ -155,7 +157,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { |
| 155 | 157 | .start => { |
| 156 | 158 | if (offset < current_offset) { |
| 157 | 159 | const delta = current_offset - offset; |
| 158 | try addAddr(delta, writer); | |
| 160 | try addAddr(delta, bw); | |
| 159 | 161 | offset += delta; |
| 160 | 162 | } |
| 161 | 163 | state = .times; |
| ... | ... | @@ -175,7 +177,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { |
| 175 | 177 | offset += skip; |
| 176 | 178 | i -= 1; |
| 177 | 179 | } else { |
| 178 | try rebaseTimes(count, writer); | |
| 180 | try rebaseTimes(count, bw); | |
| 179 | 181 | state = .start; |
| 180 | 182 | i -= 1; |
| 181 | 183 | } |
| ... | ... | @@ -184,9 +186,9 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { |
| 184 | 186 | if (current_offset < offset) { |
| 185 | 187 | count -= 1; |
| 186 | 188 | if (count == 1) { |
| 187 | try rebaseAddAddr(skip, writer); | |
| 189 | try rebaseAddAddr(skip, bw); | |
| 188 | 190 | } else { |
| 189 | try rebaseTimesSkip(count, skip, writer); | |
| 191 | try rebaseTimesSkip(count, skip, bw); | |
| 190 | 192 | } |
| 191 | 193 | state = .start; |
| 192 | 194 | offset = offset - (@sizeOf(u64) + skip); |
| ... | ... | @@ -199,7 +201,7 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { |
| 199 | 201 | count += 1; |
| 200 | 202 | offset += @sizeOf(u64) + skip; |
| 201 | 203 | } else { |
| 202 | try rebaseTimesSkip(count, skip, writer); | |
| 204 | try rebaseTimesSkip(count, skip, bw); | |
| 203 | 205 | state = .start; |
| 204 | 206 | i -= 1; |
| 205 | 207 | } |
| ... | ... | @@ -210,68 +212,66 @@ fn finalizeSegment(entries: []const Entry, writer: anytype) !void { |
| 210 | 212 | switch (state) { |
| 211 | 213 | .start => unreachable, |
| 212 | 214 | .times => { |
| 213 | try rebaseTimes(count, writer); | |
| 215 | try rebaseTimes(count, bw); | |
| 214 | 216 | }, |
| 215 | 217 | .times_skip => { |
| 216 | try rebaseTimesSkip(count, skip, writer); | |
| 218 | try rebaseTimesSkip(count, skip, bw); | |
| 217 | 219 | }, |
| 218 | 220 | } |
| 219 | 221 | } |
| 220 | 222 | |
| 221 | fn setTypePointer(writer: anytype) !void { | |
| 223 | fn setTypePointer(bw: *std.io.BufferedWriter) anyerror!void { | |
| 222 | 224 | 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))); | |
| 224 | 226 | } |
| 225 | 227 | |
| 226 | fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void { | |
| 228 | fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 227 | 229 | 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); | |
| 230 | 232 | } |
| 231 | 233 | |
| 232 | fn rebaseAddAddr(addr: u64, writer: anytype) !void { | |
| 234 | fn rebaseAddAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 233 | 235 | 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); | |
| 236 | 238 | } |
| 237 | 239 | |
| 238 | fn rebaseTimes(count: usize, writer: anytype) !void { | |
| 240 | fn rebaseTimes(count: usize, bw: *std.io.BufferedWriter) anyerror!void { | |
| 239 | 241 | log.debug(">>> rebase with count: {d}", .{count}); |
| 240 | 242 | 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))); | |
| 242 | 244 | } 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); | |
| 245 | 247 | } |
| 246 | 248 | } |
| 247 | 249 | |
| 248 | fn rebaseTimesSkip(count: usize, skip: u64, writer: anytype) !void { | |
| 250 | fn rebaseTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 249 | 251 | 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); | |
| 253 | 255 | } |
| 254 | 256 | |
| 255 | fn addAddr(addr: u64, writer: anytype) !void { | |
| 257 | fn addAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 256 | 258 | 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); | |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | fn done(writer: anytype) !void { | |
| 268 | fn done(bw: *std.io.BufferedWriter) anyerror!void { | |
| 269 | 269 | log.debug(">>> done", .{}); |
| 270 | try writer.writeByte(macho.REBASE_OPCODE_DONE); | |
| 270 | try bw.writeByte(macho.REBASE_OPCODE_DONE); | |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | pub fn write(rebase: Rebase, writer: anytype) !void { | |
| 274 | try writer.writeAll(rebase.buffer.items); | |
| 273 | pub fn write(rebase: Rebase, bw: *std.io.BufferedWriter) anyerror!void { | |
| 274 | try bw.writeAll(rebase.buffer.items); | |
| 275 | 275 | } |
| 276 | 276 | |
| 277 | 277 | test "rebase - no entries" { |
src/link/MachO/dyld_info/Trie.zig+32-35| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | |
| 32 | 32 | /// The root node of the trie. |
| 33 | 33 | root: ?Node.Index = null, |
| 34 | buffer: std.ArrayListUnmanaged(u8) = .empty, | |
| 34 | buffer: []u8 = &.{}, | |
| 35 | 35 | nodes: std.MultiArrayList(Node) = .{}, |
| 36 | 36 | edges: std.ArrayListUnmanaged(Edge) = .empty, |
| 37 | 37 | |
| ... | ... | @@ -123,7 +123,7 @@ pub fn updateSize(self: *Trie, macho_file: *MachO) !void { |
| 123 | 123 | |
| 124 | 124 | try self.finalize(gpa); |
| 125 | 125 | |
| 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)); | |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 129 | /// Finalizes this trie for writing to a byte stream. |
| ... | ... | @@ -164,9 +164,12 @@ fn finalize(self: *Trie, allocator: Allocator) !void { |
| 164 | 164 | } |
| 165 | 165 | } |
| 166 | 166 | |
| 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); | |
| 168 | 171 | for (ordered_nodes.items) |node_index| { |
| 169 | try self.writeNode(node_index, self.buffer.writer(allocator)); | |
| 172 | try self.writeNode(node_index, &bw); | |
| 170 | 173 | } |
| 171 | 174 | } |
| 172 | 175 | |
| ... | ... | @@ -181,17 +184,20 @@ const FinalizeNodeResult = struct { |
| 181 | 184 | |
| 182 | 185 | /// Updates offset of this node in the output byte stream. |
| 183 | 186 | fn 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 | }; | |
| 186 | 192 | const slice = self.nodes.slice(); |
| 187 | 193 | |
| 188 | 194 | var node_size: u32 = 0; |
| 189 | 195 | if (slice.items(.is_terminal)[node_index]) { |
| 190 | 196 | const export_flags = slice.items(.export_flags)[node_index]; |
| 191 | 197 | 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); | |
| 195 | 201 | } else { |
| 196 | 202 | node_size += 1; // 0x0 for non-terminal nodes |
| 197 | 203 | } |
| ... | ... | @@ -201,13 +207,13 @@ fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !Final |
| 201 | 207 | const edge = &self.edges.items[edge_index]; |
| 202 | 208 | const next_node_offset = slice.items(.trie_offset)[edge.node]; |
| 203 | 209 | node_size += @intCast(edge.label.len + 1); |
| 204 | try leb.writeULEB128(writer, next_node_offset); | |
| 210 | try bw.writeLeb128(next_node_offset); | |
| 205 | 211 | } |
| 206 | 212 | |
| 207 | 213 | const trie_offset = slice.items(.trie_offset)[node_index]; |
| 208 | 214 | const updated = offset_in_trie != trie_offset; |
| 209 | 215 | slice.items(.trie_offset)[node_index] = offset_in_trie; |
| 210 | node_size += @intCast(stream.bytes_written); | |
| 216 | node_size += @intCast(bw.count); | |
| 211 | 217 | |
| 212 | 218 | return .{ .node_size = node_size, .updated = updated }; |
| 213 | 219 | } |
| ... | ... | @@ -223,12 +229,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void { |
| 223 | 229 | } |
| 224 | 230 | self.nodes.deinit(allocator); |
| 225 | 231 | self.edges.deinit(allocator); |
| 226 | self.buffer.deinit(allocator); | |
| 232 | allocator.free(self.buffer); | |
| 227 | 233 | } |
| 228 | 234 | |
| 229 | pub fn write(self: Trie, writer: anytype) !void { | |
| 230 | if (self.buffer.items.len == 0) return; | |
| 231 | try writer.writeAll(self.buffer.items); | |
| 235 | pub fn write(self: Trie, bw: *std.io.BufferedWriter) anyerror!void { | |
| 236 | try bw.writeAll(self.buffer); | |
| 232 | 237 | } |
| 233 | 238 | |
| 234 | 239 | /// Writes this node to a byte stream. |
| ... | ... | @@ -237,7 +242,7 @@ pub fn write(self: Trie, writer: anytype) !void { |
| 237 | 242 | /// iterate over `Trie.ordered_nodes` and call this method on each node. |
| 238 | 243 | /// This is one of the requirements of the MachO. |
| 239 | 244 | /// Panics if `finalize` was not called before calling this method. |
| 240 | fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void { | |
| 245 | fn writeNode(self: *Trie, node_index: Node.Index, bw: *std.io.BufferedWriter) !void { | |
| 241 | 246 | const slice = self.nodes.slice(); |
| 242 | 247 | const edges = slice.items(.edges)[node_index]; |
| 243 | 248 | const is_terminal = slice.items(.is_terminal)[node_index]; |
| ... | ... | @@ -245,36 +250,28 @@ fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void { |
| 245 | 250 | const vmaddr_offset = slice.items(.vmaddr_offset)[node_index]; |
| 246 | 251 | |
| 247 | 252 | 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; | |
| 251 | 254 | // TODO Implement for special flags. |
| 252 | 255 | assert(export_flags & macho.EXPORT_SYMBOL_FLAGS_REEXPORT == 0 and |
| 253 | 256 | 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); | |
| 257 | 260 | // 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); | |
| 265 | 262 | } else { |
| 266 | 263 | // Non-terminal node is delimited by 0 byte. |
| 267 | try writer.writeByte(0); | |
| 264 | try bw.writeByte(0); | |
| 268 | 265 | } |
| 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)); | |
| 271 | 268 | |
| 272 | 269 | for (edges.items) |edge_index| { |
| 273 | 270 | const edge = self.edges.items[edge_index]; |
| 274 | 271 | // 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]); | |
| 278 | 275 | } |
| 279 | 276 | } |
| 280 | 277 |
src/link/MachO/dyld_info/bind.zig+151-184| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | pub const Entry = struct { |
| 2 | 2 | target: MachO.Ref, |
| 3 | 3 | offset: u64, |
| 4 | segment_id: u8, | |
| 4 | segment_id: u4, | |
| 5 | 5 | addend: i64, |
| 6 | 6 | |
| 7 | 7 | pub fn lessThan(ctx: *MachO, entry: Entry, other: Entry) bool { |
| ... | ... | @@ -20,14 +20,12 @@ pub const Bind = struct { |
| 20 | 20 | entries: std.ArrayListUnmanaged(Entry) = .empty, |
| 21 | 21 | buffer: std.ArrayListUnmanaged(u8) = .empty, |
| 22 | 22 | |
| 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); | |
| 28 | 26 | } |
| 29 | 27 | |
| 30 | pub fn updateSize(self: *Self, macho_file: *MachO) !void { | |
| 28 | pub fn updateSize(bind: *Bind, macho_file: *MachO) !void { | |
| 31 | 29 | const tracy = trace(@src()); |
| 32 | 30 | defer tracy.end(); |
| 33 | 31 | |
| ... | ... | @@ -56,15 +54,12 @@ pub const Bind = struct { |
| 56 | 54 | const addend = rel.addend + rel.getRelocAddend(cpu_arch); |
| 57 | 55 | const sym = rel.getTargetSymbol(atom.*, macho_file); |
| 58 | 56 | 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)).* = .{ | |
| 60 | 58 | .target = rel.getTargetSymbolRef(atom.*, macho_file), |
| 61 | 59 | .offset = atom_addr + rel_offset - seg.vmaddr, |
| 62 | 60 | .segment_id = seg_id, |
| 63 | 61 | .addend = addend, |
| 64 | 62 | }; |
| 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 | } | |
| 68 | 63 | } |
| 69 | 64 | } |
| 70 | 65 | } |
| ... | ... | @@ -75,15 +70,12 @@ pub const Bind = struct { |
| 75 | 70 | for (macho_file.got.symbols.items, 0..) |ref, idx| { |
| 76 | 71 | const sym = ref.getSymbol(macho_file).?; |
| 77 | 72 | 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)).* = .{ | |
| 79 | 74 | .target = ref, |
| 80 | 75 | .offset = addr - seg.vmaddr, |
| 81 | 76 | .segment_id = seg_id, |
| 82 | 77 | .addend = 0, |
| 83 | 78 | }; |
| 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 | } | |
| 87 | 79 | } |
| 88 | 80 | } |
| 89 | 81 | |
| ... | ... | @@ -94,15 +86,12 @@ pub const Bind = struct { |
| 94 | 86 | for (macho_file.stubs.symbols.items, 0..) |ref, idx| { |
| 95 | 87 | const sym = ref.getSymbol(macho_file).?; |
| 96 | 88 | 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)).* = .{ | |
| 98 | 90 | .target = ref, |
| 99 | 91 | .offset = addr - seg.vmaddr, |
| 100 | 92 | .segment_id = seg_id, |
| 101 | 93 | .addend = 0, |
| 102 | 94 | }; |
| 103 | if (sym.flags.import and sym.flags.weak) { | |
| 104 | try self.entries.append(gpa, bind_entry); | |
| 105 | } | |
| 106 | 95 | } |
| 107 | 96 | } |
| 108 | 97 | |
| ... | ... | @@ -113,49 +102,48 @@ pub const Bind = struct { |
| 113 | 102 | for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| { |
| 114 | 103 | const sym = ref.getSymbol(macho_file).?; |
| 115 | 104 | 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)).* = .{ | |
| 117 | 106 | .target = ref, |
| 118 | 107 | .offset = addr - seg.vmaddr, |
| 119 | 108 | .segment_id = seg_id, |
| 120 | 109 | .addend = 0, |
| 121 | 110 | }; |
| 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 | } | |
| 125 | 111 | } |
| 126 | 112 | } |
| 127 | 113 | |
| 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)); | |
| 130 | 116 | } |
| 131 | 117 | |
| 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; | |
| 134 | 120 | |
| 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(); | |
| 136 | 124 | |
| 137 | 125 | log.debug("bind opcodes", .{}); |
| 138 | 126 | |
| 139 | std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan); | |
| 127 | std.mem.sort(Entry, bind.entries.items, ctx, Entry.lessThan); | |
| 140 | 128 | |
| 141 | 129 | var start: usize = 0; |
| 142 | 130 | var seg_id: ?u8 = null; |
| 143 | for (self.entries.items, 0..) |entry, i| { | |
| 131 | for (bind.entries.items, 0..) |entry, i| { | |
| 144 | 132 | 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); | |
| 146 | 134 | seg_id = entry.segment_id; |
| 147 | 135 | start = i; |
| 148 | 136 | } |
| 149 | 137 | |
| 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); | |
| 152 | 140 | } |
| 153 | 141 | |
| 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 { | |
| 155 | 143 | if (entries.len == 0) return; |
| 156 | 144 | |
| 157 | 145 | const seg_id = entries[0].segment_id; |
| 158 | try setSegmentOffset(seg_id, 0, writer); | |
| 146 | try setSegmentOffset(seg_id, 0, bw); | |
| 159 | 147 | |
| 160 | 148 | var offset: u64 = 0; |
| 161 | 149 | var addend: i64 = 0; |
| ... | ... | @@ -175,15 +163,15 @@ pub const Bind = struct { |
| 175 | 163 | if (target == null or !target.?.eql(current.target)) { |
| 176 | 164 | switch (state) { |
| 177 | 165 | .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), | |
| 180 | 168 | } |
| 181 | 169 | state = .start; |
| 182 | 170 | target = current.target; |
| 183 | 171 | |
| 184 | 172 | const sym = current.target.getSymbol(ctx).?; |
| 185 | 173 | 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; | |
| 187 | 175 | const ordinal: i16 = ord: { |
| 188 | 176 | if (sym.flags.interposable) break :ord macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP; |
| 189 | 177 | if (sym.flags.import) { |
| ... | ... | @@ -195,13 +183,13 @@ pub const Bind = struct { |
| 195 | 183 | break :ord macho.BIND_SPECIAL_DYLIB_SELF; |
| 196 | 184 | }; |
| 197 | 185 | |
| 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); | |
| 201 | 189 | |
| 202 | 190 | if (current.addend != addend) { |
| 203 | 191 | addend = current.addend; |
| 204 | try setAddend(addend, writer); | |
| 192 | try setAddend(addend, bw); | |
| 205 | 193 | } |
| 206 | 194 | } |
| 207 | 195 | |
| ... | ... | @@ -210,11 +198,11 @@ pub const Bind = struct { |
| 210 | 198 | switch (state) { |
| 211 | 199 | .start => { |
| 212 | 200 | 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); | |
| 214 | 202 | offset = offset - (offset - current.offset); |
| 215 | 203 | } else if (current.offset > offset) { |
| 216 | 204 | const delta = current.offset - offset; |
| 217 | try addAddr(delta, writer); | |
| 205 | try addAddr(delta, bw); | |
| 218 | 206 | offset += delta; |
| 219 | 207 | } |
| 220 | 208 | state = .bind_single; |
| ... | ... | @@ -223,7 +211,7 @@ pub const Bind = struct { |
| 223 | 211 | }, |
| 224 | 212 | .bind_single => { |
| 225 | 213 | if (current.offset == offset) { |
| 226 | try doBind(writer); | |
| 214 | try doBind(bw); | |
| 227 | 215 | state = .start; |
| 228 | 216 | } else if (current.offset > offset) { |
| 229 | 217 | const delta = current.offset - offset; |
| ... | ... | @@ -237,9 +225,9 @@ pub const Bind = struct { |
| 237 | 225 | if (current.offset < offset) { |
| 238 | 226 | count -= 1; |
| 239 | 227 | if (count == 1) { |
| 240 | try doBindAddAddr(skip, writer); | |
| 228 | try doBindAddAddr(skip, bw); | |
| 241 | 229 | } else { |
| 242 | try doBindTimesSkip(count, skip, writer); | |
| 230 | try doBindTimesSkip(count, skip, bw); | |
| 243 | 231 | } |
| 244 | 232 | state = .start; |
| 245 | 233 | offset = offset - (@sizeOf(u64) + skip); |
| ... | ... | @@ -248,7 +236,7 @@ pub const Bind = struct { |
| 248 | 236 | count += 1; |
| 249 | 237 | offset += @sizeOf(u64) + skip; |
| 250 | 238 | } else { |
| 251 | try doBindTimesSkip(count, skip, writer); | |
| 239 | try doBindTimesSkip(count, skip, bw); | |
| 252 | 240 | state = .start; |
| 253 | 241 | i -= 1; |
| 254 | 242 | } |
| ... | ... | @@ -258,13 +246,13 @@ pub const Bind = struct { |
| 258 | 246 | |
| 259 | 247 | switch (state) { |
| 260 | 248 | .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), | |
| 263 | 251 | } |
| 264 | 252 | } |
| 265 | 253 | |
| 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); | |
| 268 | 256 | } |
| 269 | 257 | }; |
| 270 | 258 | |
| ... | ... | @@ -272,14 +260,12 @@ pub const WeakBind = struct { |
| 272 | 260 | entries: std.ArrayListUnmanaged(Entry) = .empty, |
| 273 | 261 | buffer: std.ArrayListUnmanaged(u8) = .empty, |
| 274 | 262 | |
| 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); | |
| 280 | 266 | } |
| 281 | 267 | |
| 282 | pub fn updateSize(self: *Self, macho_file: *MachO) !void { | |
| 268 | pub fn updateSize(bind: *WeakBind, macho_file: *MachO) !void { | |
| 283 | 269 | const tracy = trace(@src()); |
| 284 | 270 | defer tracy.end(); |
| 285 | 271 | |
| ... | ... | @@ -308,15 +294,12 @@ pub const WeakBind = struct { |
| 308 | 294 | const addend = rel.addend + rel.getRelocAddend(cpu_arch); |
| 309 | 295 | const sym = rel.getTargetSymbol(atom.*, macho_file); |
| 310 | 296 | if (sym.isTlvInit(macho_file)) continue; |
| 311 | const entry = Entry{ | |
| 297 | if (!sym.isLocal() and sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{ | |
| 312 | 298 | .target = rel.getTargetSymbolRef(atom.*, macho_file), |
| 313 | 299 | .offset = atom_addr + rel_offset - seg.vmaddr, |
| 314 | 300 | .segment_id = seg_id, |
| 315 | 301 | .addend = addend, |
| 316 | 302 | }; |
| 317 | if (!sym.isLocal() and sym.flags.weak) { | |
| 318 | try self.entries.append(gpa, entry); | |
| 319 | } | |
| 320 | 303 | } |
| 321 | 304 | } |
| 322 | 305 | } |
| ... | ... | @@ -327,15 +310,12 @@ pub const WeakBind = struct { |
| 327 | 310 | for (macho_file.got.symbols.items, 0..) |ref, idx| { |
| 328 | 311 | const sym = ref.getSymbol(macho_file).?; |
| 329 | 312 | const addr = macho_file.got.getAddress(@intCast(idx), macho_file); |
| 330 | const entry = Entry{ | |
| 313 | if (sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{ | |
| 331 | 314 | .target = ref, |
| 332 | 315 | .offset = addr - seg.vmaddr, |
| 333 | 316 | .segment_id = seg_id, |
| 334 | 317 | .addend = 0, |
| 335 | 318 | }; |
| 336 | if (sym.flags.weak) { | |
| 337 | try self.entries.append(gpa, entry); | |
| 338 | } | |
| 339 | 319 | } |
| 340 | 320 | } |
| 341 | 321 | |
| ... | ... | @@ -347,15 +327,12 @@ pub const WeakBind = struct { |
| 347 | 327 | for (macho_file.stubs.symbols.items, 0..) |ref, idx| { |
| 348 | 328 | const sym = ref.getSymbol(macho_file).?; |
| 349 | 329 | const addr = sect.addr + idx * @sizeOf(u64); |
| 350 | const bind_entry = Entry{ | |
| 330 | if (sym.flags.weak) (try bind.entries.addOne(gpa)).* = .{ | |
| 351 | 331 | .target = ref, |
| 352 | 332 | .offset = addr - seg.vmaddr, |
| 353 | 333 | .segment_id = seg_id, |
| 354 | 334 | .addend = 0, |
| 355 | 335 | }; |
| 356 | if (sym.flags.weak) { | |
| 357 | try self.entries.append(gpa, bind_entry); | |
| 358 | } | |
| 359 | 336 | } |
| 360 | 337 | } |
| 361 | 338 | |
| ... | ... | @@ -366,49 +343,48 @@ pub const WeakBind = struct { |
| 366 | 343 | for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| { |
| 367 | 344 | const sym = ref.getSymbol(macho_file).?; |
| 368 | 345 | 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)).* = .{ | |
| 370 | 347 | .target = ref, |
| 371 | 348 | .offset = addr - seg.vmaddr, |
| 372 | 349 | .segment_id = seg_id, |
| 373 | 350 | .addend = 0, |
| 374 | 351 | }; |
| 375 | if (sym.flags.weak) { | |
| 376 | try self.entries.append(gpa, entry); | |
| 377 | } | |
| 378 | 352 | } |
| 379 | 353 | } |
| 380 | 354 | |
| 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)); | |
| 383 | 357 | } |
| 384 | 358 | |
| 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; | |
| 387 | 361 | |
| 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(); | |
| 389 | 365 | |
| 390 | 366 | log.debug("weak bind opcodes", .{}); |
| 391 | 367 | |
| 392 | std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan); | |
| 368 | std.mem.sort(Entry, bind.entries.items, ctx, Entry.lessThan); | |
| 393 | 369 | |
| 394 | 370 | var start: usize = 0; |
| 395 | 371 | var seg_id: ?u8 = null; |
| 396 | for (self.entries.items, 0..) |entry, i| { | |
| 372 | for (bind.entries.items, 0..) |entry, i| { | |
| 397 | 373 | 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); | |
| 399 | 375 | seg_id = entry.segment_id; |
| 400 | 376 | start = i; |
| 401 | 377 | } |
| 402 | 378 | |
| 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); | |
| 405 | 381 | } |
| 406 | 382 | |
| 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 { | |
| 408 | 384 | if (entries.len == 0) return; |
| 409 | 385 | |
| 410 | 386 | const seg_id = entries[0].segment_id; |
| 411 | try setSegmentOffset(seg_id, 0, writer); | |
| 387 | try setSegmentOffset(seg_id, 0, bw); | |
| 412 | 388 | |
| 413 | 389 | var offset: u64 = 0; |
| 414 | 390 | var addend: i64 = 0; |
| ... | ... | @@ -428,8 +404,8 @@ pub const WeakBind = struct { |
| 428 | 404 | if (target == null or !target.?.eql(current.target)) { |
| 429 | 405 | switch (state) { |
| 430 | 406 | .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), | |
| 433 | 409 | } |
| 434 | 410 | state = .start; |
| 435 | 411 | target = current.target; |
| ... | ... | @@ -438,12 +414,12 @@ pub const WeakBind = struct { |
| 438 | 414 | const name = sym.getName(ctx); |
| 439 | 415 | const flags: u8 = 0; // TODO NON_WEAK_DEFINITION |
| 440 | 416 | |
| 441 | try setSymbol(name, flags, writer); | |
| 442 | try setTypePointer(writer); | |
| 417 | try setSymbol(name, flags, bw); | |
| 418 | try setTypePointer(bw); | |
| 443 | 419 | |
| 444 | 420 | if (current.addend != addend) { |
| 445 | 421 | addend = current.addend; |
| 446 | try setAddend(addend, writer); | |
| 422 | try setAddend(addend, bw); | |
| 447 | 423 | } |
| 448 | 424 | } |
| 449 | 425 | |
| ... | ... | @@ -452,11 +428,11 @@ pub const WeakBind = struct { |
| 452 | 428 | switch (state) { |
| 453 | 429 | .start => { |
| 454 | 430 | 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); | |
| 456 | 432 | offset = offset - (offset - current.offset); |
| 457 | 433 | } else if (current.offset > offset) { |
| 458 | 434 | const delta = current.offset - offset; |
| 459 | try addAddr(delta, writer); | |
| 435 | try addAddr(delta, bw); | |
| 460 | 436 | offset += delta; |
| 461 | 437 | } |
| 462 | 438 | state = .bind_single; |
| ... | ... | @@ -465,7 +441,7 @@ pub const WeakBind = struct { |
| 465 | 441 | }, |
| 466 | 442 | .bind_single => { |
| 467 | 443 | if (current.offset == offset) { |
| 468 | try doBind(writer); | |
| 444 | try doBind(bw); | |
| 469 | 445 | state = .start; |
| 470 | 446 | } else if (current.offset > offset) { |
| 471 | 447 | const delta = current.offset - offset; |
| ... | ... | @@ -479,9 +455,9 @@ pub const WeakBind = struct { |
| 479 | 455 | if (current.offset < offset) { |
| 480 | 456 | count -= 1; |
| 481 | 457 | if (count == 1) { |
| 482 | try doBindAddAddr(skip, writer); | |
| 458 | try doBindAddAddr(skip, bw); | |
| 483 | 459 | } else { |
| 484 | try doBindTimesSkip(count, skip, writer); | |
| 460 | try doBindTimesSkip(count, skip, bw); | |
| 485 | 461 | } |
| 486 | 462 | state = .start; |
| 487 | 463 | offset = offset - (@sizeOf(u64) + skip); |
| ... | ... | @@ -490,7 +466,7 @@ pub const WeakBind = struct { |
| 490 | 466 | count += 1; |
| 491 | 467 | offset += @sizeOf(u64) + skip; |
| 492 | 468 | } else { |
| 493 | try doBindTimesSkip(count, skip, writer); | |
| 469 | try doBindTimesSkip(count, skip, bw); | |
| 494 | 470 | state = .start; |
| 495 | 471 | i -= 1; |
| 496 | 472 | } |
| ... | ... | @@ -500,13 +476,13 @@ pub const WeakBind = struct { |
| 500 | 476 | |
| 501 | 477 | switch (state) { |
| 502 | 478 | .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), | |
| 505 | 481 | } |
| 506 | 482 | } |
| 507 | 483 | |
| 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); | |
| 510 | 486 | } |
| 511 | 487 | }; |
| 512 | 488 | |
| ... | ... | @@ -515,15 +491,13 @@ pub const LazyBind = struct { |
| 515 | 491 | buffer: std.ArrayListUnmanaged(u8) = .empty, |
| 516 | 492 | offsets: std.ArrayListUnmanaged(u32) = .empty, |
| 517 | 493 | |
| 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); | |
| 524 | 498 | } |
| 525 | 499 | |
| 526 | pub fn updateSize(self: *Self, macho_file: *MachO) !void { | |
| 500 | pub fn updateSize(bind: *LazyBind, macho_file: *MachO) !void { | |
| 527 | 501 | const tracy = trace(@src()); |
| 528 | 502 | defer tracy.end(); |
| 529 | 503 | |
| ... | ... | @@ -537,36 +511,35 @@ pub const LazyBind = struct { |
| 537 | 511 | for (macho_file.stubs.symbols.items, 0..) |ref, idx| { |
| 538 | 512 | const sym = ref.getSymbol(macho_file).?; |
| 539 | 513 | 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)).* = .{ | |
| 541 | 515 | .target = ref, |
| 542 | 516 | .offset = addr - seg.vmaddr, |
| 543 | 517 | .segment_id = seg_id, |
| 544 | 518 | .addend = 0, |
| 545 | 519 | }; |
| 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 | } | |
| 549 | 520 | } |
| 550 | 521 | |
| 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)); | |
| 553 | 524 | } |
| 554 | 525 | |
| 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); | |
| 557 | 528 | |
| 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(); | |
| 559 | 532 | |
| 560 | 533 | log.debug("lazy bind opcodes", .{}); |
| 561 | 534 | |
| 562 | 535 | var addend: i64 = 0; |
| 563 | 536 | |
| 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)); | |
| 566 | 539 | |
| 567 | 540 | const sym = entry.target.getSymbol(ctx).?; |
| 568 | 541 | 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; | |
| 570 | 543 | const ordinal: i16 = ord: { |
| 571 | 544 | if (sym.flags.interposable) break :ord macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP; |
| 572 | 545 | if (sym.flags.import) { |
| ... | ... | @@ -578,109 +551,103 @@ pub const LazyBind = struct { |
| 578 | 551 | break :ord macho.BIND_SPECIAL_DYLIB_SELF; |
| 579 | 552 | }; |
| 580 | 553 | |
| 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); | |
| 584 | 557 | |
| 585 | 558 | if (entry.addend != addend) { |
| 586 | try setAddend(entry.addend, writer); | |
| 559 | try setAddend(entry.addend, bw); | |
| 587 | 560 | addend = entry.addend; |
| 588 | 561 | } |
| 589 | 562 | |
| 590 | try doBind(writer); | |
| 591 | try done(writer); | |
| 563 | try doBind(bw); | |
| 564 | try done(bw); | |
| 592 | 565 | } |
| 593 | 566 | } |
| 594 | 567 | |
| 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); | |
| 597 | 570 | } |
| 598 | 571 | }; |
| 599 | 572 | |
| 600 | fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void { | |
| 573 | fn setSegmentOffset(segment_id: u4, offset: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 601 | 574 | 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); | |
| 604 | 577 | } |
| 605 | 578 | |
| 606 | fn setSymbol(name: []const u8, flags: u8, writer: anytype) !void { | |
| 579 | fn setSymbol(name: []const u8, flags: u4, bw: *std.io.BufferedWriter) anyerror!void { | |
| 607 | 580 | 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); | |
| 611 | 584 | } |
| 612 | 585 | |
| 613 | fn setTypePointer(writer: anytype) !void { | |
| 586 | fn setTypePointer(bw: *std.io.BufferedWriter) anyerror!void { | |
| 614 | 587 | 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))); | |
| 616 | 589 | } |
| 617 | 590 | |
| 618 | fn 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 | } | |
| 591 | fn 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 | }, | |
| 639 | 610 | } |
| 640 | 611 | } |
| 641 | 612 | |
| 642 | fn setAddend(addend: i64, writer: anytype) !void { | |
| 613 | fn setAddend(addend: i64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 643 | 614 | 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); | |
| 646 | 617 | } |
| 647 | 618 | |
| 648 | fn doBind(writer: anytype) !void { | |
| 619 | fn doBind(bw: *std.io.BufferedWriter) anyerror!void { | |
| 649 | 620 | log.debug(">>> bind", .{}); |
| 650 | try writer.writeByte(macho.BIND_OPCODE_DO_BIND); | |
| 621 | try bw.writeByte(macho.BIND_OPCODE_DO_BIND); | |
| 651 | 622 | } |
| 652 | 623 | |
| 653 | fn doBindAddAddr(addr: u64, writer: anytype) !void { | |
| 624 | fn doBindAddAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 654 | 625 | 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); | |
| 666 | 633 | } |
| 667 | 634 | |
| 668 | fn doBindTimesSkip(count: usize, skip: u64, writer: anytype) !void { | |
| 635 | fn doBindTimesSkip(count: usize, skip: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 669 | 636 | 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); | |
| 673 | 640 | } |
| 674 | 641 | |
| 675 | fn addAddr(addr: u64, writer: anytype) !void { | |
| 642 | fn addAddr(addr: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 676 | 643 | 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); | |
| 679 | 646 | } |
| 680 | 647 | |
| 681 | fn done(writer: anytype) !void { | |
| 648 | fn done(bw: *std.io.BufferedWriter) anyerror!void { | |
| 682 | 649 | log.debug(">>> done", .{}); |
| 683 | try writer.writeByte(macho.BIND_OPCODE_DONE); | |
| 650 | try bw.writeByte(macho.BIND_OPCODE_DONE); | |
| 684 | 651 | } |
| 685 | 652 | |
| 686 | 653 | const assert = std.debug.assert; |
src/link/MachO/eh_frame.zig+37-53| ... | ... | @@ -12,36 +12,34 @@ pub const Cie = struct { |
| 12 | 12 | const tracy = trace(@src()); |
| 13 | 13 | defer tracy.end(); |
| 14 | 14 | |
| 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)); | |
| 17 | 17 | |
| 18 | try br.discard(9); | |
| 19 | const aug = try br.takeSentinel(0); | |
| 18 | 20 | if (aug[0] != 'z') return; // TODO should we error out? |
| 19 | 21 | |
| 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 | |
| 28 | 26 | |
| 29 | 27 | for (aug[1..]) |ch| switch (ch) { |
| 30 | 28 | 'R' => { |
| 31 | const enc = try reader.readByte(); | |
| 29 | const enc = try br.takeByte(); | |
| 32 | 30 | if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) { |
| 33 | 31 | @panic("unexpected pointer encoding"); // TODO error |
| 34 | 32 | } |
| 35 | 33 | }, |
| 36 | 34 | 'P' => { |
| 37 | const enc = try reader.readByte(); | |
| 35 | const enc = try br.takeByte(); | |
| 38 | 36 | if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) { |
| 39 | 37 | @panic("unexpected personality pointer encoding"); // TODO error |
| 40 | 38 | } |
| 41 | _ = try reader.readInt(u32, .little); // personality pointer | |
| 39 | _ = try br.takeInt(u32, .little); // personality pointer | |
| 42 | 40 | }, |
| 43 | 41 | 'L' => { |
| 44 | const enc = try reader.readByte(); | |
| 42 | const enc = try br.takeByte(); | |
| 45 | 43 | switch (enc & DW_EH_PE.type_mask) { |
| 46 | 44 | DW_EH_PE.sdata4 => cie.lsda_size = .p32, |
| 47 | 45 | DW_EH_PE.absptr => cie.lsda_size = .p64, |
| ... | ... | @@ -106,20 +104,14 @@ pub const Cie = struct { |
| 106 | 104 | macho_file: *MachO, |
| 107 | 105 | }; |
| 108 | 106 | |
| 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 { | |
| 115 | 108 | _ = unused_fmt_string; |
| 116 | _ = options; | |
| 117 | 109 | const cie = ctx.cie; |
| 118 | try writer.print("@{x} : size({x})", .{ | |
| 110 | try bw.print("@{x} : size({x})", .{ | |
| 119 | 111 | cie.offset, |
| 120 | 112 | cie.getSize(), |
| 121 | 113 | }); |
| 122 | if (!cie.alive) try writer.writeAll(" : [*]"); | |
| 114 | if (!cie.alive) try bw.writeAll(" : [*]"); | |
| 123 | 115 | } |
| 124 | 116 | |
| 125 | 117 | pub const Index = u32; |
| ... | ... | @@ -148,12 +140,17 @@ pub const Fde = struct { |
| 148 | 140 | const tracy = trace(@src()); |
| 149 | 141 | defer tracy.end(); |
| 150 | 142 | |
| 151 | const data = fde.getData(macho_file); | |
| 152 | 143 | const object = fde.getObject(macho_file); |
| 153 | 144 | const sect = object.sections.items(.header)[object.eh_frame_sect_index.?]; |
| 154 | 145 | |
| 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 | ||
| 155 | 153 | // Parse target atom index |
| 156 | const pc_begin = std.mem.readInt(i64, data[8..][0..8], .little); | |
| 157 | 154 | const taddr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + 8)) + pc_begin); |
| 158 | 155 | fde.atom = object.findAtom(taddr) orelse { |
| 159 | 156 | try macho_file.reportParseError2(object.index, "{s},{s}: 0x{x}: invalid function reference in FDE", .{ |
| ... | ... | @@ -165,7 +162,6 @@ pub const Fde = struct { |
| 165 | 162 | fde.atom_offset = @intCast(taddr - atom.getInputAddress(macho_file)); |
| 166 | 163 | |
| 167 | 164 | // Associate with a CIE |
| 168 | const cie_ptr = std.mem.readInt(u32, data[4..8], .little); | |
| 169 | 165 | const cie_offset = fde.offset + 4 - cie_ptr; |
| 170 | 166 | const cie_index = for (object.cies.items, 0..) |cie, cie_index| { |
| 171 | 167 | if (cie.offset == cie_offset) break @as(Cie.Index, @intCast(cie_index)); |
| ... | ... | @@ -183,14 +179,12 @@ pub const Fde = struct { |
| 183 | 179 | |
| 184 | 180 | // Parse LSDA atom index if any |
| 185 | 181 | 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); | |
| 191 | 185 | 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), | |
| 194 | 188 | }; |
| 195 | 189 | const lsda_addr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + fde.lsda_ptr_offset)) + lsda_ptr); |
| 196 | 190 | fde.lsda = object.findAtom(lsda_addr) orelse { |
| ... | ... | @@ -256,31 +250,24 @@ pub const Fde = struct { |
| 256 | 250 | macho_file: *MachO, |
| 257 | 251 | }; |
| 258 | 252 | |
| 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 { | |
| 265 | 254 | _ = unused_fmt_string; |
| 266 | _ = options; | |
| 267 | 255 | const fde = ctx.fde; |
| 268 | 256 | 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}", .{ | |
| 270 | 258 | fde.offset, |
| 271 | 259 | fde.getSize(), |
| 272 | 260 | fde.cie, |
| 273 | 261 | fde.getAtom(macho_file).getName(macho_file), |
| 274 | 262 | }); |
| 275 | if (!fde.alive) try writer.writeAll(" : [*]"); | |
| 263 | if (!fde.alive) try bw.writeAll(" : [*]"); | |
| 276 | 264 | } |
| 277 | 265 | |
| 278 | 266 | pub const Index = u32; |
| 279 | 267 | }; |
| 280 | 268 | |
| 281 | 269 | pub const Iterator = struct { |
| 282 | data: []const u8, | |
| 283 | pos: u32 = 0, | |
| 270 | br: std.io.BufferedReader, | |
| 284 | 271 | |
| 285 | 272 | pub const Record = struct { |
| 286 | 273 | tag: enum { fde, cie }, |
| ... | ... | @@ -289,21 +276,18 @@ pub const Iterator = struct { |
| 289 | 276 | }; |
| 290 | 277 | |
| 291 | 278 | 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; | |
| 296 | 280 | |
| 297 | const size = try reader.readInt(u32, .little); | |
| 281 | const size = try it.br.takeInt(u32, .little); | |
| 298 | 282 | if (size == 0xFFFFFFFF) @panic("DWARF CFI is 32bit on macOS"); |
| 299 | 283 | |
| 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 = .{ | |
| 302 | 286 | .tag = if (id == 0) .cie else .fde, |
| 303 | .offset = it.pos, | |
| 287 | .offset = @intCast(it.br.seek), | |
| 304 | 288 | .size = size, |
| 305 | 289 | }; |
| 306 | it.pos += size + 4; | |
| 290 | try it.br.discard(size); | |
| 307 | 291 | |
| 308 | 292 | return record; |
| 309 | 293 | } |
src/link/MachO/file.zig+8-14| ... | ... | @@ -14,19 +14,13 @@ pub const File = union(enum) { |
| 14 | 14 | return .{ .data = file }; |
| 15 | 15 | } |
| 16 | 16 | |
| 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 { | |
| 23 | 18 | _ = unused_fmt_string; |
| 24 | _ = options; | |
| 25 | 19 | 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)}), | |
| 30 | 24 | } |
| 31 | 25 | } |
| 32 | 26 | |
| ... | ... | @@ -328,11 +322,11 @@ pub const File = union(enum) { |
| 328 | 322 | }; |
| 329 | 323 | } |
| 330 | 324 | |
| 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 { | |
| 332 | 326 | return switch (file) { |
| 333 | 327 | .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), | |
| 336 | 330 | }; |
| 337 | 331 | } |
| 338 | 332 |
src/link/MachO/load_commands.zig+21-30| ... | ... | @@ -180,23 +180,20 @@ pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 { |
| 180 | 180 | return offset; |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | pub fn writeDylinkerLC(writer: anytype) !void { | |
| 183 | pub fn writeDylinkerLC(bw: *std.io.BufferedWriter) anyerror!void { | |
| 184 | 184 | const name_len = mem.sliceTo(default_dyld_path, 0).len; |
| 185 | 185 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 186 | 186 | u64, |
| 187 | 187 | @sizeOf(macho.dylinker_command) + name_len, |
| 188 | 188 | @sizeOf(u64), |
| 189 | 189 | ))); |
| 190 | try writer.writeStruct(macho.dylinker_command{ | |
| 190 | try bw.writeStruct(macho.dylinker_command{ | |
| 191 | 191 | .cmd = .LOAD_DYLINKER, |
| 192 | 192 | .cmdsize = cmdsize, |
| 193 | 193 | .name = @sizeOf(macho.dylinker_command), |
| 194 | 194 | }); |
| 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); | |
| 200 | 197 | } |
| 201 | 198 | |
| 202 | 199 | const WriteDylibLCCtx = struct { |
| ... | ... | @@ -207,14 +204,14 @@ const WriteDylibLCCtx = struct { |
| 207 | 204 | compatibility_version: u32 = 0x10000, |
| 208 | 205 | }; |
| 209 | 206 | |
| 210 | pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void { | |
| 207 | pub fn writeDylibLC(ctx: WriteDylibLCCtx, bw: *std.io.BufferedWriter) !void { | |
| 211 | 208 | const name_len = ctx.name.len + 1; |
| 212 | const cmdsize = @as(u32, @intCast(mem.alignForward( | |
| 209 | const cmdsize: u32 = @intCast(mem.alignForward( | |
| 213 | 210 | u64, |
| 214 | 211 | @sizeOf(macho.dylib_command) + name_len, |
| 215 | 212 | @sizeOf(u64), |
| 216 | ))); | |
| 217 | try writer.writeStruct(macho.dylib_command{ | |
| 213 | )); | |
| 214 | try bw.writeStruct(macho.dylib_command{ | |
| 218 | 215 | .cmd = ctx.cmd, |
| 219 | 216 | .cmdsize = cmdsize, |
| 220 | 217 | .dylib = .{ |
| ... | ... | @@ -224,12 +221,9 @@ pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void { |
| 224 | 221 | .compatibility_version = ctx.compatibility_version, |
| 225 | 222 | }, |
| 226 | 223 | }); |
| 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); | |
| 233 | 227 | } |
| 234 | 228 | |
| 235 | 229 | pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void { |
| ... | ... | @@ -258,26 +252,23 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void { |
| 258 | 252 | }, writer); |
| 259 | 253 | } |
| 260 | 254 | |
| 261 | pub fn writeRpathLC(rpath: []const u8, writer: anytype) !void { | |
| 255 | pub fn writeRpathLC(bw: *std.io.BufferedWriter, rpath: []const u8) !void { | |
| 262 | 256 | const rpath_len = rpath.len + 1; |
| 263 | 257 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 264 | 258 | u64, |
| 265 | 259 | @sizeOf(macho.rpath_command) + rpath_len, |
| 266 | 260 | @sizeOf(u64), |
| 267 | 261 | ))); |
| 268 | try writer.writeStruct(macho.rpath_command{ | |
| 262 | try bw.writeStruct(macho.rpath_command{ | |
| 269 | 263 | .cmdsize = cmdsize, |
| 270 | 264 | .path = @sizeOf(macho.rpath_command), |
| 271 | 265 | }); |
| 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); | |
| 278 | 269 | } |
| 279 | 270 | |
| 280 | pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void { | |
| 271 | pub fn writeVersionMinLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) anyerror!void { | |
| 281 | 272 | const cmd: macho.LC = switch (platform.os_tag) { |
| 282 | 273 | .macos => .VERSION_MIN_MACOSX, |
| 283 | 274 | .ios => .VERSION_MIN_IPHONEOS, |
| ... | ... | @@ -285,7 +276,7 @@ pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVer |
| 285 | 276 | .watchos => .VERSION_MIN_WATCHOS, |
| 286 | 277 | else => unreachable, |
| 287 | 278 | }; |
| 288 | try writer.writeAll(mem.asBytes(&macho.version_min_command{ | |
| 279 | try bw.writeAll(mem.asBytes(&macho.version_min_command{ | |
| 289 | 280 | .cmd = cmd, |
| 290 | 281 | .version = platform.toAppleVersion(), |
| 291 | 282 | .sdk = if (sdk_version) |ver| |
| ... | ... | @@ -295,9 +286,9 @@ pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVer |
| 295 | 286 | })); |
| 296 | 287 | } |
| 297 | 288 | |
| 298 | pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void { | |
| 289 | pub fn writeBuildVersionLC(bw: *std.io.BufferedWriter, platform: MachO.Platform, sdk_version: ?std.SemanticVersion) anyerror!void { | |
| 299 | 290 | 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{ | |
| 301 | 292 | .cmdsize = cmdsize, |
| 302 | 293 | .platform = platform.toApplePlatform(), |
| 303 | 294 | .minos = platform.toAppleVersion(), |
| ... | ... | @@ -307,7 +298,7 @@ pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticV |
| 307 | 298 | platform.toAppleVersion(), |
| 308 | 299 | .ntools = 1, |
| 309 | 300 | }); |
| 310 | try writer.writeAll(mem.asBytes(&macho.build_tool_version{ | |
| 301 | try bw.writeAll(mem.asBytes(&macho.build_tool_version{ | |
| 311 | 302 | .tool = .ZIG, |
| 312 | 303 | .version = 0x0, |
| 313 | 304 | })); |
src/link/MachO/relocatable.zig+33-58| ... | ... | @@ -20,13 +20,13 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 20 | 20 | // the *only* input file over. |
| 21 | 21 | const path = positionals.items[0].path().?; |
| 22 | 22 | 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) }); | |
| 24 | 24 | 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) }); | |
| 26 | 26 | 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) }); | |
| 28 | 28 | 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}); | |
| 30 | 30 | return; |
| 31 | 31 | } |
| 32 | 32 | |
| ... | ... | @@ -62,12 +62,12 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 62 | 62 | allocateSegment(macho_file); |
| 63 | 63 | |
| 64 | 64 | if (build_options.enable_logging) { |
| 65 | state_log.debug("{}", .{macho_file.dumpState()}); | |
| 65 | state_log.debug("{f}", .{macho_file.dumpState()}); | |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | try writeSections(macho_file); |
| 69 | 69 | sortRelocs(macho_file); |
| 70 | try writeSectionsToFile(macho_file); | |
| 70 | writeSectionsToFile(macho_file) catch |err| return @errorCast(err); | |
| 71 | 71 | |
| 72 | 72 | // In order to please Apple ld (and possibly other MachO linkers in the wild), |
| 73 | 73 | // 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: ? |
| 126 | 126 | allocateSegment(macho_file); |
| 127 | 127 | |
| 128 | 128 | if (build_options.enable_logging) { |
| 129 | state_log.debug("{}", .{macho_file.dumpState()}); | |
| 129 | state_log.debug("{f}", .{macho_file.dumpState()}); | |
| 130 | 130 | } |
| 131 | 131 | |
| 132 | 132 | try writeSections(macho_file); |
| 133 | 133 | sortRelocs(macho_file); |
| 134 | try writeSectionsToFile(macho_file); | |
| 134 | writeSectionsToFile(macho_file) catch |err| return @errorCast(err); | |
| 135 | 135 | |
| 136 | 136 | // In order to please Apple ld (and possibly other MachO linkers in the wild), |
| 137 | 137 | // 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: ? |
| 202 | 202 | }; |
| 203 | 203 | |
| 204 | 204 | 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)}); | |
| 206 | 206 | } |
| 207 | 207 | |
| 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); | |
| 212 | 211 | |
| 213 | 212 | // Write magic |
| 214 | try writer.writeAll(Archive.ARMAG); | |
| 213 | bw.writeAll(Archive.ARMAG) catch unreachable; | |
| 215 | 214 | |
| 216 | 215 | // 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, | |
| 219 | 218 | else => |e| return diags.fail("failed to write archive symbol table: {s}", .{@errorName(e)}), |
| 220 | 219 | }; |
| 221 | 220 | |
| 222 | 221 | // Write object files |
| 223 | 222 | 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| | |
| 230 | 225 | return diags.fail("failed to write archive: {s}", .{@errorName(err)}); |
| 231 | 226 | } |
| 232 | 227 | |
| 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); | |
| 237 | 231 | |
| 238 | 232 | if (diags.hasErrors()) return error.LinkFailure; |
| 239 | 233 | } |
| ... | ... | @@ -689,12 +683,9 @@ fn writeSectionsToFile(macho_file: *MachO) !void { |
| 689 | 683 | |
| 690 | 684 | fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struct { usize, usize } { |
| 691 | 685 | 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); | |
| 698 | 689 | |
| 699 | 690 | var ncmds: usize = 0; |
| 700 | 691 | |
| ... | ... | @@ -702,47 +693,31 @@ fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struc |
| 702 | 693 | { |
| 703 | 694 | assert(macho_file.segments.items.len == 1); |
| 704 | 695 | 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; | |
| 708 | 697 | 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; | |
| 712 | 699 | } |
| 713 | 700 | ncmds += 1; |
| 714 | 701 | } |
| 715 | 702 | |
| 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; | |
| 719 | 704 | 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; | |
| 723 | 706 | 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; | |
| 727 | 708 | ncmds += 1; |
| 728 | 709 | |
| 729 | 710 | 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; | |
| 733 | 712 | ncmds += 1; |
| 734 | 713 | } 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; | |
| 738 | 715 | ncmds += 1; |
| 739 | 716 | } |
| 740 | 717 | |
| 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 }; | |
| 746 | 721 | } |
| 747 | 722 | |
| 748 | 723 | fn writeHeader(macho_file: *MachO, ncmds: usize, sizeofcmds: usize) !void { |
src/link/MachO/synthetic.zig+62-70| ... | ... | @@ -27,13 +27,13 @@ pub const GotSection = struct { |
| 27 | 27 | return got.symbols.items.len * @sizeOf(u64); |
| 28 | 28 | } |
| 29 | 29 | |
| 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 { | |
| 31 | 31 | const tracy = trace(@src()); |
| 32 | 32 | defer tracy.end(); |
| 33 | 33 | for (got.symbols.items) |ref| { |
| 34 | 34 | const sym = ref.getSymbol(macho_file).?; |
| 35 | 35 | 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); | |
| 37 | 37 | } |
| 38 | 38 | } |
| 39 | 39 | |
| ... | ... | @@ -48,15 +48,13 @@ pub const GotSection = struct { |
| 48 | 48 | |
| 49 | 49 | pub fn format2( |
| 50 | 50 | ctx: FormatCtx, |
| 51 | bw: *std.io.BufferedWriter, | |
| 51 | 52 | comptime unused_fmt_string: []const u8, |
| 52 | options: std.fmt.FormatOptions, | |
| 53 | writer: anytype, | |
| 54 | 53 | ) !void { |
| 55 | _ = options; | |
| 56 | 54 | _ = unused_fmt_string; |
| 57 | 55 | for (ctx.got.symbols.items, 0..) |ref, i| { |
| 58 | 56 | 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", .{ | |
| 60 | 58 | i, |
| 61 | 59 | symbol.getGotAddress(ctx.macho_file), |
| 62 | 60 | ref, |
| ... | ... | @@ -96,7 +94,7 @@ pub const StubsSection = struct { |
| 96 | 94 | return stubs.symbols.items.len * header.reserved2; |
| 97 | 95 | } |
| 98 | 96 | |
| 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 { | |
| 100 | 98 | const tracy = trace(@src()); |
| 101 | 99 | defer tracy.end(); |
| 102 | 100 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| ... | ... | @@ -108,20 +106,20 @@ pub const StubsSection = struct { |
| 108 | 106 | const target = laptr_sect.addr + idx * @sizeOf(u64); |
| 109 | 107 | switch (cpu_arch) { |
| 110 | 108 | .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); | |
| 113 | 111 | }, |
| 114 | 112 | .aarch64 => { |
| 115 | 113 | // TODO relax if possible |
| 116 | 114 | 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); | |
| 118 | 116 | const off = try math.divExact(u12, @truncate(target), 8); |
| 119 | try writer.writeInt( | |
| 117 | try bw.writeInt( | |
| 120 | 118 | u32, |
| 121 | 119 | aarch64.Instruction.ldr(.x16, .x16, aarch64.Instruction.LoadStoreOffset.imm(off)).toU32(), |
| 122 | 120 | .little, |
| 123 | 121 | ); |
| 124 | try writer.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little); | |
| 122 | try bw.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little); | |
| 125 | 123 | }, |
| 126 | 124 | else => unreachable, |
| 127 | 125 | } |
| ... | ... | @@ -139,15 +137,13 @@ pub const StubsSection = struct { |
| 139 | 137 | |
| 140 | 138 | pub fn format2( |
| 141 | 139 | ctx: FormatCtx, |
| 140 | bw: *std.io.BufferedWriter, | |
| 142 | 141 | comptime unused_fmt_string: []const u8, |
| 143 | options: std.fmt.FormatOptions, | |
| 144 | writer: anytype, | |
| 145 | 142 | ) !void { |
| 146 | _ = options; | |
| 147 | 143 | _ = unused_fmt_string; |
| 148 | 144 | for (ctx.stubs.symbols.items, 0..) |ref, i| { |
| 149 | 145 | 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", .{ | |
| 151 | 147 | i, |
| 152 | 148 | symbol.getStubsAddress(ctx.macho_file), |
| 153 | 149 | ref, |
| ... | ... | @@ -189,11 +185,11 @@ pub const StubsHelperSection = struct { |
| 189 | 185 | return s; |
| 190 | 186 | } |
| 191 | 187 | |
| 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 { | |
| 193 | 189 | const tracy = trace(@src()); |
| 194 | 190 | defer tracy.end(); |
| 195 | 191 | |
| 196 | try stubs_helper.writePreamble(macho_file, writer); | |
| 192 | try stubs_helper.writePreamble(macho_file, bw); | |
| 197 | 193 | |
| 198 | 194 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| 199 | 195 | const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?]; |
| ... | ... | @@ -209,24 +205,24 @@ pub const StubsHelperSection = struct { |
| 209 | 205 | const target: i64 = @intCast(sect.addr); |
| 210 | 206 | switch (cpu_arch) { |
| 211 | 207 | .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); | |
| 216 | 212 | }, |
| 217 | 213 | .aarch64 => { |
| 218 | 214 | const literal = blk: { |
| 219 | 215 | const div_res = try std.math.divExact(u64, entry_size - @sizeOf(u32), 4); |
| 220 | 216 | break :blk std.math.cast(u18, div_res) orelse return error.Overflow; |
| 221 | 217 | }; |
| 222 | try writer.writeInt(u32, aarch64.Instruction.ldrLiteral( | |
| 218 | try bw.writeInt(u32, aarch64.Instruction.ldrLiteral( | |
| 223 | 219 | .w16, |
| 224 | 220 | literal, |
| 225 | 221 | ).toU32(), .little); |
| 226 | 222 | const disp = math.cast(i28, @as(i64, @intCast(target)) - @as(i64, @intCast(source + 4))) orelse |
| 227 | 223 | 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 }); | |
| 230 | 226 | }, |
| 231 | 227 | else => unreachable, |
| 232 | 228 | } |
| ... | ... | @@ -234,7 +230,7 @@ pub const StubsHelperSection = struct { |
| 234 | 230 | } |
| 235 | 231 | } |
| 236 | 232 | |
| 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 { | |
| 238 | 234 | _ = stubs_helper; |
| 239 | 235 | const obj = macho_file.getInternalObject().?; |
| 240 | 236 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| ... | ... | @@ -249,21 +245,21 @@ pub const StubsHelperSection = struct { |
| 249 | 245 | }; |
| 250 | 246 | switch (cpu_arch) { |
| 251 | 247 | .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); | |
| 257 | 253 | }, |
| 258 | 254 | .aarch64 => { |
| 259 | 255 | { |
| 260 | 256 | // TODO relax if possible |
| 261 | 257 | 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); | |
| 263 | 259 | 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); | |
| 265 | 261 | } |
| 266 | try writer.writeInt(u32, aarch64.Instruction.stp( | |
| 262 | try bw.writeInt(u32, aarch64.Instruction.stp( | |
| 267 | 263 | .x16, |
| 268 | 264 | .x17, |
| 269 | 265 | aarch64.Register.sp, |
| ... | ... | @@ -272,15 +268,15 @@ pub const StubsHelperSection = struct { |
| 272 | 268 | { |
| 273 | 269 | // TODO relax if possible |
| 274 | 270 | 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); | |
| 276 | 272 | 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( | |
| 278 | 274 | .x16, |
| 279 | 275 | .x16, |
| 280 | 276 | aarch64.Instruction.LoadStoreOffset.imm(off), |
| 281 | 277 | ).toU32(), .little); |
| 282 | 278 | } |
| 283 | try writer.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little); | |
| 279 | try bw.writeInt(u32, aarch64.Instruction.br(.x16).toU32(), .little); | |
| 284 | 280 | }, |
| 285 | 281 | else => unreachable, |
| 286 | 282 | } |
| ... | ... | @@ -293,7 +289,7 @@ pub const LaSymbolPtrSection = struct { |
| 293 | 289 | return macho_file.stubs.symbols.items.len * @sizeOf(u64); |
| 294 | 290 | } |
| 295 | 291 | |
| 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 { | |
| 297 | 293 | const tracy = trace(@src()); |
| 298 | 294 | defer tracy.end(); |
| 299 | 295 | _ = laptr; |
| ... | ... | @@ -304,12 +300,12 @@ pub const LaSymbolPtrSection = struct { |
| 304 | 300 | const sym = ref.getSymbol(macho_file).?; |
| 305 | 301 | if (sym.flags.weak) { |
| 306 | 302 | const value = sym.getAddress(.{ .stubs = false }, macho_file); |
| 307 | try writer.writeInt(u64, @intCast(value), .little); | |
| 303 | try bw.writeInt(u64, @intCast(value), .little); | |
| 308 | 304 | } else { |
| 309 | 305 | const value = sect.addr + StubsHelperSection.preambleSize(cpu_arch) + |
| 310 | 306 | StubsHelperSection.entrySize(cpu_arch) * stub_helper_idx; |
| 311 | 307 | stub_helper_idx += 1; |
| 312 | try writer.writeInt(u64, @intCast(value), .little); | |
| 308 | try bw.writeInt(u64, @intCast(value), .little); | |
| 313 | 309 | } |
| 314 | 310 | } |
| 315 | 311 | } |
| ... | ... | @@ -343,16 +339,16 @@ pub const TlvPtrSection = struct { |
| 343 | 339 | return tlv.symbols.items.len * @sizeOf(u64); |
| 344 | 340 | } |
| 345 | 341 | |
| 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 { | |
| 347 | 343 | const tracy = trace(@src()); |
| 348 | 344 | defer tracy.end(); |
| 349 | 345 | |
| 350 | 346 | for (tlv.symbols.items) |ref| { |
| 351 | 347 | const sym = ref.getSymbol(macho_file).?; |
| 352 | 348 | if (sym.flags.import) { |
| 353 | try writer.writeInt(u64, 0, .little); | |
| 349 | try bw.writeInt(u64, 0, .little); | |
| 354 | 350 | } else { |
| 355 | try writer.writeInt(u64, sym.getAddress(.{}, macho_file), .little); | |
| 351 | try bw.writeInt(u64, sym.getAddress(.{}, macho_file), .little); | |
| 356 | 352 | } |
| 357 | 353 | } |
| 358 | 354 | } |
| ... | ... | @@ -368,15 +364,13 @@ pub const TlvPtrSection = struct { |
| 368 | 364 | |
| 369 | 365 | pub fn format2( |
| 370 | 366 | ctx: FormatCtx, |
| 367 | bw: *std.io.BufferedWriter, | |
| 371 | 368 | comptime unused_fmt_string: []const u8, |
| 372 | options: std.fmt.FormatOptions, | |
| 373 | writer: anytype, | |
| 374 | 369 | ) !void { |
| 375 | _ = options; | |
| 376 | 370 | _ = unused_fmt_string; |
| 377 | 371 | for (ctx.tlv.symbols.items, 0..) |ref, i| { |
| 378 | 372 | 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", .{ | |
| 380 | 374 | i, |
| 381 | 375 | symbol.getTlvPtrAddress(ctx.macho_file), |
| 382 | 376 | ref, |
| ... | ... | @@ -421,7 +415,7 @@ pub const ObjcStubsSection = struct { |
| 421 | 415 | return objc.symbols.items.len * entrySize(macho_file.getTarget().cpu.arch); |
| 422 | 416 | } |
| 423 | 417 | |
| 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 { | |
| 425 | 419 | const tracy = trace(@src()); |
| 426 | 420 | defer tracy.end(); |
| 427 | 421 | |
| ... | ... | @@ -432,18 +426,18 @@ pub const ObjcStubsSection = struct { |
| 432 | 426 | const addr = objc.getAddress(@intCast(idx), macho_file); |
| 433 | 427 | switch (macho_file.getTarget().cpu.arch) { |
| 434 | 428 | .x86_64 => { |
| 435 | try writer.writeAll(&.{ 0x48, 0x8b, 0x35 }); | |
| 429 | try bw.writeAll(&.{ 0x48, 0x8b, 0x35 }); | |
| 436 | 430 | { |
| 437 | 431 | const target = sym.getObjcSelrefsAddress(macho_file); |
| 438 | 432 | 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); | |
| 440 | 434 | } |
| 441 | try writer.writeAll(&.{ 0xff, 0x25 }); | |
| 435 | try bw.writeAll(&.{ 0xff, 0x25 }); | |
| 442 | 436 | { |
| 443 | 437 | const target_sym = obj.getObjcMsgSendRef(macho_file).?.getSymbol(macho_file).?; |
| 444 | 438 | const target = target_sym.getGotAddress(macho_file); |
| 445 | 439 | 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); | |
| 447 | 441 | } |
| 448 | 442 | }, |
| 449 | 443 | .aarch64 => { |
| ... | ... | @@ -451,9 +445,9 @@ pub const ObjcStubsSection = struct { |
| 451 | 445 | const target = sym.getObjcSelrefsAddress(macho_file); |
| 452 | 446 | const source = addr; |
| 453 | 447 | 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); | |
| 455 | 449 | const off = try math.divExact(u12, @truncate(target), 8); |
| 456 | try writer.writeInt( | |
| 450 | try bw.writeInt( | |
| 457 | 451 | u32, |
| 458 | 452 | aarch64.Instruction.ldr(.x1, .x1, aarch64.Instruction.LoadStoreOffset.imm(off)).toU32(), |
| 459 | 453 | .little, |
| ... | ... | @@ -464,18 +458,18 @@ pub const ObjcStubsSection = struct { |
| 464 | 458 | const target = target_sym.getGotAddress(macho_file); |
| 465 | 459 | const source = addr + 2 * @sizeOf(u32); |
| 466 | 460 | 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); | |
| 468 | 462 | const off = try math.divExact(u12, @truncate(target), 8); |
| 469 | try writer.writeInt( | |
| 463 | try bw.writeInt( | |
| 470 | 464 | u32, |
| 471 | 465 | aarch64.Instruction.ldr(.x16, .x16, aarch64.Instruction.LoadStoreOffset.imm(off)).toU32(), |
| 472 | 466 | .little, |
| 473 | 467 | ); |
| 474 | 468 | } |
| 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); | |
| 479 | 473 | }, |
| 480 | 474 | else => unreachable, |
| 481 | 475 | } |
| ... | ... | @@ -493,15 +487,13 @@ pub const ObjcStubsSection = struct { |
| 493 | 487 | |
| 494 | 488 | pub fn format2( |
| 495 | 489 | ctx: FormatCtx, |
| 490 | bw: *std.io.BufferedWriter, | |
| 496 | 491 | comptime unused_fmt_string: []const u8, |
| 497 | options: std.fmt.FormatOptions, | |
| 498 | writer: anytype, | |
| 499 | 492 | ) !void { |
| 500 | _ = options; | |
| 501 | 493 | _ = unused_fmt_string; |
| 502 | 494 | for (ctx.objc.symbols.items, 0..) |ref, i| { |
| 503 | 495 | 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", .{ | |
| 505 | 497 | i, |
| 506 | 498 | symbol.getObjcStubsAddress(ctx.macho_file), |
| 507 | 499 | ref, |
| ... | ... | @@ -524,7 +516,7 @@ pub const Indsymtab = struct { |
| 524 | 516 | macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file); |
| 525 | 517 | } |
| 526 | 518 | |
| 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 { | |
| 528 | 520 | const tracy = trace(@src()); |
| 529 | 521 | defer tracy.end(); |
| 530 | 522 | |
| ... | ... | @@ -533,21 +525,21 @@ pub const Indsymtab = struct { |
| 533 | 525 | for (macho_file.stubs.symbols.items) |ref| { |
| 534 | 526 | const sym = ref.getSymbol(macho_file).?; |
| 535 | 527 | if (sym.getOutputSymtabIndex(macho_file)) |idx| { |
| 536 | try writer.writeInt(u32, idx, .little); | |
| 528 | try bw.writeInt(u32, idx, .little); | |
| 537 | 529 | } |
| 538 | 530 | } |
| 539 | 531 | |
| 540 | 532 | for (macho_file.got.symbols.items) |ref| { |
| 541 | 533 | const sym = ref.getSymbol(macho_file).?; |
| 542 | 534 | if (sym.getOutputSymtabIndex(macho_file)) |idx| { |
| 543 | try writer.writeInt(u32, idx, .little); | |
| 535 | try bw.writeInt(u32, idx, .little); | |
| 544 | 536 | } |
| 545 | 537 | } |
| 546 | 538 | |
| 547 | 539 | for (macho_file.stubs.symbols.items) |ref| { |
| 548 | 540 | const sym = ref.getSymbol(macho_file).?; |
| 549 | 541 | if (sym.getOutputSymtabIndex(macho_file)) |idx| { |
| 550 | try writer.writeInt(u32, idx, .little); | |
| 542 | try bw.writeInt(u32, idx, .little); | |
| 551 | 543 | } |
| 552 | 544 | } |
| 553 | 545 | } |
| ... | ... | @@ -601,7 +593,7 @@ pub const DataInCode = struct { |
| 601 | 593 | macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow; |
| 602 | 594 | } |
| 603 | 595 | |
| 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 { | |
| 605 | 597 | const base_address = if (!macho_file.base.isRelocatable()) |
| 606 | 598 | macho_file.getTextSegment().vmaddr |
| 607 | 599 | else |
| ... | ... | @@ -609,7 +601,7 @@ pub const DataInCode = struct { |
| 609 | 601 | for (dice.entries.items) |entry| { |
| 610 | 602 | const atom_address = entry.atom_ref.getAtom(macho_file).?.getAddress(macho_file); |
| 611 | 603 | 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{ | |
| 613 | 605 | .offset = @intCast(offset), |
| 614 | 606 | .length = entry.length, |
| 615 | 607 | .kind = entry.kind, |
src/link/Plan9.zig+60-56| ... | ... | @@ -202,7 +202,7 @@ pub const Atom = struct { |
| 202 | 202 | /// after every opcode, add the quanta of the instruction size to the pc |
| 203 | 203 | pub const DebugInfoOutput = struct { |
| 204 | 204 | /// the actual opcodes |
| 205 | dbg_line: std.ArrayList(u8), | |
| 205 | dbg_line: std.ArrayListUnmanaged(u8), | |
| 206 | 206 | /// what line the debuginfo starts on |
| 207 | 207 | /// 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 |
| 208 | 208 | start_line: ?u32, |
| ... | ... | @@ -336,23 +336,26 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void |
| 336 | 336 | }; |
| 337 | 337 | try fn_map_res.value_ptr.functions.put(gpa, nav_index, out); |
| 338 | 338 | |
| 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 | ||
| 341 | 344 | // every 'z' starts with 0 |
| 342 | try a.append(0); | |
| 345 | try bw.writeByte(0); | |
| 343 | 346 | // path component value of '/' |
| 344 | try a.writer().writeInt(u16, 1, .big); | |
| 347 | try bw.writeInt(u16, 1, .big); | |
| 345 | 348 | |
| 346 | 349 | // getting the full file path |
| 347 | 350 | { |
| 348 | 351 | const full_path = try file.path.toAbsolute(comp.dirs, gpa); |
| 349 | 352 | defer gpa.free(full_path); |
| 350 | try self.addPathComponents(full_path, &a); | |
| 353 | try self.addPathComponents(full_path, bw); | |
| 351 | 354 | } |
| 352 | 355 | |
| 353 | 356 | // null terminate |
| 354 | try a.append(0); | |
| 355 | const final = try a.toOwnedSlice(); | |
| 357 | try bw.writeByte(0); | |
| 358 | const final = try aw.toOwnedSlice(); | |
| 356 | 359 | self.syms.items[fn_map_res.value_ptr.sym_index - 1] = .{ |
| 357 | 360 | .type = .z, |
| 358 | 361 | .value = 1, |
| ... | ... | @@ -367,17 +370,17 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void |
| 367 | 370 | } |
| 368 | 371 | } |
| 369 | 372 | |
| 370 | fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !void { | |
| 373 | fn addPathComponents(self: *Plan9, path: []const u8, bw: *std.io.BufferedWriter) !void { | |
| 371 | 374 | const gpa = self.base.comp.gpa; |
| 372 | 375 | const sep = std.fs.path.sep; |
| 373 | 376 | var it = std.mem.tokenizeScalar(u8, path, sep); |
| 374 | 377 | while (it.next()) |component| { |
| 375 | 378 | if (self.file_segments.get(component)) |num| { |
| 376 | try a.writer().writeInt(u16, num, .big); | |
| 379 | try bw.writeInt(u16, num, .big); | |
| 377 | 380 | } else { |
| 378 | 381 | self.file_segments_i += 1; |
| 379 | 382 | 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); | |
| 381 | 384 | } |
| 382 | 385 | } |
| 383 | 386 | } |
| ... | ... | @@ -402,14 +405,14 @@ pub fn updateFunc( |
| 402 | 405 | var code_buffer: std.ArrayListUnmanaged(u8) = .empty; |
| 403 | 406 | defer code_buffer.deinit(gpa); |
| 404 | 407 | var dbg_info_output: DebugInfoOutput = .{ |
| 405 | .dbg_line = std.ArrayList(u8).init(gpa), | |
| 408 | .dbg_line = .empty, | |
| 406 | 409 | .start_line = null, |
| 407 | 410 | .end_line = undefined, |
| 408 | 411 | .pcop_change_index = null, |
| 409 | 412 | // we have already checked the target in the linker to make sure it is compatable |
| 410 | 413 | .pc_quanta = aout.getPCQuant(target.cpu.arch) catch unreachable, |
| 411 | 414 | }; |
| 412 | defer dbg_info_output.dbg_line.deinit(); | |
| 415 | defer dbg_info_output.dbg_line.deinit(gpa); | |
| 413 | 416 | |
| 414 | 417 | try codegen.emitFunction( |
| 415 | 418 | &self.base, |
| ... | ... | @@ -427,7 +430,7 @@ pub fn updateFunc( |
| 427 | 430 | }; |
| 428 | 431 | const out: FnNavOutput = .{ |
| 429 | 432 | .code = code, |
| 430 | .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(), | |
| 433 | .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(gpa), | |
| 431 | 434 | .start_line = dbg_info_output.start_line.?, |
| 432 | 435 | .end_line = dbg_info_output.end_line, |
| 433 | 436 | }; |
| ... | ... | @@ -445,7 +448,7 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 445 | 448 | .func => return, |
| 446 | 449 | .variable => |variable| Value.fromInterned(variable.init), |
| 447 | 450 | .@"extern" => { |
| 448 | log.debug("found extern decl: {}", .{nav.name.fmt(ip)}); | |
| 451 | log.debug("found extern decl: {f}", .{nav.name.fmt(ip)}); | |
| 449 | 452 | return; |
| 450 | 453 | }, |
| 451 | 454 | else => nav_val, |
| ... | ... | @@ -524,16 +527,14 @@ fn allocateGotIndex(self: *Plan9) usize { |
| 524 | 527 | } |
| 525 | 528 | } |
| 526 | 529 | |
| 527 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { | |
| 530 | pub fn changeLine(bw: *std.io.Writer, delta_line: i32) !void { | |
| 528 | 531 | 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)); | |
| 531 | 533 | } 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)); | |
| 534 | 535 | } 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); | |
| 537 | 538 | } |
| 538 | 539 | } |
| 539 | 540 | |
| ... | ... | @@ -645,10 +646,12 @@ pub fn flush( |
| 645 | 646 | var iovecs_i: usize = 1; |
| 646 | 647 | var text_i: u64 = 0; |
| 647 | 648 | |
| 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(); | |
| 650 | 652 | // text |
| 651 | 653 | { |
| 654 | const linecountinfo_bw = &linecountinfo_aw.buffered_writer; | |
| 652 | 655 | var linecount: i64 = -1; |
| 653 | 656 | var it_file = self.fn_nav_table.iterator(); |
| 654 | 657 | while (it_file.next()) |fentry| { |
| ... | ... | @@ -662,11 +665,11 @@ pub fn flush( |
| 662 | 665 | // connect the previous decl to the next |
| 663 | 666 | const delta_line = @as(i32, @intCast(out.start_line)) - @as(i32, @intCast(linecount)); |
| 664 | 667 | |
| 665 | try changeLine(&linecountinfo, delta_line); | |
| 668 | changeLine(linecountinfo_bw, delta_line) catch |err| return @errorCast(err); | |
| 666 | 669 | // TODO change the pc too (maybe?) |
| 667 | 670 | |
| 668 | 671 | // 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); | |
| 670 | 673 | linecount = out.end_line; |
| 671 | 674 | } |
| 672 | 675 | foff += out.code.len; |
| ... | ... | @@ -675,7 +678,7 @@ pub fn flush( |
| 675 | 678 | const off = self.getAddr(text_i, .t); |
| 676 | 679 | text_i += out.code.len; |
| 677 | 680 | 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 }); | |
| 679 | 682 | if (!self.sixtyfour_bit) { |
| 680 | 683 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @intCast(off), target.cpu.arch.endian()); |
| 681 | 684 | } else { |
| ... | ... | @@ -687,11 +690,12 @@ pub fn flush( |
| 687 | 690 | } |
| 688 | 691 | } |
| 689 | 692 | } |
| 690 | if (linecountinfo.items.len & 1 == 1) { | |
| 693 | if (linecountinfo_aw.getWritten().len & 1 == 1) { | |
| 691 | 694 | // 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); | |
| 693 | 696 | } |
| 694 | 697 | } |
| 698 | const linecountinfo = linecountinfo_aw.getWritten(); | |
| 695 | 699 | // the text lazy symbols |
| 696 | 700 | { |
| 697 | 701 | var it = self.lazy_syms.iterator(); |
| ... | ... | @@ -815,25 +819,26 @@ pub fn flush( |
| 815 | 819 | } |
| 816 | 820 | } |
| 817 | 821 | } |
| 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(); | |
| 822 | 827 | assert(2 + self.atomCount() - self.externCount() == iovecs_i); // we didn't write all the decls |
| 823 | 828 | iovecs[iovecs_i] = .{ .base = syms.ptr, .len = syms.len }; |
| 824 | 829 | 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 }; | |
| 826 | 831 | iovecs_i += 1; |
| 827 | 832 | // generate the header |
| 828 | 833 | self.hdr = .{ |
| 829 | 834 | .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), | |
| 833 | 838 | .bss = 0, |
| 834 | 839 | .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.?), | |
| 837 | 842 | }; |
| 838 | 843 | @memcpy(hdr_slice, self.hdr.toU8s()[0..hdr_size]); |
| 839 | 844 | // 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) |
| 974 | 979 | self.etext_edata_end_atom_indices[2] = atom_idx; |
| 975 | 980 | } |
| 976 | 981 | 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})", .{ | |
| 978 | 983 | nav.name.fmt(ip), |
| 979 | 984 | self.getAtom(atom_idx).getOffsetTableAddress(self), |
| 980 | 985 | }); |
| 981 | } else log.debug("seeNav for {}", .{nav.name.fmt(ip)}); | |
| 986 | } else log.debug("seeNav for {f}", .{nav.name.fmt(ip)}); | |
| 982 | 987 | return atom_idx; |
| 983 | 988 | } |
| 984 | 989 | |
| ... | ... | @@ -1043,7 +1048,7 @@ fn updateLazySymbolAtom( |
| 1043 | 1048 | defer code_buffer.deinit(gpa); |
| 1044 | 1049 | |
| 1045 | 1050 | // 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}", .{ | |
| 1047 | 1052 | @tagName(sym.kind), |
| 1048 | 1053 | Type.fromInterned(sym.ty).fmt(pt), |
| 1049 | 1054 | }); |
| ... | ... | @@ -1200,17 +1205,16 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void { |
| 1200 | 1205 | try w.writeByte(0); |
| 1201 | 1206 | } |
| 1202 | 1207 | |
| 1203 | pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { | |
| 1208 | pub fn writeSyms(self: *Plan9, bw: *std.io.BufferedWriter) !void { | |
| 1204 | 1209 | const zcu = self.base.comp.zcu.?; |
| 1205 | 1210 | const ip = &zcu.intern_pool; |
| 1206 | const writer = buf.writer(); | |
| 1207 | 1211 | // write __GOT |
| 1208 | try self.writeSym(writer, self.syms.items[0]); | |
| 1212 | try self.writeSym(bw, self.syms.items[0]); | |
| 1209 | 1213 | // write the f symbols |
| 1210 | 1214 | { |
| 1211 | 1215 | var it = self.file_segments.iterator(); |
| 1212 | 1216 | while (it.next()) |entry| { |
| 1213 | try self.writeSym(writer, .{ | |
| 1217 | try self.writeSym(bw, .{ | |
| 1214 | 1218 | .type = .f, |
| 1215 | 1219 | .value = entry.value_ptr.*, |
| 1216 | 1220 | .name = entry.key_ptr.*, |
| ... | ... | @@ -1226,12 +1230,12 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1226 | 1230 | const nav_metadata = self.navs.get(nav_index).?; |
| 1227 | 1231 | const atom = self.getAtom(nav_metadata.index); |
| 1228 | 1232 | const sym = self.syms.items[atom.sym_index.?]; |
| 1229 | try self.writeSym(writer, sym); | |
| 1233 | try self.writeSym(bw, sym); | |
| 1230 | 1234 | if (self.nav_exports.get(nav_index)) |export_indices| { |
| 1231 | 1235 | for (export_indices) |export_idx| { |
| 1232 | 1236 | const exp = export_idx.ptr(zcu); |
| 1233 | 1237 | 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]); | |
| 1235 | 1239 | } |
| 1236 | 1240 | } |
| 1237 | 1241 | } |
| ... | ... | @@ -1244,7 +1248,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1244 | 1248 | const meta = kv.value_ptr; |
| 1245 | 1249 | const data_atom = if (meta.rodata_state != .unused) self.getAtomPtr(meta.rodata_atom) else continue; |
| 1246 | 1250 | const sym = self.syms.items[data_atom.sym_index.?]; |
| 1247 | try self.writeSym(writer, sym); | |
| 1251 | try self.writeSym(bw, sym); | |
| 1248 | 1252 | } |
| 1249 | 1253 | } |
| 1250 | 1254 | // text symbols are the hardest: |
| ... | ... | @@ -1255,8 +1259,8 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1255 | 1259 | while (it_file.next()) |fentry| { |
| 1256 | 1260 | var symidx_and_submap = fentry.value_ptr; |
| 1257 | 1261 | // 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]); | |
| 1260 | 1264 | |
| 1261 | 1265 | // write all the decls come from the file of the z symbol |
| 1262 | 1266 | var submap_it = symidx_and_submap.functions.iterator(); |
| ... | ... | @@ -1265,7 +1269,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1265 | 1269 | const nav_metadata = self.navs.get(nav_index).?; |
| 1266 | 1270 | const atom = self.getAtom(nav_metadata.index); |
| 1267 | 1271 | const sym = self.syms.items[atom.sym_index.?]; |
| 1268 | try self.writeSym(writer, sym); | |
| 1272 | try self.writeSym(bw, sym); | |
| 1269 | 1273 | if (self.nav_exports.get(nav_index)) |export_indices| { |
| 1270 | 1274 | for (export_indices) |export_idx| { |
| 1271 | 1275 | const exp = export_idx.ptr(zcu); |
| ... | ... | @@ -1273,7 +1277,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1273 | 1277 | const s = self.syms.items[exp_i]; |
| 1274 | 1278 | if (mem.eql(u8, s.name, "_start")) |
| 1275 | 1279 | self.entry_val = s.value; |
| 1276 | try self.writeSym(writer, s); | |
| 1280 | try self.writeSym(bw, s); | |
| 1277 | 1281 | } |
| 1278 | 1282 | } |
| 1279 | 1283 | } |
| ... | ... | @@ -1286,7 +1290,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1286 | 1290 | const meta = kv.value_ptr; |
| 1287 | 1291 | const text_atom = if (meta.text_state != .unused) self.getAtomPtr(meta.text_atom) else continue; |
| 1288 | 1292 | const sym = self.syms.items[text_atom.sym_index.?]; |
| 1289 | try self.writeSym(writer, sym); | |
| 1293 | try self.writeSym(bw, sym); | |
| 1290 | 1294 | } |
| 1291 | 1295 | } |
| 1292 | 1296 | } |
| ... | ... | @@ -1295,7 +1299,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1295 | 1299 | if (idx) |atom_idx| { |
| 1296 | 1300 | const atom = self.getAtom(atom_idx); |
| 1297 | 1301 | const sym = self.syms.items[atom.sym_index.?]; |
| 1298 | try self.writeSym(writer, sym); | |
| 1302 | try self.writeSym(bw, sym); | |
| 1299 | 1303 | } |
| 1300 | 1304 | } |
| 1301 | 1305 | } |
| ... | ... | @@ -1314,7 +1318,7 @@ pub fn getNavVAddr( |
| 1314 | 1318 | ) !u64 { |
| 1315 | 1319 | const ip = &pt.zcu.intern_pool; |
| 1316 | 1320 | 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)}); | |
| 1318 | 1322 | if (nav.getExtern(ip) != null) { |
| 1319 | 1323 | if (nav.name.eqlSlice("etext", ip)) { |
| 1320 | 1324 | 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 |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | 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 }); | |
| 121 | 121 | |
| 122 | 122 | try self.object.updateNav(pt, nav); |
| 123 | 123 | } |
| ... | ... | @@ -203,10 +203,11 @@ pub fn flush( |
| 203 | 203 | // We need to export the list of error names somewhere so that we can pretty-print them in the |
| 204 | 204 | // executor. This is not really an important thing though, so we can just dump it in any old |
| 205 | 205 | // 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); | |
| 207 | 208 | defer error_info.deinit(); |
| 208 | 209 | |
| 209 | try error_info.appendSlice("zig_errors:"); | |
| 210 | error_info.buffered_writer.writeAll("zig_errors:") catch |err| return @errorCast(err); | |
| 210 | 211 | const ip = &self.base.comp.zcu.?.intern_pool; |
| 211 | 212 | for (ip.global_error_set.getNamesFromMainThread()) |name| { |
| 212 | 213 | // Errors can contain pretty much any character - to encode them in a string we must escape |
| ... | ... | @@ -214,9 +215,9 @@ pub fn flush( |
| 214 | 215 | // name if it contains no strange characters is nice for debugging. URI encoding fits the bill. |
| 215 | 216 | // We're using : as separator, which is a reserved character. |
| 216 | 217 | |
| 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, | |
| 220 | 221 | name.toSlice(ip), |
| 221 | 222 | struct { |
| 222 | 223 | fn isValidChar(c: u8) bool { |
| ... | ... | @@ -226,10 +227,10 @@ pub fn flush( |
| 226 | 227 | }; |
| 227 | 228 | } |
| 228 | 229 | }.isValidChar, |
| 229 | ); | |
| 230 | ) catch |err| return @errorCast(err); | |
| 230 | 231 | } |
| 231 | 232 | try spv.sections.debug_strings.emit(gpa, .OpSourceExtension, .{ |
| 232 | .extension = error_info.items, | |
| 233 | .extension = error_info.getWritten(), | |
| 233 | 234 | }); |
| 234 | 235 | |
| 235 | 236 | const module = try spv.finalize(arena); |
src/link/SpirV/deduplicate.zig+1-1| ... | ... | @@ -110,7 +110,7 @@ const ModuleInfo = struct { |
| 110 | 110 | .TypeDeclaration, .ConstantCreation => { |
| 111 | 111 | const entry = try entities.getOrPut(result_id); |
| 112 | 112 | 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}); | |
| 114 | 114 | return error.DuplicateId; |
| 115 | 115 | } |
| 116 | 116 | entry.value_ptr.* = entity; |
src/link/SpirV/lower_invocation_globals.zig+9-9| ... | ... | @@ -92,7 +92,7 @@ const ModuleInfo = struct { |
| 92 | 92 | const entry_point: ResultId = @enumFromInt(inst.operands[1]); |
| 93 | 93 | const entry = try entry_points.getOrPut(entry_point); |
| 94 | 94 | 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}); | |
| 96 | 96 | return error.DuplicateId; |
| 97 | 97 | } |
| 98 | 98 | }, |
| ... | ... | @@ -103,7 +103,7 @@ const ModuleInfo = struct { |
| 103 | 103 | |
| 104 | 104 | const entry = try fn_types.getOrPut(fn_type); |
| 105 | 105 | 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}); | |
| 107 | 107 | return error.DuplicateId; |
| 108 | 108 | } |
| 109 | 109 | |
| ... | ... | @@ -135,7 +135,7 @@ const ModuleInfo = struct { |
| 135 | 135 | }, |
| 136 | 136 | .OpFunction => { |
| 137 | 137 | 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}); | |
| 139 | 139 | return error.InvalidPhysicalFormat; |
| 140 | 140 | } |
| 141 | 141 | |
| ... | ... | @@ -154,7 +154,7 @@ const ModuleInfo = struct { |
| 154 | 154 | }; |
| 155 | 155 | const entry = try functions.getOrPut(current_function); |
| 156 | 156 | if (entry.found_existing) { |
| 157 | log.err("Function {} has duplicate definition", .{current_function}); | |
| 157 | log.err("Function {f} has duplicate definition", .{current_function}); | |
| 158 | 158 | return error.DuplicateId; |
| 159 | 159 | } |
| 160 | 160 | |
| ... | ... | @@ -162,7 +162,7 @@ const ModuleInfo = struct { |
| 162 | 162 | try callee_store.appendSlice(calls.keys()); |
| 163 | 163 | |
| 164 | 164 | 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}); | |
| 166 | 166 | return error.InvalidId; |
| 167 | 167 | }; |
| 168 | 168 | |
| ... | ... | @@ -187,7 +187,7 @@ const ModuleInfo = struct { |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | 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}); | |
| 191 | 191 | return error.InvalidPhysicalFormat; |
| 192 | 192 | } |
| 193 | 193 | |
| ... | ... | @@ -222,7 +222,7 @@ const ModuleInfo = struct { |
| 222 | 222 | seen: *std.DynamicBitSetUnmanaged, |
| 223 | 223 | ) !void { |
| 224 | 224 | const index = self.functions.getIndex(id) orelse { |
| 225 | log.err("function calls invalid function {}", .{id}); | |
| 225 | log.err("function calls invalid function {f}", .{id}); | |
| 226 | 226 | return error.InvalidId; |
| 227 | 227 | }; |
| 228 | 228 | |
| ... | ... | @@ -261,7 +261,7 @@ const ModuleInfo = struct { |
| 261 | 261 | seen: *std.DynamicBitSetUnmanaged, |
| 262 | 262 | ) !void { |
| 263 | 263 | const index = self.invocation_globals.getIndex(id) orelse { |
| 264 | log.err("invalid invocation global {}", .{id}); | |
| 264 | log.err("invalid invocation global {f}", .{id}); | |
| 265 | 265 | return error.InvalidId; |
| 266 | 266 | }; |
| 267 | 267 | |
| ... | ... | @@ -276,7 +276,7 @@ const ModuleInfo = struct { |
| 276 | 276 | } |
| 277 | 277 | |
| 278 | 278 | 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 }); | |
| 280 | 280 | return error.InvalidId; |
| 281 | 281 | }; |
| 282 | 282 |
src/link/SpirV/prune_unused.zig+4-4| ... | ... | @@ -128,7 +128,7 @@ const ModuleInfo = struct { |
| 128 | 128 | switch (inst.opcode) { |
| 129 | 129 | .OpFunction => { |
| 130 | 130 | 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}); | |
| 132 | 132 | return error.InvalidPhysicalFormat; |
| 133 | 133 | } |
| 134 | 134 | |
| ... | ... | @@ -145,7 +145,7 @@ const ModuleInfo = struct { |
| 145 | 145 | }; |
| 146 | 146 | const entry = try functions.getOrPut(current_function); |
| 147 | 147 | if (entry.found_existing) { |
| 148 | log.err("Function {} has duplicate definition", .{current_function}); | |
| 148 | log.err("Function {f} has duplicate definition", .{current_function}); | |
| 149 | 149 | return error.DuplicateId; |
| 150 | 150 | } |
| 151 | 151 | |
| ... | ... | @@ -163,7 +163,7 @@ const ModuleInfo = struct { |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | 165 | 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}); | |
| 167 | 167 | return error.InvalidPhysicalFormat; |
| 168 | 168 | } |
| 169 | 169 | |
| ... | ... | @@ -184,7 +184,7 @@ const AliveMarker = struct { |
| 184 | 184 | |
| 185 | 185 | fn markAlive(self: *AliveMarker, result_id: ResultId) BinaryModule.ParseError!void { |
| 186 | 186 | 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}); | |
| 188 | 188 | return error.InvalidId; |
| 189 | 189 | }; |
| 190 | 190 |
src/link/Wasm.zig+27-34| ... | ... | @@ -547,7 +547,7 @@ pub const SourceLocation = enum(u32) { |
| 547 | 547 | switch (sl.unpack(wasm)) { |
| 548 | 548 | .none => unreachable, |
| 549 | 549 | .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), | |
| 551 | 551 | .source_location_index => @panic("TODO"), |
| 552 | 552 | } |
| 553 | 553 | } |
| ... | ... | @@ -579,9 +579,9 @@ pub const SourceLocation = enum(u32) { |
| 579 | 579 | .object_index => |i| { |
| 580 | 580 | const obj = i.ptr(wasm); |
| 581 | 581 | 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 }) | |
| 583 | 583 | else |
| 584 | try bundle.printString("{}: {s}", .{ obj.path, msg }); | |
| 584 | try bundle.printString("{f}: {s}", .{ obj.path, msg }); | |
| 585 | 585 | }, |
| 586 | 586 | .source_location_index => @panic("TODO"), |
| 587 | 587 | }; |
| ... | ... | @@ -2087,11 +2087,10 @@ pub const Expr = enum(u32) { |
| 2087 | 2087 | pub const end = @intFromEnum(std.wasm.Opcode.end); |
| 2088 | 2088 | |
| 2089 | 2089 | 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]; | |
| 2095 | 2094 | } |
| 2096 | 2095 | }; |
| 2097 | 2096 | |
| ... | ... | @@ -2126,32 +2125,26 @@ pub const FunctionType = extern struct { |
| 2126 | 2125 | wasm: *const Wasm, |
| 2127 | 2126 | ft: FunctionType, |
| 2128 | 2127 | |
| 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 { | |
| 2135 | 2129 | if (format_string.len != 0) std.fmt.invalidFmtError(format_string, self); |
| 2136 | _ = options; | |
| 2137 | 2130 | const params = self.ft.params.slice(self.wasm); |
| 2138 | 2131 | const returns = self.ft.returns.slice(self.wasm); |
| 2139 | 2132 | |
| 2140 | try writer.writeByte('('); | |
| 2133 | try bw.writeByte('('); | |
| 2141 | 2134 | for (params, 0..) |param, i| { |
| 2142 | try writer.print("{s}", .{@tagName(param)}); | |
| 2135 | try bw.print("{s}", .{@tagName(param)}); | |
| 2143 | 2136 | if (i + 1 != params.len) { |
| 2144 | try writer.writeAll(", "); | |
| 2137 | try bw.writeAll(", "); | |
| 2145 | 2138 | } |
| 2146 | 2139 | } |
| 2147 | try writer.writeAll(") -> "); | |
| 2140 | try bw.writeAll(") -> "); | |
| 2148 | 2141 | if (returns.len == 0) { |
| 2149 | try writer.writeAll("nil"); | |
| 2142 | try bw.writeAll("nil"); | |
| 2150 | 2143 | } else { |
| 2151 | 2144 | for (returns, 0..) |return_ty, i| { |
| 2152 | try writer.print("{s}", .{@tagName(return_ty)}); | |
| 2145 | try bw.print("{s}", .{@tagName(return_ty)}); | |
| 2153 | 2146 | if (i + 1 != returns.len) { |
| 2154 | try writer.writeAll(", "); | |
| 2147 | try bw.writeAll(", "); | |
| 2155 | 2148 | } |
| 2156 | 2149 | } |
| 2157 | 2150 | } |
| ... | ... | @@ -2912,10 +2905,9 @@ pub const Feature = packed struct(u8) { |
| 2912 | 2905 | @"=", |
| 2913 | 2906 | }; |
| 2914 | 2907 | |
| 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 { | |
| 2917 | 2909 | _ = 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) }); | |
| 2919 | 2911 | } |
| 2920 | 2912 | |
| 2921 | 2913 | pub fn lessThan(_: void, a: Feature, b: Feature) bool { |
| ... | ... | @@ -3036,7 +3028,7 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void { |
| 3036 | 3028 | } |
| 3037 | 3029 | |
| 3038 | 3030 | fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3039 | log.debug("parseObject {}", .{obj.path}); | |
| 3031 | log.debug("parseObject {f}", .{obj.path}); | |
| 3040 | 3032 | const gpa = wasm.base.comp.gpa; |
| 3041 | 3033 | const gc_sections = wasm.base.gc_sections; |
| 3042 | 3034 | |
| ... | ... | @@ -3046,21 +3038,22 @@ fn parseObject(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3046 | 3038 | const stat = try obj.file.stat(); |
| 3047 | 3039 | const size = std.math.cast(usize, stat.size) orelse return error.FileTooBig; |
| 3048 | 3040 | |
| 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()); | |
| 3051 | 3044 | |
| 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; | |
| 3054 | 3047 | |
| 3055 | 3048 | var ss: Object.ScratchSpace = .{}; |
| 3056 | 3049 | defer ss.deinit(gpa); |
| 3057 | 3050 | |
| 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); | |
| 3059 | 3052 | wasm.objects.appendAssumeCapacity(object); |
| 3060 | 3053 | } |
| 3061 | 3054 | |
| 3062 | 3055 | fn parseArchive(wasm: *Wasm, obj: link.Input.Object) !void { |
| 3063 | log.debug("parseArchive {}", .{obj.path}); | |
| 3056 | log.debug("parseArchive {f}", .{obj.path}); | |
| 3064 | 3057 | const gpa = wasm.base.comp.gpa; |
| 3065 | 3058 | const gc_sections = wasm.base.gc_sections; |
| 3066 | 3059 | |
| ... | ... | @@ -3196,7 +3189,7 @@ pub fn updateFunc( |
| 3196 | 3189 | const is_obj = zcu.comp.config.output_mode == .Obj; |
| 3197 | 3190 | const target = &zcu.comp.root_mod.resolved_target.result; |
| 3198 | 3191 | 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)}); | |
| 3200 | 3193 | |
| 3201 | 3194 | // For Wasm, we do not lower the MIR to code just yet. That lowering happens during `flush`, |
| 3202 | 3195 | // after garbage collection, which can affect function and global indexes, which affects the |
| ... | ... | @@ -4347,7 +4340,7 @@ fn resolveFunctionSynthetic( |
| 4347 | 4340 | }); |
| 4348 | 4341 | if (import.type != correct_func_type) { |
| 4349 | 4342 | 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}", .{ | |
| 4351 | 4344 | @tagName(res), correct_func_type.fmt(wasm), import.type.fmt(wasm), |
| 4352 | 4345 | }); |
| 4353 | 4346 | } |
src/link/Wasm/Archive.zig+3-2| ... | ... | @@ -167,9 +167,10 @@ pub fn parseObject( |
| 167 | 167 | }; |
| 168 | 168 | |
| 169 | 169 | 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]); | |
| 171 | 172 | |
| 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); | |
| 173 | 174 | } |
| 174 | 175 | |
| 175 | 176 | const Archive = @This(); |
src/link/Wasm/Flush.zig+469-554| ... | ... | @@ -16,7 +16,6 @@ const build_options = @import("build_options"); |
| 16 | 16 | const std = @import("std"); |
| 17 | 17 | const Allocator = std.mem.Allocator; |
| 18 | 18 | const mem = std.mem; |
| 19 | const leb = std.leb; | |
| 20 | 19 | const log = std.log.scoped(.link); |
| 21 | 20 | const assert = std.debug.assert; |
| 22 | 21 | |
| ... | ... | @@ -557,13 +556,12 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 557 | 556 | // Index of the data section. Used to tell relocation table where the section lives. |
| 558 | 557 | var data_section_index: ?u32 = null; |
| 559 | 558 | |
| 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(); | |
| 562 | 563 | |
| 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); | |
| 567 | 565 | |
| 568 | 566 | // Type section. |
| 569 | 567 | for (f.function_imports.values()) |id| { |
| ... | ... | @@ -573,22 +571,18 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 573 | 571 | try f.func_types.put(gpa, function.typeIndex(wasm), {}); |
| 574 | 572 | } |
| 575 | 573 | if (f.func_types.entries.len != 0) { |
| 576 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 574 | const header_offset = try reserveVecSectionHeader(bw); | |
| 577 | 575 | for (f.func_types.keys()) |func_type_index| { |
| 578 | 576 | 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); | |
| 580 | 578 | 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)); | |
| 585 | 581 | 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)); | |
| 590 | 584 | } |
| 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)); | |
| 592 | 586 | section_index += 1; |
| 593 | 587 | } |
| 594 | 588 | |
| ... | ... | @@ -601,42 +595,42 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 601 | 595 | // Import section |
| 602 | 596 | { |
| 603 | 597 | var total_imports: usize = 0; |
| 604 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 598 | const header_offset = try reserveVecSectionHeader(bw); | |
| 605 | 599 | |
| 606 | 600 | for (f.function_imports.values()) |id| { |
| 607 | 601 | 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); | |
| 610 | 604 | |
| 611 | 605 | 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); | |
| 614 | 608 | |
| 615 | try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | |
| 609 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | |
| 616 | 610 | 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)); | |
| 618 | 612 | } |
| 619 | 613 | total_imports += f.function_imports.entries.len; |
| 620 | 614 | |
| 621 | 615 | for (wasm.table_imports.values()) |id| { |
| 622 | 616 | const table_import = id.value(wasm); |
| 623 | 617 | 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); | |
| 626 | 620 | |
| 627 | 621 | 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); | |
| 630 | 624 | |
| 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()); | |
| 634 | 628 | } |
| 635 | 629 | total_imports += wasm.table_imports.entries.len; |
| 636 | 630 | |
| 637 | 631 | if (import_memory) { |
| 638 | 632 | 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, &.{ | |
| 640 | 634 | // TODO the import_memory option needs to specify from which module |
| 641 | 635 | .module_name = wasm.object_host_name.unwrap().?, |
| 642 | 636 | .limits_min = wasm.memories.limits.min, |
| ... | ... | @@ -650,215 +644,209 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 650 | 644 | |
| 651 | 645 | for (f.global_imports.values()) |id| { |
| 652 | 646 | 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); | |
| 655 | 649 | |
| 656 | 650 | 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); | |
| 659 | 653 | |
| 660 | try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.global)); | |
| 654 | try bw.writeByte(@intFromEnum(std.wasm.ExternalKind.global)); | |
| 661 | 655 | 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)); | |
| 664 | 658 | } |
| 665 | 659 | total_imports += f.global_imports.entries.len; |
| 666 | 660 | |
| 667 | 661 | if (total_imports > 0) { |
| 668 | replaceVecSectionHeader(binary_bytes, header_offset, .import, @intCast(total_imports)); | |
| 662 | replaceVecSectionHeader(&aw, header_offset, .import, @intCast(total_imports)); | |
| 669 | 663 | section_index += 1; |
| 670 | 664 | } else { |
| 671 | binary_bytes.shrinkRetainingCapacity(header_offset); | |
| 665 | aw.shrinkRetainingCapacity(header_offset); | |
| 672 | 666 | } |
| 673 | 667 | } |
| 674 | 668 | |
| 675 | 669 | // Function section |
| 676 | 670 | if (wasm.functions.count() != 0) { |
| 677 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 671 | const header_offset = try reserveVecSectionHeader(bw); | |
| 678 | 672 | for (wasm.functions.keys()) |function| { |
| 679 | 673 | const index: FuncTypeIndex = .fromTypeIndex(function.typeIndex(wasm), f); |
| 680 | try leb.writeUleb128(binary_writer, @intFromEnum(index)); | |
| 674 | try bw.writeLeb128(@intFromEnum(index)); | |
| 681 | 675 | } |
| 682 | 676 | |
| 683 | replaceVecSectionHeader(binary_bytes, header_offset, .function, @intCast(wasm.functions.count())); | |
| 677 | replaceVecSectionHeader(&aw, header_offset, .function, @intCast(wasm.functions.count())); | |
| 684 | 678 | section_index += 1; |
| 685 | 679 | } |
| 686 | 680 | |
| 687 | 681 | // Table section |
| 688 | 682 | if (wasm.tables.entries.len > 0) { |
| 689 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 683 | const header_offset = try reserveVecSectionHeader(bw); | |
| 690 | 684 | |
| 691 | 685 | 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)); | |
| 694 | 688 | } |
| 695 | 689 | |
| 696 | replaceVecSectionHeader(binary_bytes, header_offset, .table, @intCast(wasm.tables.entries.len)); | |
| 690 | replaceVecSectionHeader(&aw, header_offset, .table, @intCast(wasm.tables.entries.len)); | |
| 697 | 691 | section_index += 1; |
| 698 | 692 | } |
| 699 | 693 | |
| 700 | 694 | // Memory section. wasm currently only supports 1 linear memory segment. |
| 701 | 695 | 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); | |
| 705 | 699 | section_index += 1; |
| 706 | 700 | } |
| 707 | 701 | |
| 708 | 702 | // Global section. |
| 709 | 703 | const globals_len: u32 = @intCast(wasm.globals.entries.len); |
| 710 | 704 | if (globals_len > 0) { |
| 711 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 705 | const header_offset = try reserveVecSectionHeader(bw); | |
| 712 | 706 | |
| 713 | 707 | for (wasm.globals.keys()) |global_resolution| { |
| 714 | 708 | switch (global_resolution.unpack(wasm)) { |
| 715 | 709 | .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.?), | |
| 722 | 716 | .object_global => |i| { |
| 723 | 717 | const global = i.ptr(wasm); |
| 724 | try binary_bytes.appendSlice(gpa, &.{ | |
| 718 | try bw.writeAll(&.{ | |
| 725 | 719 | @intFromEnum(@as(std.wasm.Valtype, global.flags.global_type.valtype.to())), |
| 726 | 720 | @intFromBool(global.flags.global_type.mutable), |
| 727 | 721 | }); |
| 728 | try emitExpr(wasm, binary_bytes, global.expr); | |
| 722 | try emitExpr(wasm, bw, global.expr); | |
| 729 | 723 | }, |
| 730 | 724 | .nav_exe => unreachable, // Zig source code currently cannot represent this. |
| 731 | 725 | .nav_obj => unreachable, // Zig source code currently cannot represent this. |
| 732 | 726 | } |
| 733 | 727 | } |
| 734 | 728 | |
| 735 | replaceVecSectionHeader(binary_bytes, header_offset, .global, globals_len); | |
| 729 | replaceVecSectionHeader(&aw, header_offset, .global, globals_len); | |
| 736 | 730 | section_index += 1; |
| 737 | 731 | } |
| 738 | 732 | |
| 739 | 733 | // Export section |
| 740 | 734 | { |
| 741 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 735 | const header_offset = try reserveVecSectionHeader(bw); | |
| 742 | 736 | var exports_len: usize = 0; |
| 743 | 737 | |
| 744 | 738 | for (wasm.function_exports.keys(), wasm.function_exports.values()) |exp_name, function_index| { |
| 745 | 739 | 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)); | |
| 749 | 743 | 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)); | |
| 751 | 745 | } |
| 752 | 746 | exports_len += wasm.function_exports.entries.len; |
| 753 | 747 | |
| 754 | 748 | if (wasm.export_table and f.indirect_function_table.entries.len > 0) { |
| 755 | 749 | const name = "__indirect_function_table"; |
| 756 | 750 | 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); | |
| 761 | 755 | exports_len += 1; |
| 762 | 756 | } |
| 763 | 757 | |
| 764 | 758 | if (export_memory) { |
| 765 | 759 | 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); | |
| 770 | 764 | exports_len += 1; |
| 771 | 765 | } |
| 772 | 766 | |
| 773 | 767 | for (wasm.global_exports.items) |exp| { |
| 774 | 768 | 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)); | |
| 779 | 773 | } |
| 780 | 774 | exports_len += wasm.global_exports.items.len; |
| 781 | 775 | |
| 782 | 776 | if (exports_len > 0) { |
| 783 | replaceVecSectionHeader(binary_bytes, header_offset, .@"export", @intCast(exports_len)); | |
| 777 | replaceVecSectionHeader(&aw, header_offset, .@"export", @intCast(exports_len)); | |
| 784 | 778 | section_index += 1; |
| 785 | 779 | } else { |
| 786 | binary_bytes.shrinkRetainingCapacity(header_offset); | |
| 780 | aw.shrinkRetainingCapacity(header_offset); | |
| 787 | 781 | } |
| 788 | 782 | } |
| 789 | 783 | |
| 790 | 784 | // start section |
| 791 | 785 | 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))); | |
| 793 | 787 | } 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); | |
| 795 | 789 | } |
| 796 | 790 | |
| 797 | 791 | // element section |
| 798 | 792 | if (f.indirect_function_table.entries.len > 0) { |
| 799 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 793 | const header_offset = try reserveVecSectionHeader(bw); | |
| 800 | 794 | |
| 801 | 795 | // indirect function table elements |
| 802 | 796 | const table_index: u32 = @intCast(wasm.tables.getIndex(.__indirect_function_table).?); |
| 803 | 797 | // passive with implicit 0-index table or set table index manually |
| 804 | 798 | 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); | |
| 809 | 801 | // 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)); | |
| 818 | 806 | |
| 819 | replaceVecSectionHeader(binary_bytes, header_offset, .element, 1); | |
| 807 | replaceVecSectionHeader(&aw, header_offset, .element, 1); | |
| 820 | 808 | section_index += 1; |
| 821 | 809 | } |
| 822 | 810 | |
| 823 | 811 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. |
| 824 | 812 | 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)); | |
| 827 | 815 | } |
| 828 | 816 | |
| 829 | 817 | // Code section. |
| 830 | 818 | if (wasm.functions.count() != 0) { |
| 831 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 819 | const header_offset = try reserveVecSectionHeader(bw); | |
| 832 | 820 | |
| 833 | 821 | for (wasm.functions.keys()) |resolution| switch (resolution.unpack(wasm)) { |
| 834 | 822 | .unresolved => unreachable, |
| 835 | 823 | .__wasm_apply_global_tls_relocs => @panic("TODO lower __wasm_apply_global_tls_relocs"), |
| 836 | 824 | .__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); | |
| 840 | 828 | }, |
| 841 | 829 | .__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); | |
| 845 | 833 | }, |
| 846 | 834 | .__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); | |
| 850 | 838 | }, |
| 851 | 839 | .object_function => |i| { |
| 852 | 840 | const ptr = i.ptr(wasm); |
| 853 | 841 | 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); | |
| 858 | 846 | }, |
| 859 | 847 | .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); | |
| 862 | 850 | |
| 863 | 851 | log.debug("lowering function code for '{s}'", .{resolution.name(wasm).?}); |
| 864 | 852 | |
| ... | ... | @@ -867,7 +855,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 867 | 855 | const ip_index = i.key(wasm).*; |
| 868 | 856 | switch (ip.indexToKey(ip_index)) { |
| 869 | 857 | .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); | |
| 871 | 859 | }, |
| 872 | 860 | else => { |
| 873 | 861 | const func = i.value(wasm).function; |
| ... | ... | @@ -882,13 +870,13 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 882 | 870 | .func_tys = undefined, |
| 883 | 871 | .error_name_table_ref_count = undefined, |
| 884 | 872 | }; |
| 885 | try mir.lower(wasm, binary_bytes); | |
| 873 | try mir.lower(wasm, bw); | |
| 886 | 874 | }, |
| 887 | 875 | } |
| 888 | 876 | }, |
| 889 | 877 | }; |
| 890 | 878 | |
| 891 | replaceVecSectionHeader(binary_bytes, header_offset, .code, @intCast(wasm.functions.entries.len)); | |
| 879 | replaceVecSectionHeader(&aw, header_offset, .code, @intCast(wasm.functions.entries.len)); | |
| 892 | 880 | code_section_index = section_index; |
| 893 | 881 | section_index += 1; |
| 894 | 882 | } |
| ... | ... | @@ -924,7 +912,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 924 | 912 | |
| 925 | 913 | // Data section. |
| 926 | 914 | if (f.data_segment_groups.items.len != 0) { |
| 927 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | |
| 915 | const header_offset = try reserveVecSectionHeader(bw); | |
| 928 | 916 | |
| 929 | 917 | var group_index: u32 = 0; |
| 930 | 918 | var segment_offset: u32 = 0; |
| ... | ... | @@ -932,7 +920,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 932 | 920 | var group_end_addr = f.data_segment_groups.items[group_index].end_addr; |
| 933 | 921 | for (segment_ids, segment_vaddrs) |segment_id, segment_vaddr| { |
| 934 | 922 | 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); | |
| 936 | 924 | group_index += 1; |
| 937 | 925 | if (group_index >= f.data_segment_groups.items.len) { |
| 938 | 926 | // All remaining segments are zero. |
| ... | ... | @@ -946,12 +934,10 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 946 | 934 | const group_size = group_end_addr - group_start_addr; |
| 947 | 935 | log.debug("emit data section group, {d} bytes", .{group_size}); |
| 948 | 936 | 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)); | |
| 950 | 938 | // 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); | |
| 955 | 941 | } |
| 956 | 942 | if (segment_id.isEmpty(wasm)) { |
| 957 | 943 | // 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 { |
| 960 | 946 | |
| 961 | 947 | // Padding for alignment. |
| 962 | 948 | 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); | |
| 964 | 950 | segment_offset = needed_offset; |
| 965 | 951 | |
| 966 | const code_start = binary_bytes.items.len; | |
| 952 | const code_start = bw.count; | |
| 967 | 953 | append: { |
| 968 | 954 | const code = switch (segment_id.unpack(wasm)) { |
| 969 | 955 | .__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); | |
| 971 | 957 | break :append; |
| 972 | 958 | }, |
| 973 | 959 | .__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); | |
| 975 | 961 | break :append; |
| 976 | 962 | }, |
| 977 | 963 | .__zig_error_names => { |
| 978 | try binary_bytes.appendSlice(gpa, wasm.error_name_bytes.items); | |
| 964 | try bw.writeAll(wasm.error_name_bytes.items); | |
| 979 | 965 | break :append; |
| 980 | 966 | }, |
| 981 | 967 | .__zig_error_name_table => { |
| 982 | 968 | if (is_obj) @panic("TODO error name table reloc"); |
| 983 | 969 | const base = f.data_segments.get(.__zig_error_names).?; |
| 984 | 970 | 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); | |
| 986 | 972 | } 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); | |
| 988 | 974 | } |
| 989 | 975 | break :append; |
| 990 | 976 | }, |
| 991 | 977 | .__zig_tag_names => { |
| 992 | try binary_bytes.appendSlice(gpa, wasm.tag_name_bytes.items); | |
| 978 | try bw.writeAll(wasm.tag_name_bytes.items); | |
| 993 | 979 | break :append; |
| 994 | 980 | }, |
| 995 | 981 | .__zig_tag_name_table => { |
| 996 | 982 | if (is_obj) @panic("TODO tag name table reloc"); |
| 997 | 983 | const base = f.data_segments.get(.__zig_tag_names).?; |
| 998 | 984 | 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); | |
| 1000 | 986 | } 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); | |
| 1002 | 988 | } |
| 1003 | 989 | break :append; |
| 1004 | 990 | }, |
| 1005 | 991 | .object => |i| { |
| 1006 | 992 | 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); | |
| 1009 | 995 | break :append; |
| 1010 | 996 | }, |
| 1011 | 997 | inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code, |
| 1012 | 998 | }; |
| 1013 | try binary_bytes.appendSlice(gpa, code.slice(wasm)); | |
| 999 | try bw.writeAll(code.slice(wasm)); | |
| 1014 | 1000 | } |
| 1015 | segment_offset += @intCast(binary_bytes.items.len - code_start); | |
| 1001 | segment_offset += @intCast(bw.count - code_start); | |
| 1016 | 1002 | } |
| 1017 | 1003 | |
| 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)); | |
| 1019 | 1005 | data_section_index = section_index; |
| 1020 | 1006 | section_index += 1; |
| 1021 | 1007 | } |
| ... | ... | @@ -1023,7 +1009,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1023 | 1009 | if (is_obj) { |
| 1024 | 1010 | @panic("TODO emit link section for object file and emit modified relocations"); |
| 1025 | 1011 | } 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); | |
| 1027 | 1013 | } |
| 1028 | 1014 | |
| 1029 | 1015 | if (comp.config.debug_format != .strip) { |
| ... | ... | @@ -1033,17 +1019,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1033 | 1019 | .none => {}, |
| 1034 | 1020 | .fast => { |
| 1035 | 1021 | 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, .{}); | |
| 1037 | 1023 | var uuid: [36]u8 = undefined; |
| 1038 | 1024 | _ = try std.fmt.bufPrint(&uuid, "{x}-{x}-{x}-{x}-{x}", .{ |
| 1039 | 1025 | id[0..4], id[4..6], id[6..8], id[8..10], id[10..], |
| 1040 | 1026 | }); |
| 1041 | try emitBuildIdSection(gpa, binary_bytes, &uuid); | |
| 1027 | try emitBuildIdSection(&aw, &uuid); | |
| 1042 | 1028 | }, |
| 1043 | 1029 | .hexstring => |hs| { |
| 1044 | 1030 | var buffer: [32 * 2]u8 = undefined; |
| 1045 | 1031 | const str = std.fmt.bufPrint(&buffer, "{x}", .{hs.toSlice()}) catch unreachable; |
| 1046 | try emitBuildIdSection(gpa, binary_bytes, str); | |
| 1032 | try emitBuildIdSection(&aw, str); | |
| 1047 | 1033 | }, |
| 1048 | 1034 | else => |mode| { |
| 1049 | 1035 | var err = try diags.addErrorWithNotes(0); |
| ... | ... | @@ -1054,14 +1040,15 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1054 | 1040 | var debug_bytes = std.ArrayList(u8).init(gpa); |
| 1055 | 1041 | defer debug_bytes.deinit(); |
| 1056 | 1042 | |
| 1057 | try emitProducerSection(gpa, binary_bytes); | |
| 1058 | try emitFeaturesSection(gpa, binary_bytes, target); | |
| 1043 | try emitProducerSection(&aw); | |
| 1044 | try emitFeaturesSection(&aw, target); | |
| 1059 | 1045 | } |
| 1060 | 1046 | |
| 1061 | 1047 | // Finally, write the entire binary into the file. |
| 1062 | 1048 | 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); | |
| 1065 | 1052 | } |
| 1066 | 1053 | |
| 1067 | 1054 | const VirtualAddrs = struct { |
| ... | ... | @@ -1076,170 +1063,155 @@ const VirtualAddrs = struct { |
| 1076 | 1063 | |
| 1077 | 1064 | fn emitNameSection( |
| 1078 | 1065 | wasm: *Wasm, |
| 1066 | aw: *std.io.AllocatingWriter, | |
| 1079 | 1067 | data_segment_groups: []const DataSegmentGroup, |
| 1080 | binary_bytes: *std.ArrayListUnmanaged(u8), | |
| 1081 | ) !void { | |
| 1068 | ) anyerror!void { | |
| 1082 | 1069 | 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)); | |
| 1085 | 1073 | |
| 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); | |
| 1092 | 1077 | |
| 1093 | 1078 | { |
| 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)); | |
| 1099 | 1081 | |
| 1082 | try bw.writeLeb128(f.function_imports.entries.len + wasm.functions.entries.len); | |
| 1100 | 1083 | for (f.function_imports.keys(), 0..) |name_index, function_index| { |
| 1101 | 1084 | 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); | |
| 1105 | 1088 | } |
| 1106 | 1089 | for (wasm.functions.keys(), f.function_imports.entries.len..) |resolution, function_index| { |
| 1107 | 1090 | 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); | |
| 1111 | 1094 | } |
| 1112 | 1095 | } |
| 1113 | 1096 | |
| 1114 | 1097 | { |
| 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)); | |
| 1120 | 1100 | |
| 1101 | try bw.writeLeb128(f.global_imports.entries.len + wasm.globals.entries.len); | |
| 1121 | 1102 | for (f.global_imports.keys(), 0..) |name_index, global_index| { |
| 1122 | 1103 | 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); | |
| 1126 | 1107 | } |
| 1127 | 1108 | for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| { |
| 1128 | 1109 | 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); | |
| 1132 | 1113 | } |
| 1133 | 1114 | } |
| 1134 | 1115 | |
| 1135 | 1116 | { |
| 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)); | |
| 1138 | 1119 | |
| 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| { | |
| 1143 | 1122 | 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); | |
| 1147 | 1126 | } |
| 1148 | 1127 | } |
| 1149 | 1128 | } |
| 1150 | 1129 | |
| 1151 | fn emitFeaturesSection( | |
| 1152 | gpa: Allocator, | |
| 1153 | binary_bytes: *std.ArrayListUnmanaged(u8), | |
| 1154 | target: *const std.Target, | |
| 1155 | ) Allocator.Error!void { | |
| 1130 | fn emitFeaturesSection(aw: *std.io.AllocatingWriter, target: *const std.Target) anyerror!void { | |
| 1156 | 1131 | const feature_count = target.cpu.features.count(); |
| 1157 | 1132 | if (feature_count == 0) return; |
| 1158 | 1133 | |
| 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)); | |
| 1166 | 1137 | |
| 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); | |
| 1168 | 1141 | |
| 1142 | try bw.writeLeb128(feature_count); | |
| 1169 | 1143 | var safety_count = feature_count; |
| 1170 | 1144 | for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| { |
| 1171 | 1145 | if (!target.cpu.has(.wasm, @as(std.Target.wasm.Feature, @enumFromInt(i)))) continue; |
| 1172 | 1146 | safety_count -= 1; |
| 1173 | 1147 | |
| 1174 | try leb.writeUleb128(writer, @as(u32, '+')); | |
| 1148 | try bw.writeUleb128('+'); | |
| 1175 | 1149 | // Depends on llvm_name for the hyphenated version that matches wasm tooling conventions. |
| 1176 | 1150 | 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); | |
| 1179 | 1153 | } |
| 1180 | 1154 | assert(safety_count == 0); |
| 1181 | 1155 | } |
| 1182 | 1156 | |
| 1183 | fn 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); | |
| 1157 | fn 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)); | |
| 1186 | 1161 | |
| 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); | |
| 1191 | 1165 | |
| 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); | |
| 1195 | 1169 | } |
| 1196 | 1170 | |
| 1197 | fn 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); | |
| 1171 | fn 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)); | |
| 1205 | 1175 | |
| 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); | |
| 1207 | 1179 | |
| 1208 | // language field | |
| 1180 | try bw.writeUleb128(2); // 2 fields: language + processed-by | |
| 1209 | 1181 | { |
| 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); | |
| 1213 | 1185 | |
| 1214 | 1186 | // 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); | |
| 1216 | 1188 | |
| 1217 | 1189 | // versioned name |
| 1218 | 1190 | { |
| 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); | |
| 1221 | 1194 | |
| 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); | |
| 1224 | 1197 | } |
| 1225 | 1198 | } |
| 1226 | ||
| 1227 | // processed-by field | |
| 1228 | 1199 | { |
| 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); | |
| 1232 | 1203 | |
| 1233 | 1204 | // 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); | |
| 1235 | 1206 | |
| 1236 | 1207 | // versioned name |
| 1237 | 1208 | { |
| 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); | |
| 1240 | 1212 | |
| 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); | |
| 1243 | 1215 | } |
| 1244 | 1216 | } |
| 1245 | 1217 | } |
| ... | ... | @@ -1277,170 +1249,133 @@ fn wantSegmentMerge( |
| 1277 | 1249 | } |
| 1278 | 1250 | |
| 1279 | 1251 | /// section id + fixed leb contents size + fixed leb vector length |
| 1280 | const section_header_reserve_size = 1 + 5 + 5; | |
| 1281 | const section_header_size = 5 + 1; | |
| 1252 | const vec_section_header_size = section_header_size + size_header_size; | |
| 1282 | 1253 | |
| 1283 | fn 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); | |
| 1254 | fn 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); | |
| 1286 | 1259 | } |
| 1287 | 1260 | |
| 1288 | 1261 | fn replaceVecSectionHeader( |
| 1289 | bytes: *std.ArrayListUnmanaged(u8), | |
| 1262 | aw: *std.io.AllocatingWriter, | |
| 1290 | 1263 | offset: u32, |
| 1291 | 1264 | section: std.wasm.Section, |
| 1292 | 1265 | n_items: u32, |
| 1293 | 1266 | ) 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); | |
| 1302 | 1271 | } |
| 1303 | 1272 | |
| 1304 | fn 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 | } | |
| 1273 | const section_header_size = 1 + size_header_size; | |
| 1308 | 1274 | |
| 1309 | fn writeCustomSectionHeader(bytes: *std.ArrayListUnmanaged(u8), offset: u32) void { | |
| 1310 | return replaceHeader(bytes, offset, 0); // 0 = 'custom' section | |
| 1275 | fn 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); | |
| 1311 | 1280 | } |
| 1312 | 1281 | |
| 1313 | fn 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()); | |
| 1282 | fn 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)); | |
| 1321 | 1286 | } |
| 1322 | 1287 | |
| 1323 | const max_size_encoding = 5; | |
| 1288 | const size_header_size = 5; | |
| 1324 | 1289 | |
| 1325 | fn 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); | |
| 1290 | fn 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); | |
| 1328 | 1295 | } |
| 1329 | 1296 | |
| 1330 | fn 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()); | |
| 1297 | fn 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)); | |
| 1336 | 1300 | } |
| 1337 | 1301 | |
| 1338 | fn 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); | |
| 1302 | fn 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); | |
| 1346 | 1306 | } |
| 1347 | 1307 | |
| 1348 | 1308 | fn emitMemoryImport( |
| 1349 | 1309 | wasm: *Wasm, |
| 1350 | binary_bytes: *std.ArrayListUnmanaged(u8), | |
| 1310 | bw: *std.io.BufferedWriter, | |
| 1351 | 1311 | name_index: String, |
| 1352 | 1312 | memory_import: *const Wasm.MemoryImport, |
| 1353 | ) Allocator.Error!void { | |
| 1354 | const gpa = wasm.base.comp.gpa; | |
| 1313 | ) anyerror!void { | |
| 1355 | 1314 | 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); | |
| 1358 | 1317 | |
| 1359 | 1318 | 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); | |
| 1362 | 1321 | |
| 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()); | |
| 1365 | 1324 | } |
| 1366 | 1325 | |
| 1367 | pub fn emitInit(writer: anytype, init_expr: std.wasm.InitExpression) !void { | |
| 1326 | pub fn emitInit(bw: *std.io.BufferedWriter, init_expr: std.wasm.InitExpression) anyerror!void { | |
| 1368 | 1327 | 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 | } | |
| 1388 | 1339 | }, |
| 1389 | 1340 | } |
| 1390 | try writer.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1341 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1391 | 1342 | } |
| 1392 | 1343 | |
| 1393 | pub fn emitExpr(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanaged(u8), expr: Wasm.Expr) Allocator.Error!void { | |
| 1394 | const gpa = wasm.base.comp.gpa; | |
| 1344 | pub fn emitExpr(wasm: *const Wasm, bw: *std.io.BufferedWriter, expr: Wasm.Expr) anyerror!void { | |
| 1395 | 1345 | 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 | |
| 1397 | 1347 | } |
| 1398 | 1348 | |
| 1399 | fn 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; | |
| 1349 | fn 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)); | |
| 1404 | 1353 | |
| 1405 | try leb.writeUleb128(writer, @as(u32, @intCast(wasm.segment_info.count()))); | |
| 1354 | try bw.writeLeb128(wasm.segment_info.count()); | |
| 1406 | 1355 | for (wasm.segment_info.values()) |segment_info| { |
| 1407 | 1356 | log.debug("Emit segment: {s} align({d}) flags({b})", .{ |
| 1408 | 1357 | segment_info.name, |
| 1409 | 1358 | segment_info.alignment, |
| 1410 | 1359 | segment_info.flags, |
| 1411 | 1360 | }); |
| 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); | |
| 1416 | 1365 | } |
| 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 | ||
| 1423 | fn uleb128size(x: u32) u32 { | |
| 1424 | var value = x; | |
| 1425 | var size: u32 = 0; | |
| 1426 | while (value != 0) : (size += 1) value >>= 7; | |
| 1427 | return size; | |
| 1428 | 1366 | } |
| 1429 | 1367 | |
| 1430 | 1368 | fn emitTagNameTable( |
| 1431 | gpa: Allocator, | |
| 1432 | code: *std.ArrayListUnmanaged(u8), | |
| 1369 | bw: *std.io.BufferedWriter, | |
| 1433 | 1370 | tag_name_offs: []const u32, |
| 1434 | 1371 | tag_name_bytes: []const u8, |
| 1435 | 1372 | base: u32, |
| 1436 | 1373 | 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 { | |
| 1440 | 1375 | for (tag_name_offs) |off| { |
| 1441 | 1376 | 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); | |
| 1444 | 1379 | } |
| 1445 | 1380 | } |
| 1446 | 1381 | |
| ... | ... | @@ -1525,11 +1460,11 @@ fn reloc_u64_table_index(code: []u8, i: IndirectFunctionTableIndex) void { |
| 1525 | 1460 | } |
| 1526 | 1461 | |
| 1527 | 1462 | fn 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()); | |
| 1529 | 1464 | } |
| 1530 | 1465 | |
| 1531 | 1466 | fn 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()); | |
| 1533 | 1468 | } |
| 1534 | 1469 | |
| 1535 | 1470 | fn reloc_u32_function(code: []u8, function: Wasm.OutputFunctionIndex) void { |
| ... | ... | @@ -1537,7 +1472,7 @@ fn reloc_u32_function(code: []u8, function: Wasm.OutputFunctionIndex) void { |
| 1537 | 1472 | } |
| 1538 | 1473 | |
| 1539 | 1474 | fn 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)); | |
| 1541 | 1476 | } |
| 1542 | 1477 | |
| 1543 | 1478 | fn reloc_u32_global(code: []u8, global: Wasm.GlobalIndex) void { |
| ... | ... | @@ -1545,7 +1480,7 @@ fn reloc_u32_global(code: []u8, global: Wasm.GlobalIndex) void { |
| 1545 | 1480 | } |
| 1546 | 1481 | |
| 1547 | 1482 | fn 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)); | |
| 1549 | 1484 | } |
| 1550 | 1485 | |
| 1551 | 1486 | const RelocAddr = struct { |
| ... | ... | @@ -1581,35 +1516,31 @@ fn reloc_u64_addr(code: []u8, ra: RelocAddr) void { |
| 1581 | 1516 | } |
| 1582 | 1517 | |
| 1583 | 1518 | fn 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); | |
| 1585 | 1520 | } |
| 1586 | 1521 | |
| 1587 | 1522 | fn 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); | |
| 1589 | 1524 | } |
| 1590 | 1525 | |
| 1591 | 1526 | fn 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); | |
| 1593 | 1528 | } |
| 1594 | 1529 | |
| 1595 | 1530 | fn 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); | |
| 1597 | 1532 | } |
| 1598 | 1533 | |
| 1599 | 1534 | fn 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)); | |
| 1601 | 1536 | } |
| 1602 | 1537 | |
| 1603 | 1538 | fn 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)); | |
| 1605 | 1540 | } |
| 1606 | 1541 | |
| 1607 | fn 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 | ||
| 1542 | fn emitCallCtorsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) anyerror!void { | |
| 1543 | try bw.writeUleb128(0); // no locals | |
| 1613 | 1544 | for (wasm.object_init_funcs.items) |init_func| { |
| 1614 | 1545 | const func = init_func.function_index.ptr(wasm); |
| 1615 | 1546 | if (!func.object_index.ptr(wasm).is_included) continue; |
| ... | ... | @@ -1617,25 +1548,18 @@ fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanage |
| 1617 | 1548 | const n_returns = ty.returns.slice(wasm).len; |
| 1618 | 1549 | |
| 1619 | 1550 | // Call function by its function index |
| 1620 | try binary_bytes.ensureUnusedCapacity(gpa, 1 + 5 + n_returns + 1); | |
| 1621 | 1551 | 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)); | |
| 1624 | 1554 | |
| 1625 | 1555 | // 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); | |
| 1627 | 1557 | } |
| 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 | |
| 1630 | 1559 | } |
| 1631 | 1560 | |
| 1632 | fn emitInitMemoryFunction( | |
| 1633 | wasm: *const Wasm, | |
| 1634 | binary_bytes: *std.ArrayListUnmanaged(u8), | |
| 1635 | virtual_addrs: *const VirtualAddrs, | |
| 1636 | ) Allocator.Error!void { | |
| 1561 | fn emitInitMemoryFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter, virtual_addrs: *const VirtualAddrs) anyerror!void { | |
| 1637 | 1562 | const comp = wasm.base.comp; |
| 1638 | const gpa = comp.gpa; | |
| 1639 | 1563 | const shared_memory = comp.config.shared_memory; |
| 1640 | 1564 | |
| 1641 | 1565 | // Passive segments are used to avoid memory being reinitialized on each |
| ... | ... | @@ -1645,39 +1569,40 @@ fn emitInitMemoryFunction( |
| 1645 | 1569 | // function. |
| 1646 | 1570 | assert(wasm.any_passive_inits); |
| 1647 | 1571 | |
| 1648 | try binary_bytes.ensureUnusedCapacity(gpa, 5 + 1); | |
| 1649 | appendReservedUleb32(binary_bytes, 0); // no locals | |
| 1572 | try bw.writeUleb128(0); // no locals | |
| 1650 | 1573 | |
| 1651 | 1574 | if (virtual_addrs.init_memory_flag) |flag_address| { |
| 1652 | 1575 | assert(shared_memory); |
| 1653 | try binary_bytes.ensureUnusedCapacity(gpa, 2 * 3 + 6 * 3 + 1 + 6 * 3 + 1 + 5 * 4 + 1 + 1); | |
| 1654 | 1576 | // destination blocks |
| 1655 | 1577 | // 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 | }); | |
| 1664 | 1586 | |
| 1665 | 1587 | // 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 | |
| 1673 | 1598 | |
| 1674 | 1599 | // 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)); | |
| 1681 | 1606 | } |
| 1682 | 1607 | |
| 1683 | 1608 | const segment_groups = wasm.flush_buffer.data_segment_groups.items; |
| ... | ... | @@ -1690,74 +1615,82 @@ fn emitInitMemoryFunction( |
| 1690 | 1615 | const start_addr: u32 = @intCast(segment.alignment(wasm).forward(prev_end)); |
| 1691 | 1616 | const segment_size: u32 = group.end_addr - start_addr; |
| 1692 | 1617 | |
| 1693 | try binary_bytes.ensureUnusedCapacity(gpa, 6 + 6 + 1 + 5 + 6 + 6 + 1 + 6 * 2 + 1 + 1); | |
| 1694 | ||
| 1695 | 1618 | // For passive BSS segments we can simply issue a memory.fill(0). For |
| 1696 | 1619 | // non-BSS segments we do a memory.init. Both instructions take as |
| 1697 | 1620 | // 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))); | |
| 1699 | 1623 | |
| 1700 | 1624 | if (shared_memory and segment.isTls(wasm)) { |
| 1701 | 1625 | // When we initialize the TLS segment we also set the `__tls_base` |
| 1702 | 1626 | // global. This allows the runtime to use this static copy of the |
| 1703 | 1627 | // 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.?); | |
| 1707 | 1632 | } |
| 1708 | 1633 | |
| 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)); | |
| 1712 | 1639 | if (segment.isBss(wasm)) { |
| 1713 | 1640 | // 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)); | |
| 1715 | 1642 | } else { |
| 1716 | 1643 | // 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); | |
| 1719 | 1646 | } |
| 1720 | binary_bytes.appendAssumeCapacity(0); // memory index immediate | |
| 1647 | try bw.writeByte(0); // memory index immediate | |
| 1721 | 1648 | } |
| 1722 | 1649 | |
| 1723 | 1650 | if (virtual_addrs.init_memory_flag) |flag_address| { |
| 1724 | 1651 | 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 | ||
| 1726 | 1653 | // 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 | |
| 1733 | 1662 | |
| 1734 | 1663 | // 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)); | |
| 1743 | 1674 | |
| 1744 | 1675 | // 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); | |
| 1747 | 1678 | |
| 1748 | 1679 | // 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 | |
| 1761 | 1694 | } |
| 1762 | 1695 | |
| 1763 | 1696 | for (segment_groups, 0..) |group, segment_index| { |
| ... | ... | @@ -1768,26 +1701,20 @@ fn emitInitMemoryFunction( |
| 1768 | 1701 | // during the initialization of each thread (__wasm_init_tls). |
| 1769 | 1702 | if (shared_memory and segment.isTls(wasm)) continue; |
| 1770 | 1703 | |
| 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); | |
| 1776 | 1707 | } |
| 1777 | 1708 | |
| 1778 | 1709 | // End of the function body |
| 1779 | binary_bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); | |
| 1710 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1780 | 1711 | } |
| 1781 | 1712 | |
| 1782 | fn emitInitTlsFunction(wasm: *const Wasm, bytes: *std.ArrayListUnmanaged(u8)) Allocator.Error!void { | |
| 1713 | fn emitInitTlsFunction(wasm: *const Wasm, bw: *std.io.BufferedWriter) anyerror!void { | |
| 1783 | 1714 | const comp = wasm.base.comp; |
| 1784 | const gpa = comp.gpa; | |
| 1785 | ||
| 1786 | 1715 | assert(comp.config.shared_memory); |
| 1787 | 1716 | |
| 1788 | try bytes.ensureUnusedCapacity(gpa, 5 * 10 + 8); | |
| 1789 | ||
| 1790 | appendReservedUleb32(bytes, 0); // no locals | |
| 1717 | try bw.writeUleb128(0); // no locals | |
| 1791 | 1718 | |
| 1792 | 1719 | // If there's a TLS segment, initialize it during runtime using the bulk-memory feature |
| 1793 | 1720 | // 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 |
| 1796 | 1723 | const start_addr = wasm.flush_buffer.data_segments.values()[0]; |
| 1797 | 1724 | const end_addr = wasm.flush_buffer.data_segment_groups.items[0].end_addr; |
| 1798 | 1725 | const group_size = end_addr - start_addr; |
| 1799 | const data_segment_index = 0; | |
| 1726 | const data_segment_index: u32 = 0; | |
| 1800 | 1727 | |
| 1801 | 1728 | const param_local: u32 = 0; |
| 1802 | 1729 | |
| 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); | |
| 1805 | 1732 | |
| 1806 | 1733 | 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)); | |
| 1809 | 1736 | |
| 1810 | 1737 | // load stack values for the bulk-memory operation |
| 1811 | 1738 | { |
| 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); | |
| 1814 | 1741 | |
| 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 | |
| 1817 | 1744 | |
| 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 | |
| 1820 | 1747 | } |
| 1821 | 1748 | |
| 1822 | 1749 | // 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)); | |
| 1825 | 1752 | // 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 | |
| 1829 | 1755 | } |
| 1830 | 1756 | |
| 1831 | 1757 | // 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 |
| 1833 | 1759 | // generated by the linker. |
| 1834 | 1760 | if (wasm.functions.getIndex(.__wasm_apply_global_tls_relocs)) |function_index| { |
| 1835 | 1761 | 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)); | |
| 1838 | 1764 | } |
| 1839 | 1765 | |
| 1840 | bytes.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); | |
| 1766 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1841 | 1767 | } |
| 1842 | 1768 | |
| 1843 | fn 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)); | |
| 1769 | fn 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)); | |
| 1846 | 1772 | } |
| 1847 | 1773 | |
| 1848 | 1774 | fn emitTagNameFunction( |
| 1849 | 1775 | wasm: *Wasm, |
| 1850 | code: *std.ArrayListUnmanaged(u8), | |
| 1776 | bw: *std.io.BufferedWriter, | |
| 1851 | 1777 | table_base_addr: u32, |
| 1852 | 1778 | table_index: u32, |
| 1853 | 1779 | enum_type_ip: InternPool.Index, |
| 1854 | 1780 | ) !void { |
| 1855 | 1781 | const comp = wasm.base.comp; |
| 1856 | const gpa = comp.gpa; | |
| 1857 | 1782 | const diags = &comp.link_diags; |
| 1858 | 1783 | const zcu = comp.zcu.?; |
| 1859 | 1784 | const ip = &zcu.intern_pool; |
| 1860 | 1785 | const enum_type = ip.loadEnumType(enum_type_ip); |
| 1861 | 1786 | const tag_values = enum_type.values.get(ip); |
| 1862 | 1787 | |
| 1863 | try code.ensureUnusedCapacity(gpa, 7 * 5 + 6 + 1 * 6); | |
| 1864 | appendReservedUleb32(code, 0); // no locals | |
| 1788 | try bw.writeUleb128(0); // no locals | |
| 1865 | 1789 | |
| 1866 | const slice_abi_size = 8; | |
| 1867 | const encoded_alignment = @ctz(@as(u32, 4)); | |
| 1790 | const slice_abi_size: u32 = 8; | |
| 1868 | 1791 | if (tag_values.len == 0) { |
| 1869 | 1792 | // 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); | |
| 1872 | 1795 | |
| 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); | |
| 1875 | 1798 | |
| 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 | } | |
| 1878 | 1807 | |
| 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); | |
| 1882 | 1811 | |
| 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); | |
| 1886 | 1815 | } else { |
| 1887 | 1816 | const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu); |
| 1888 | 1817 | const outer_block_type: std.wasm.BlockType = switch (int_info.bits) { |
| ... | ... | @@ -1891,94 +1820,80 @@ fn emitTagNameFunction( |
| 1891 | 1820 | else => return diags.fail("wasm linker does not yet implement @tagName for sparse enums with more than 64 bit integer tag types", .{}), |
| 1892 | 1821 | }; |
| 1893 | 1822 | |
| 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); | |
| 1896 | 1825 | |
| 1897 | 1826 | // 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)); | |
| 1900 | 1829 | |
| 1901 | 1830 | for (tag_values, 0..) |tag_value, tag_index| { |
| 1902 | 1831 | // 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)); | |
| 1905 | 1834 | |
| 1906 | 1835 | // 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); | |
| 1909 | 1838 | |
| 1910 | 1839 | const val: Zcu.Value = .fromInterned(tag_value); |
| 1911 | 1840 | switch (outer_block_type) { |
| 1912 | 1841 | .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)); | |
| 1919 | 1848 | }, |
| 1920 | 1849 | .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)); | |
| 1927 | 1856 | }, |
| 1928 | 1857 | else => unreachable, |
| 1929 | 1858 | } |
| 1930 | 1859 | |
| 1931 | 1860 | // 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); | |
| 1934 | 1863 | |
| 1935 | 1864 | // 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))))); | |
| 1937 | 1867 | |
| 1938 | 1868 | // 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); | |
| 1941 | 1871 | |
| 1942 | 1872 | // end the block for this case |
| 1943 | code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.end)); | |
| 1873 | try bw.writeByte(@intFromEnum(std.wasm.Opcode.end)); | |
| 1944 | 1874 | } |
| 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)); | |
| 1947 | 1877 | |
| 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); | |
| 1951 | 1881 | |
| 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); | |
| 1955 | 1885 | } |
| 1956 | 1886 | |
| 1957 | 1887 | // 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. | |
| 1962 | fn 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. | |
| 1968 | fn 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 | ||
| 1973 | fn 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)); | |
| 1975 | 1889 | } |
| 1976 | 1890 | |
| 1977 | fn 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)); | |
| 1891 | fn 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)); | |
| 1984 | 1899 | } |
src/link/Wasm/Object.zig+263-323| ... | ... | @@ -252,7 +252,7 @@ pub const ScratchSpace = struct { |
| 252 | 252 | |
| 253 | 253 | pub fn parse( |
| 254 | 254 | wasm: *Wasm, |
| 255 | bytes: []const u8, | |
| 255 | br: *std.io.BufferedReader, | |
| 256 | 256 | path: Path, |
| 257 | 257 | archive_member_name: ?[]const u8, |
| 258 | 258 | host_name: Wasm.OptionalString, |
| ... | ... | @@ -264,13 +264,9 @@ pub fn parse( |
| 264 | 264 | const gpa = comp.gpa; |
| 265 | 265 | const diags = &comp.link_diags; |
| 266 | 266 | |
| 267 | var pos: usize = 0; | |
| 267 | if (!std.mem.eql(u8, try br.takeArray(std.wasm.magic.len), &std.wasm.magic)) return error.BadObjectMagic; | |
| 268 | 268 | |
| 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); | |
| 274 | 270 | |
| 275 | 271 | const data_segment_start: u32 = @intCast(wasm.object_data_segments.items.len); |
| 276 | 272 | const custom_segment_start: u32 = @intCast(wasm.object_custom_segments.entries.len); |
| ... | ... | @@ -298,200 +294,187 @@ pub fn parse( |
| 298 | 294 | var code_section_index: ?Wasm.ObjectSectionIndex = null; |
| 299 | 295 | var global_section_index: ?Wasm.ObjectSectionIndex = null; |
| 300 | 296 | 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) { | |
| 302 | 298 | const section_index: Wasm.ObjectSectionIndex = @enumFromInt(wasm.object_total_sections); |
| 303 | 299 | |
| 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; | |
| 309 | 302 | switch (section_tag) { |
| 310 | 303 | .custom => { |
| 311 | const section_name, pos = readBytes(bytes, pos); | |
| 304 | const section_name = try br.take(try br.takeLeb128(u32)); | |
| 312 | 305 | if (std.mem.eql(u8, section_name, "linking")) { |
| 313 | 306 | saw_linking_section = true; |
| 314 | const section_version, pos = readLeb(u32, bytes, pos); | |
| 307 | const section_version = try br.takeLeb128(u32); | |
| 315 | 308 | log.debug("link meta data version: {d}", .{section_version}); |
| 316 | 309 | 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); | |
| 321 | 314 | if (payload_len == 0) break; |
| 322 | 315 | |
| 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 | }; | |
| 348 | 337 | }, |
| 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 | }); | |
| 369 | 352 | } |
| 353 | func.* = .{ | |
| 354 | .priority = priority, | |
| 355 | .function_index = sym.pointee.function, | |
| 356 | }; | |
| 370 | 357 | }, |
| 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 | }); | |
| 396 | 373 | } |
| 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 | }; | |
| 397 | 382 | }, |
| 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(); | |
| 416 | 430 | } 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(); | |
| 430 | 432 | } |
| 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)); | |
| 452 | 446 | 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 | } | |
| 466 | 447 | } 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(); | |
| 470 | 449 | } |
| 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)); | |
| 487 | 464 | symbol.name = (try wasm.internString(name)).toOptional(); |
| 465 | } else { | |
| 466 | symbol.name = table_import.ptr(ss).name.toOptional(); | |
| 488 | 467 | } |
| 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 | }, | |
| 495 | 478 | } |
| 496 | 479 | }, |
| 497 | 480 | } |
| ... | ... | @@ -504,8 +487,8 @@ pub fn parse( |
| 504 | 487 | // which section they apply to, and must be sequenced in |
| 505 | 488 | // the module after that section." |
| 506 | 489 | // "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); | |
| 509 | 492 | const section: Wasm.ObjectSectionIndex = @enumFromInt(local_section_index_base + local_section); |
| 510 | 493 | |
| 511 | 494 | log.debug("found {d} relocations for section={d}", .{ count, section }); |
| ... | ... | @@ -513,10 +496,9 @@ pub fn parse( |
| 513 | 496 | var prev_offset: u32 = 0; |
| 514 | 497 | try wasm.object_relocations.ensureUnusedCapacity(gpa, count); |
| 515 | 498 | 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); | |
| 520 | 502 | |
| 521 | 503 | if (offset < prev_offset) |
| 522 | 504 | return diags.failParse(path, "relocation entries not sorted by offset", .{}); |
| ... | ... | @@ -537,7 +519,7 @@ pub fn parse( |
| 537 | 519 | .memory_addr_locrel_i32, |
| 538 | 520 | .memory_addr_tls_sleb64, |
| 539 | 521 | => { |
| 540 | const addend: i32, pos = readLeb(i32, bytes, pos); | |
| 522 | const addend = try br.takeLeb128(i32); | |
| 541 | 523 | wasm.object_relocations.appendAssumeCapacity(switch (sym.pointee) { |
| 542 | 524 | .data => |data| .{ |
| 543 | 525 | .tag = .fromType(tag), |
| ... | ... | @@ -555,7 +537,7 @@ pub fn parse( |
| 555 | 537 | }); |
| 556 | 538 | }, |
| 557 | 539 | .function_offset_i32, .function_offset_i64 => { |
| 558 | const addend: i32, pos = readLeb(i32, bytes, pos); | |
| 540 | const addend = try br.takeLeb128(i32); | |
| 559 | 541 | wasm.object_relocations.appendAssumeCapacity(switch (sym.pointee) { |
| 560 | 542 | .function => .{ |
| 561 | 543 | .tag = .fromType(tag), |
| ... | ... | @@ -573,7 +555,7 @@ pub fn parse( |
| 573 | 555 | }); |
| 574 | 556 | }, |
| 575 | 557 | .section_offset_i32 => { |
| 576 | const addend: i32, pos = readLeb(i32, bytes, pos); | |
| 558 | const addend = try br.takeLeb128(i32); | |
| 577 | 559 | wasm.object_relocations.appendAssumeCapacity(.{ |
| 578 | 560 | .tag = .section_offset_i32, |
| 579 | 561 | .offset = offset, |
| ... | ... | @@ -658,10 +640,9 @@ pub fn parse( |
| 658 | 640 | .len = count, |
| 659 | 641 | }); |
| 660 | 642 | } 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); | |
| 662 | 644 | } 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); | |
| 665 | 646 | |
| 666 | 647 | const data_off: u32 = @intCast(wasm.string_bytes.items.len); |
| 667 | 648 | try wasm.string_bytes.appendSlice(gpa, debug_content); |
| ... | ... | @@ -669,23 +650,20 @@ pub fn parse( |
| 669 | 650 | try wasm.object_custom_segments.put(gpa, section_index, .{ |
| 670 | 651 | .payload = .{ |
| 671 | 652 | .off = @enumFromInt(data_off), |
| 672 | .len = @intCast(debug_content.len), | |
| 653 | .len = @intCast(len), | |
| 673 | 654 | }, |
| 674 | 655 | .flags = .{}, |
| 675 | 656 | .section_name = try wasm.internString(section_name), |
| 676 | 657 | }); |
| 677 | } else { | |
| 678 | pos = section_end; | |
| 679 | } | |
| 658 | } else br.seek = section_end; | |
| 680 | 659 | }, |
| 681 | 660 | .type => { |
| 682 | const func_types_len, pos = readLeb(u32, bytes, pos); | |
| 661 | const func_types_len = try br.takeLeb128(u32); | |
| 683 | 662 | 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; | |
| 686 | 664 | |
| 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)); | |
| 689 | 667 | func_type.* = try wasm.addFuncType(.{ |
| 690 | 668 | .params = .fromString(try wasm.internString(params)), |
| 691 | 669 | .returns = .fromString(try wasm.internString(returns)), |
| ... | ... | @@ -693,16 +671,16 @@ pub fn parse( |
| 693 | 671 | } |
| 694 | 672 | }, |
| 695 | 673 | .import => { |
| 696 | const imports_len, pos = readLeb(u32, bytes, pos); | |
| 674 | const imports_len = try br.takeLeb128(u32); | |
| 697 | 675 | 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); | |
| 701 | 679 | const interned_module_name = try wasm.internString(module_name); |
| 702 | 680 | const interned_name = try wasm.internString(name); |
| 703 | 681 | switch (kind) { |
| 704 | 682 | .function => { |
| 705 | const function, pos = readLeb(u32, bytes, pos); | |
| 683 | const function = try br.takeLeb128(u32); | |
| 706 | 684 | try ss.func_imports.append(gpa, .{ |
| 707 | 685 | .module_name = interned_module_name, |
| 708 | 686 | .name = interned_name, |
| ... | ... | @@ -710,7 +688,7 @@ pub fn parse( |
| 710 | 688 | }); |
| 711 | 689 | }, |
| 712 | 690 | .memory => { |
| 713 | const limits, pos = readLimits(bytes, pos); | |
| 691 | const limits = try readLimits(br); | |
| 714 | 692 | const gop = try wasm.object_memory_imports.getOrPut(gpa, interned_name); |
| 715 | 693 | if (gop.found_existing) { |
| 716 | 694 | if (gop.value_ptr.module_name != interned_module_name) { |
| ... | ... | @@ -736,9 +714,12 @@ pub fn parse( |
| 736 | 714 | } |
| 737 | 715 | }, |
| 738 | 716 | .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 | }; | |
| 742 | 723 | try ss.global_imports.append(gpa, .{ |
| 743 | 724 | .name = interned_name, |
| 744 | 725 | .valtype = valtype, |
| ... | ... | @@ -747,8 +728,8 @@ pub fn parse( |
| 747 | 728 | }); |
| 748 | 729 | }, |
| 749 | 730 | .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); | |
| 752 | 733 | try ss.table_imports.append(gpa, .{ |
| 753 | 734 | .name = interned_name, |
| 754 | 735 | .module_name = interned_module_name, |
| ... | ... | @@ -763,17 +744,16 @@ pub fn parse( |
| 763 | 744 | } |
| 764 | 745 | }, |
| 765 | 746 | .function => { |
| 766 | const functions_len, pos = readLeb(u32, bytes, pos); | |
| 747 | const functions_len = try br.takeLeb128(u32); | |
| 767 | 748 | 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)); | |
| 770 | 750 | } |
| 771 | 751 | }, |
| 772 | 752 | .table => { |
| 773 | const tables_len, pos = readLeb(u32, bytes, pos); | |
| 753 | const tables_len = try br.takeLeb128(u32); | |
| 774 | 754 | 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); | |
| 777 | 757 | table.* = .{ |
| 778 | 758 | .name = .none, |
| 779 | 759 | .module_name = .none, |
| ... | ... | @@ -788,9 +768,9 @@ pub fn parse( |
| 788 | 768 | } |
| 789 | 769 | }, |
| 790 | 770 | .memory => { |
| 791 | const memories_len, pos = readLeb(u32, bytes, pos); | |
| 771 | const memories_len = try br.takeLeb128(u32); | |
| 792 | 772 | for (try wasm.object_memories.addManyAsSlice(gpa, memories_len)) |*memory| { |
| 793 | const limits, pos = readLimits(bytes, pos); | |
| 773 | const limits = try readLimits(br); | |
| 794 | 774 | memory.* = .{ |
| 795 | 775 | .name = .none, |
| 796 | 776 | .flags = .{ |
| ... | ... | @@ -807,14 +787,17 @@ pub fn parse( |
| 807 | 787 | return diags.failParse(path, "object has more than one global section", .{}); |
| 808 | 788 | global_section_index = section_index; |
| 809 | 789 | |
| 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); | |
| 812 | 792 | 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); | |
| 818 | 801 | global.* = .{ |
| 819 | 802 | .name = .none, |
| 820 | 803 | .flags = .{ |
| ... | ... | @@ -826,20 +809,19 @@ pub fn parse( |
| 826 | 809 | .expr = expr, |
| 827 | 810 | .object_index = object_index, |
| 828 | 811 | .offset = @intCast(init_start - section_start), |
| 829 | .size = @intCast(pos - init_start), | |
| 812 | .size = @intCast(br.seek - init_start), | |
| 830 | 813 | }; |
| 831 | 814 | } |
| 832 | 815 | }, |
| 833 | 816 | .@"export" => { |
| 834 | const exports_len, pos = readLeb(u32, bytes, pos); | |
| 817 | const exports_len = try br.takeLeb128(u32); | |
| 835 | 818 | // Read into scratch space, and then later add this data as if |
| 836 | 819 | // it were extra symbol table entries, but allow merging with |
| 837 | 820 | // existing symbol table data if the name matches. |
| 838 | 821 | 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); | |
| 843 | 825 | exp.* = .{ |
| 844 | 826 | .name = try wasm.internString(name), |
| 845 | 827 | .pointee = switch (kind) { |
| ... | ... | @@ -852,25 +834,24 @@ pub fn parse( |
| 852 | 834 | } |
| 853 | 835 | }, |
| 854 | 836 | .start => { |
| 855 | const index, pos = readLeb(u32, bytes, pos); | |
| 837 | const index = try br.takeLeb128(u32); | |
| 856 | 838 | start_function = @enumFromInt(functions_start + index); |
| 857 | 839 | }, |
| 858 | 840 | .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; | |
| 861 | 843 | }, |
| 862 | 844 | .code => { |
| 863 | 845 | if (code_section_index != null) |
| 864 | 846 | return diags.failParse(path, "object has more than one code section", .{}); |
| 865 | 847 | code_section_index = section_index; |
| 866 | 848 | |
| 867 | const start = pos; | |
| 868 | const count, pos = readLeb(u32, bytes, pos); | |
| 849 | const start = br.seek; | |
| 850 | const count = try br.takeLeb128(u32); | |
| 869 | 851 | 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)); | |
| 874 | 855 | elem.* = .{ |
| 875 | 856 | .flags = .{}, // populated from symbol table |
| 876 | 857 | .name = .none, // populated from symbol table |
| ... | ... | @@ -886,20 +867,19 @@ pub fn parse( |
| 886 | 867 | return diags.failParse(path, "object has more than one data section", .{}); |
| 887 | 868 | data_section_index = section_index; |
| 888 | 869 | |
| 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); | |
| 891 | 872 | 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)); | |
| 893 | 874 | if (flags == .active_memidx) { |
| 894 | const memidx, pos = readLeb(u32, bytes, pos); | |
| 875 | const memidx = try br.takeLeb128(u32); | |
| 895 | 876 | if (memidx != 0) return diags.failParse(path, "data section uses mem index {d}", .{memidx}); |
| 896 | 877 | } |
| 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)); | |
| 903 | 883 | elem.* = .{ |
| 904 | 884 | .payload = payload, |
| 905 | 885 | .name = .none, // Populated from segment_info |
| ... | ... | @@ -911,10 +891,10 @@ pub fn parse( |
| 911 | 891 | }; |
| 912 | 892 | } |
| 913 | 893 | }, |
| 914 | else => pos = section_end, | |
| 894 | else => br.seek = section_end, | |
| 915 | 895 | } |
| 916 | if (pos != section_end) return error.MalformedSection; | |
| 917 | } | |
| 896 | if (br.seek != section_end) return error.MalformedSection; | |
| 897 | } else |_| {} | |
| 918 | 898 | if (!saw_linking_section) return error.MissingLinkingSection; |
| 919 | 899 | |
| 920 | 900 | const cpu = comp.root_mod.resolved_target.result.cpu; |
| ... | ... | @@ -984,10 +964,10 @@ pub fn parse( |
| 984 | 964 | if (gop.value_ptr.type != fn_ty_index) { |
| 985 | 965 | var err = try diags.addErrorWithNotes(2); |
| 986 | 966 | 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", .{ | |
| 988 | 968 | gop.value_ptr.type.fmt(wasm), |
| 989 | 969 | }); |
| 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)}); | |
| 991 | 971 | continue; |
| 992 | 972 | } |
| 993 | 973 | if (gop.value_ptr.module_name != ptr.module_name.toOptional()) { |
| ... | ... | @@ -1155,11 +1135,11 @@ pub fn parse( |
| 1155 | 1135 | if (gop.value_ptr.type != ptr.type_index) { |
| 1156 | 1136 | var err = try diags.addErrorWithNotes(2); |
| 1157 | 1137 | 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", .{ | |
| 1159 | 1139 | ptr.type_index.fmt(wasm), |
| 1160 | 1140 | }); |
| 1161 | 1141 | 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) }); | |
| 1163 | 1143 | continue; |
| 1164 | 1144 | } |
| 1165 | 1145 | if (gop.value_ptr.resolution == .unresolved or gop.value_ptr.flags.binding == .weak) { |
| ... | ... | @@ -1176,8 +1156,8 @@ pub fn parse( |
| 1176 | 1156 | } |
| 1177 | 1157 | var err = try diags.addErrorWithNotes(2); |
| 1178 | 1158 | 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)}); | |
| 1181 | 1161 | continue; |
| 1182 | 1162 | } else { |
| 1183 | 1163 | gop.value_ptr.* = .{ |
| ... | ... | @@ -1422,27 +1402,21 @@ pub fn parse( |
| 1422 | 1402 | /// Based on the "features" custom section, parses it into a list of |
| 1423 | 1403 | /// features that tell the linker what features were enabled and may be mandatory |
| 1424 | 1404 | /// to be able to link. |
| 1425 | fn parseFeatures( | |
| 1426 | wasm: *Wasm, | |
| 1427 | bytes: []const u8, | |
| 1428 | start_pos: usize, | |
| 1429 | path: Path, | |
| 1430 | ) error{ OutOfMemory, LinkFailure }!struct { Wasm.Feature.Set, usize } { | |
| 1405 | fn parseFeatures(wasm: *Wasm, br: *std.io.BufferedReader, path: Path) anyerror!Wasm.Feature.Set { | |
| 1431 | 1406 | const gpa = wasm.base.comp.gpa; |
| 1432 | 1407 | 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); | |
| 1434 | 1409 | // This temporary allocation could be avoided by using the string_bytes buffer as a scratch space. |
| 1435 | 1410 | const feature_buffer = try gpa.alloc(Wasm.Feature, features_len); |
| 1436 | 1411 | defer gpa.free(feature_buffer); |
| 1437 | 1412 | for (feature_buffer) |*feature| { |
| 1438 | const prefix: Wasm.Feature.Prefix = switch (bytes[pos]) { | |
| 1413 | const prefix: Wasm.Feature.Prefix = switch (try br.takeByte()) { | |
| 1439 | 1414 | '-' => .@"-", |
| 1440 | 1415 | '+' => .@"+", |
| 1441 | 1416 | '=' => .@"=", |
| 1442 | 1417 | else => |b| return diags.failParse(path, "invalid feature prefix: 0x{x}", .{b}), |
| 1443 | 1418 | }; |
| 1444 | pos += 1; | |
| 1445 | const name, pos = readBytes(bytes, pos); | |
| 1419 | const name = try br.take(try br.takeLeb128(u32)); | |
| 1446 | 1420 | const tag = std.meta.stringToEnum(Wasm.Feature.Tag, name) orelse { |
| 1447 | 1421 | return diags.failParse(path, "unrecognized wasm feature in object: {s}", .{name}); |
| 1448 | 1422 | }; |
| ... | ... | @@ -1453,68 +1427,34 @@ fn parseFeatures( |
| 1453 | 1427 | } |
| 1454 | 1428 | std.mem.sortUnstable(Wasm.Feature, feature_buffer, {}, Wasm.Feature.lessThan); |
| 1455 | 1429 | |
| 1456 | return .{ | |
| 1457 | .fromString(try wasm.internString(@ptrCast(feature_buffer))), | |
| 1458 | pos, | |
| 1459 | }; | |
| 1430 | return .fromString(try wasm.internString(@ptrCast(feature_buffer))); | |
| 1460 | 1431 | } |
| 1461 | 1432 | |
| 1462 | fn readLeb(comptime T: type, bytes: []const u8, pos: usize) struct { T, usize } { | |
| 1463 | var fbr: std.io.FixedBufferStream = .{ .buffer = bytes[pos..] }; | |
| 1433 | fn 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; | |
| 1464 | 1437 | 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 | ||
| 1473 | fn 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 | ||
| 1481 | fn 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 | ||
| 1487 | fn 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 .{ .{ | |
| 1492 | 1438 | .flags = flags, |
| 1493 | 1439 | .min = min, |
| 1494 | 1440 | .max = max, |
| 1495 | }, end_pos }; | |
| 1441 | }; | |
| 1496 | 1442 | } |
| 1497 | 1443 | |
| 1498 | fn 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 }; | |
| 1444 | fn 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]); | |
| 1501 | 1448 | } |
| 1502 | 1449 | |
| 1503 | pub 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], | |
| 1450 | pub 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), | |
| 1511 | 1457 | else => return error.InvalidInitOpcode, |
| 1512 | }; | |
| 1513 | } | |
| 1514 | ||
| 1515 | fn 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; | |
| 1520 | 1460 | } |
src/link/aarch64.zig+3-3| ... | ... | @@ -4,7 +4,7 @@ pub inline fn isArithmeticOp(inst: *const [4]u8) bool { |
| 4 | 4 | } |
| 5 | 5 | |
| 6 | 6 | pub fn writeAddImmInst(value: u12, code: *[4]u8) void { |
| 7 | var inst = Instruction{ | |
| 7 | var inst: Instruction = .{ | |
| 8 | 8 | .add_subtract_immediate = mem.bytesToValue(@FieldType( |
| 9 | 9 | Instruction, |
| 10 | 10 | @tagName(Instruction.add_subtract_immediate), |
| ... | ... | @@ -33,7 +33,7 @@ pub fn calcNumberOfPages(saddr: i64, taddr: i64) error{Overflow}!i21 { |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | pub fn writeAdrpInst(pages: u21, code: *[4]u8) void { |
| 36 | var inst = Instruction{ | |
| 36 | var inst: Instruction = .{ | |
| 37 | 37 | .pc_relative_address = mem.bytesToValue(@FieldType( |
| 38 | 38 | Instruction, |
| 39 | 39 | @tagName(Instruction.pc_relative_address), |
| ... | ... | @@ -45,7 +45,7 @@ pub fn writeAdrpInst(pages: u21, code: *[4]u8) void { |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | pub fn writeBranchImm(disp: i28, code: *[4]u8) void { |
| 48 | var inst = Instruction{ | |
| 48 | var inst: Instruction = .{ | |
| 49 | 49 | .unconditional_branch_immediate = mem.bytesToValue(@FieldType( |
| 50 | 50 | Instruction, |
| 51 | 51 | @tagName(Instruction.unconditional_branch_immediate), |
src/link/riscv.zig+22-24| ... | ... | @@ -1,52 +1,50 @@ |
| 1 | pub fn writeSetSub6(comptime op: enum { set, sub }, code: *[1]u8, addend: anytype) void { | |
| 1 | pub fn writeSetSub6(comptime op: enum { set, sub }, addend: anytype, bw: *std.io.BufferedWriter) anyerror!void { | |
| 2 | 2 | const mask: u8 = 0b11_000000; |
| 3 | 3 | 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); | |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | pub fn writeSetSubUleb(comptime op: enum { set, sub }, stream: *std.io.FixedBufferStream([]u8), addend: i64) !void { | |
| 12 | pub fn writeSetSubUleb(comptime op: enum { set, sub }, addend: i64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 13 | 13 | switch (op) { |
| 14 | .set => try overwriteUleb(stream, @intCast(addend)), | |
| 14 | .set => try overwriteUleb(@intCast(addend), bw), | |
| 15 | 15 | .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); | |
| 20 | 20 | }, |
| 21 | 21 | } |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | fn overwriteUleb(stream: *std.io.FixedBufferStream([]u8), addend: u64) !void { | |
| 25 | var value: u64 = addend; | |
| 26 | const writer = stream.writer(); | |
| 27 | ||
| 24 | fn overwriteUleb(new_value: u64, bw: *std.io.BufferedWriter) anyerror!void { | |
| 25 | var value: u64 = new_value; | |
| 28 | 26 | 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))); | |
| 30 | 29 | if (byte & 0x80 == 0) break; |
| 31 | try writer.writeByte(0x80 | @as(u8, @truncate(value & 0x7f))); | |
| 32 | 30 | value >>= 7; |
| 33 | 31 | } |
| 34 | stream.buffer[stream.pos] = @truncate(value & 0x7f); | |
| 35 | 32 | } |
| 36 | 33 | |
| 37 | 34 | pub fn writeAddend( |
| 38 | 35 | comptime Int: type, |
| 39 | 36 | comptime op: enum { add, sub }, |
| 40 | code: *[@typeInfo(Int).int.bits / 8]u8, | |
| 41 | 37 | 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); | |
| 44 | 42 | const addend: Int = @truncate(value); |
| 45 | 43 | switch (op) { |
| 46 | 44 | .add => V +|= addend, // TODO: I think saturating arithmetic is correct here |
| 47 | 45 | .sub => V -|= addend, |
| 48 | 46 | } |
| 49 | mem.writeInt(Int, code, V, .little); | |
| 47 | try bw.writeInt(Int, V, .little); | |
| 50 | 48 | } |
| 51 | 49 | |
| 52 | 50 | pub 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 { |
| 39 | 39 | return self.entries.items.len; |
| 40 | 40 | } |
| 41 | 41 | |
| 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 { | |
| 49 | 43 | comptime assert(unused_format_string.len == 0); |
| 50 | try writer.writeAll("TableSection:\n"); | |
| 44 | try bw.writeAll("TableSection:\n"); | |
| 51 | 45 | for (self.entries.items, 0..) |entry, i| { |
| 52 | try writer.print(" {d} => {}\n", .{ i, entry }); | |
| 46 | try bw.print(" {d} => {}\n", .{ i, entry }); | |
| 53 | 47 | } |
| 54 | 48 | } |
| 55 | 49 |
src/main.zig+43-64| ... | ... | @@ -66,7 +66,7 @@ pub fn wasi_cwd() std.os.wasi.fd_t { |
| 66 | 66 | const fatal = std.process.fatal; |
| 67 | 67 | |
| 68 | 68 | /// This can be global since stdout is a singleton. |
| 69 | var stdout_buffer: [4096]u8 = undefined; | |
| 69 | var stdio_buffer: [4096]u8 = undefined; | |
| 70 | 70 | |
| 71 | 71 | /// Shaming all the locations that inappropriately use an O(N) search algorithm. |
| 72 | 72 | /// Please delete this and fix the compilation errors! |
| ... | ... | @@ -5477,7 +5477,7 @@ fn jitCmd( |
| 5477 | 5477 | defer comp.destroy(); |
| 5478 | 5478 | |
| 5479 | 5479 | if (options.server) { |
| 5480 | var server = std.zig.Server{ | |
| 5480 | var server: std.zig.Server = .{ | |
| 5481 | 5481 | .out = fs.File.stdout(), |
| 5482 | 5482 | .in = undefined, // won't be receiving messages |
| 5483 | 5483 | .receive_fifo = undefined, // won't be receiving messages |
| ... | ... | @@ -5672,7 +5672,7 @@ const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, |
| 5672 | 5672 | /// Initialize the arguments from a Response File. "*.rsp" |
| 5673 | 5673 | fn initArgIteratorResponseFile(allocator: Allocator, resp_file_path: []const u8) !ArgIteratorResponseFile { |
| 5674 | 5674 | 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)); | |
| 5676 | 5676 | errdefer allocator.free(cmd_line); |
| 5677 | 5677 | |
| 5678 | 5678 | return ArgIteratorResponseFile.initTakeOwnership(allocator, cmd_line); |
| ... | ... | @@ -6061,11 +6061,7 @@ fn cmdAstCheck( |
| 6061 | 6061 | |
| 6062 | 6062 | const tree = try Ast.parse(arena, source, mode); |
| 6063 | 6063 | |
| 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); | |
| 6069 | 6065 | switch (mode) { |
| 6070 | 6066 | .zig => { |
| 6071 | 6067 | const zir = try AstGen.generate(arena, tree); |
| ... | ... | @@ -6109,7 +6105,7 @@ fn cmdAstCheck( |
| 6109 | 6105 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + |
| 6110 | 6106 | zir.string_bytes.len * @sizeOf(u8); |
| 6111 | 6107 | // zig fmt: off |
| 6112 | try bw.print( | |
| 6108 | try stdout_bw.print( | |
| 6113 | 6109 | \\# Source bytes: {Bi} |
| 6114 | 6110 | \\# Tokens: {} ({Bi}) |
| 6115 | 6111 | \\# AST Nodes: {} ({Bi}) |
| ... | ... | @@ -6130,8 +6126,8 @@ fn cmdAstCheck( |
| 6130 | 6126 | // zig fmt: on |
| 6131 | 6127 | } |
| 6132 | 6128 | |
| 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(); | |
| 6135 | 6131 | |
| 6136 | 6132 | if (zir.hasCompileErrors()) { |
| 6137 | 6133 | process.exit(1); |
| ... | ... | @@ -6158,8 +6154,8 @@ fn cmdAstCheck( |
| 6158 | 6154 | fatal("-t option only available in builds of zig with debug extensions", .{}); |
| 6159 | 6155 | } |
| 6160 | 6156 | |
| 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(); | |
| 6163 | 6159 | return cleanExit(); |
| 6164 | 6160 | }, |
| 6165 | 6161 | } |
| ... | ... | @@ -6187,8 +6183,7 @@ fn cmdDetectCpu(args: []const []const u8) !void { |
| 6187 | 6183 | const arg = args[i]; |
| 6188 | 6184 | if (mem.startsWith(u8, arg, "-")) { |
| 6189 | 6185 | 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); | |
| 6192 | 6187 | return cleanExit(); |
| 6193 | 6188 | } else if (mem.eql(u8, arg, "--llvm")) { |
| 6194 | 6189 | use_llvm = true; |
| ... | ... | @@ -6280,13 +6275,10 @@ fn detectNativeCpuWithLLVM( |
| 6280 | 6275 | } |
| 6281 | 6276 | |
| 6282 | 6277 | fn 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); | |
| 6287 | 6279 | |
| 6288 | 6280 | if (cpu.model.llvm_name) |llvm_name| { |
| 6289 | try bw.print("{s}\n", .{llvm_name}); | |
| 6281 | try stdout_bw.print("{s}\n", .{llvm_name}); | |
| 6290 | 6282 | } |
| 6291 | 6283 | |
| 6292 | 6284 | const all_features = cpu.arch.allFeaturesList(); |
| ... | ... | @@ -6295,10 +6287,10 @@ fn printCpu(cpu: std.Target.Cpu) !void { |
| 6295 | 6287 | const index: std.Target.Cpu.Feature.Set.Index = @intCast(index_usize); |
| 6296 | 6288 | const is_enabled = cpu.features.isEnabled(index); |
| 6297 | 6289 | 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 }); | |
| 6299 | 6291 | } |
| 6300 | 6292 | |
| 6301 | try bw.flush(); | |
| 6293 | try stdout_bw.flush(); | |
| 6302 | 6294 | } |
| 6303 | 6295 | |
| 6304 | 6296 | fn cmdDumpLlvmInts( |
| ... | ... | @@ -6331,16 +6323,13 @@ fn cmdDumpLlvmInts( |
| 6331 | 6323 | const dl = tm.createTargetDataLayout(); |
| 6332 | 6324 | const context = llvm.Context.create(); |
| 6333 | 6325 | |
| 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); | |
| 6337 | 6327 | for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| { |
| 6338 | 6328 | const int_type = context.intType(bits); |
| 6339 | 6329 | 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 }); | |
| 6341 | 6331 | } |
| 6342 | ||
| 6343 | try bw.flush(); | |
| 6332 | try stdout_bw.flush(); | |
| 6344 | 6333 | |
| 6345 | 6334 | return cleanExit(); |
| 6346 | 6335 | } |
| ... | ... | @@ -6363,11 +6352,7 @@ fn cmdDumpZir( |
| 6363 | 6352 | |
| 6364 | 6353 | const zir = try Zcu.loadZirCache(arena, f); |
| 6365 | 6354 | |
| 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); | |
| 6371 | 6356 | { |
| 6372 | 6357 | const instruction_bytes = zir.instructions.len * |
| 6373 | 6358 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| ... | ... | @@ -6377,7 +6362,7 @@ fn cmdDumpZir( |
| 6377 | 6362 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + |
| 6378 | 6363 | zir.string_bytes.len * @sizeOf(u8); |
| 6379 | 6364 | // zig fmt: off |
| 6380 | try bw.print( | |
| 6365 | try stdout_bw.print( | |
| 6381 | 6366 | \\# Total ZIR bytes: {Bi} |
| 6382 | 6367 | \\# Instructions: {d} ({Bi}) |
| 6383 | 6368 | \\# String Table Bytes: {Bi} |
| ... | ... | @@ -6392,8 +6377,8 @@ fn cmdDumpZir( |
| 6392 | 6377 | // zig fmt: on |
| 6393 | 6378 | } |
| 6394 | 6379 | |
| 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(); | |
| 6397 | 6382 | } |
| 6398 | 6383 | |
| 6399 | 6384 | /// This is only enabled for debug builds. |
| ... | ... | @@ -6451,21 +6436,18 @@ fn cmdChangelist( |
| 6451 | 6436 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; |
| 6452 | 6437 | try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); |
| 6453 | 6438 | |
| 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); | |
| 6458 | 6440 | { |
| 6459 | try bw.print("Instruction mappings:\n", .{}); | |
| 6441 | try stdout_bw.print("Instruction mappings:\n", .{}); | |
| 6460 | 6442 | var it = inst_map.iterator(); |
| 6461 | 6443 | while (it.next()) |entry| { |
| 6462 | try bw.print(" %{d} => %{d}\n", .{ | |
| 6444 | try stdout_bw.print(" %{d} => %{d}\n", .{ | |
| 6463 | 6445 | @intFromEnum(entry.key_ptr.*), |
| 6464 | 6446 | @intFromEnum(entry.value_ptr.*), |
| 6465 | 6447 | }); |
| 6466 | 6448 | } |
| 6467 | 6449 | } |
| 6468 | try bw.flush(); | |
| 6450 | try stdout_bw.flush(); | |
| 6469 | 6451 | } |
| 6470 | 6452 | |
| 6471 | 6453 | fn eatIntPrefix(arg: []const u8, base: u8) []const u8 { |
| ... | ... | @@ -6800,8 +6782,7 @@ fn cmdFetch( |
| 6800 | 6782 | const arg = args[i]; |
| 6801 | 6783 | if (mem.startsWith(u8, arg, "-")) { |
| 6802 | 6784 | 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); | |
| 6805 | 6786 | return cleanExit(); |
| 6806 | 6787 | } else if (mem.eql(u8, arg, "--global-cache-dir")) { |
| 6807 | 6788 | if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); |
| ... | ... | @@ -6914,7 +6895,9 @@ fn cmdFetch( |
| 6914 | 6895 | |
| 6915 | 6896 | const name = switch (save) { |
| 6916 | 6897 | .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(); | |
| 6918 | 6901 | return cleanExit(); |
| 6919 | 6902 | }, |
| 6920 | 6903 | .yes, .exact => |name| name: { |
| ... | ... | @@ -6950,7 +6933,7 @@ fn cmdFetch( |
| 6950 | 6933 | var saved_path_or_url = path_or_url; |
| 6951 | 6934 | |
| 6952 | 6935 | 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}); | |
| 6954 | 6937 | |
| 6955 | 6938 | var uri = try std.Uri.parse(path_or_url); |
| 6956 | 6939 | |
| ... | ... | @@ -6963,7 +6946,7 @@ fn cmdFetch( |
| 6963 | 6946 | std.log.info("resolved ref '{s}' to commit {s}", .{ target_ref, latest_commit_hex }); |
| 6964 | 6947 | |
| 6965 | 6948 | // 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}) }; | |
| 6967 | 6950 | } else { |
| 6968 | 6951 | std.log.info("resolved to commit {s}", .{latest_commit_hex}); |
| 6969 | 6952 | } |
| ... | ... | @@ -6972,22 +6955,22 @@ fn cmdFetch( |
| 6972 | 6955 | uri.fragment = .{ .raw = latest_commit_hex }; |
| 6973 | 6956 | |
| 6974 | 6957 | 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}), | |
| 6976 | 6959 | .no, .exact => {}, // keep the original URL |
| 6977 | 6960 | } |
| 6978 | 6961 | } |
| 6979 | 6962 | |
| 6980 | 6963 | const new_node_init = try std.fmt.allocPrint(arena, |
| 6981 | 6964 | \\.{{ |
| 6982 | \\ .url = "{}", | |
| 6983 | \\ .hash = "{}", | |
| 6965 | \\ .url = "{f}", | |
| 6966 | \\ .hash = "{f}", | |
| 6984 | 6967 | \\ }} |
| 6985 | 6968 | , .{ |
| 6986 | 6969 | std.zig.fmtEscapes(saved_path_or_url), |
| 6987 | 6970 | std.zig.fmtEscapes(package_hash_slice), |
| 6988 | 6971 | }); |
| 6989 | 6972 | |
| 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", .{ | |
| 6991 | 6974 | std.zig.fmtId(name), new_node_init, |
| 6992 | 6975 | }); |
| 6993 | 6976 | |
| ... | ... | @@ -7014,12 +6997,12 @@ fn cmdFetch( |
| 7014 | 6997 | |
| 7015 | 6998 | const location_replace = try std.fmt.allocPrint( |
| 7016 | 6999 | arena, |
| 7017 | "\"{}\"", | |
| 7000 | "\"{f}\"", | |
| 7018 | 7001 | .{std.zig.fmtEscapes(saved_path_or_url)}, |
| 7019 | 7002 | ); |
| 7020 | 7003 | const hash_replace = try std.fmt.allocPrint( |
| 7021 | 7004 | arena, |
| 7022 | "\"{}\"", | |
| 7005 | "\"{f}\"", | |
| 7023 | 7006 | .{std.zig.fmtEscapes(package_hash_slice)}, |
| 7024 | 7007 | ); |
| 7025 | 7008 | |
| ... | ... | @@ -7047,15 +7030,11 @@ fn cmdFetch( |
| 7047 | 7030 | fatal("unable to create {s} file: {s}", .{ Package.Manifest.basename, err }); |
| 7048 | 7031 | }; |
| 7049 | 7032 | 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}", .{ | |
| 7056 | 7035 | Package.Manifest.basename, err, |
| 7057 | 7036 | }); |
| 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 }); | |
| 7059 | 7038 | return cleanExit(); |
| 7060 | 7039 | } |
| 7061 | 7040 | |
| ... | ... | @@ -7208,9 +7187,9 @@ fn loadManifest( |
| 7208 | 7187 | ) !struct { Package.Manifest, Ast } { |
| 7209 | 7188 | const manifest_bytes = while (true) { |
| 7210 | 7189 | break options.dir.readFileAllocOptions( |
| 7211 | arena, | |
| 7212 | 7190 | Package.Manifest.basename, |
| 7213 | Package.Manifest.max_bytes, | |
| 7191 | arena, | |
| 7192 | .limited(Package.Manifest.max_bytes), | |
| 7214 | 7193 | null, |
| 7215 | 7194 | .@"1", |
| 7216 | 7195 | 0, |
| ... | ... | @@ -7287,7 +7266,7 @@ const Templates = struct { |
| 7287 | 7266 | } |
| 7288 | 7267 | |
| 7289 | 7268 | 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| { | |
| 7291 | 7270 | fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) }); |
| 7292 | 7271 | }; |
| 7293 | 7272 | templates.buffer.clearRetainingCapacity(); |
src/print_targets.zig+4-4| ... | ... | @@ -27,9 +27,9 @@ fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target) |
| 27 | 27 | defer zig_lib_directory.handle.close(); |
| 28 | 28 | |
| 29 | 29 | const abilists_contents = zig_lib_directory.handle.readFileAlloc( |
| 30 | arena, | |
| 31 | 30 | glibc.abilists_path, |
| 32 | glibc.abilists_max_size, | |
| 31 | arena, | |
| 32 | .limited(glibc.abilists_max_size), | |
| 33 | 33 | ) catch |err| switch (err) { |
| 34 | 34 | error.OutOfMemory => return error.OutOfMemory, |
| 35 | 35 | 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) |
| 37 | 37 | |
| 38 | 38 | const glibc_abi = try glibc.loadMetaData(arena, abilists_contents); |
| 39 | 39 | |
| 40 | var sz = std.zon.stringify.serializer(output, .{}); | |
| 40 | var sz: std.zon.stringify.Serializer = .{ .writer = output }; | |
| 41 | 41 | |
| 42 | 42 | { |
| 43 | 43 | var root_obj = try sz.beginStruct(.{}); |
| ... | ... | @@ -60,7 +60,7 @@ fn print(arena: Allocator, output: *std.io.BufferedWriter, host: *const Target) |
| 60 | 60 | { |
| 61 | 61 | var glibc_obj = try root_obj.beginTupleField("glibc", .{}); |
| 62 | 62 | 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}); | |
| 64 | 64 | try glibc_obj.field(tmp, .{}); |
| 65 | 65 | } |
| 66 | 66 | try glibc_obj.end(); |
src/print_value.zig+113-124| ... | ... | @@ -20,16 +20,10 @@ pub const FormatContext = struct { |
| 20 | 20 | depth: u8, |
| 21 | 21 | }; |
| 22 | 22 | |
| 23 | pub 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; | |
| 23 | pub fn formatSema(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void { | |
| 30 | 24 | const sema = ctx.opt_sema.?; |
| 31 | 25 | 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) { | |
| 33 | 27 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function |
| 34 | 28 | error.ComptimeBreak, error.ComptimeReturn => unreachable, |
| 35 | 29 | error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `sema` more fully |
| ... | ... | @@ -37,16 +31,10 @@ pub fn formatSema( |
| 37 | 31 | }; |
| 38 | 32 | } |
| 39 | 33 | |
| 40 | pub 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; | |
| 34 | pub fn format(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!void { | |
| 47 | 35 | std.debug.assert(ctx.opt_sema == null); |
| 48 | 36 | 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) { | |
| 50 | 38 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function |
| 51 | 39 | error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable, |
| 52 | 40 | else => |e| return e, |
| ... | ... | @@ -55,7 +43,7 @@ pub fn format( |
| 55 | 43 | |
| 56 | 44 | pub fn print( |
| 57 | 45 | val: Value, |
| 58 | writer: *std.io.BufferedWriter, | |
| 46 | bw: *std.io.BufferedWriter, | |
| 59 | 47 | level: u8, |
| 60 | 48 | pt: Zcu.PerThread, |
| 61 | 49 | opt_sema: ?*Sema, |
| ... | ... | @@ -79,61 +67,62 @@ pub fn print( |
| 79 | 67 | .func_type, |
| 80 | 68 | .error_set_type, |
| 81 | 69 | .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"), | |
| 84 | 72 | .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)), | |
| 88 | 76 | }, |
| 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)}), | |
| 92 | 80 | .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}), | |
| 94 | 83 | .lazy_align => |ty| if (opt_sema != null) { |
| 95 | 84 | 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)}), | |
| 98 | 87 | .lazy_size => |ty| if (opt_sema != null) { |
| 99 | 88 | 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)}), | |
| 102 | 91 | }, |
| 103 | .err => |err| try writer.print("error.{}", .{ | |
| 92 | .err => |err| try bw.print("error.{f}", .{ | |
| 104 | 93 | err.name.fmt(ip), |
| 105 | 94 | }), |
| 106 | 95 | .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}", .{ | |
| 108 | 97 | err_name.fmt(ip), |
| 109 | 98 | }), |
| 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), | |
| 111 | 100 | }, |
| 112 | .enum_literal => |enum_literal| try writer.print(".{}", .{ | |
| 101 | .enum_literal => |enum_literal| try bw.print(".{f}", .{ | |
| 113 | 102 | enum_literal.fmt(ip), |
| 114 | 103 | }), |
| 115 | 104 | .enum_tag => |enum_tag| { |
| 116 | 105 | const enum_type = ip.loadEnumType(val.typeOf(zcu).toIntern()); |
| 117 | 106 | 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)}); | |
| 119 | 108 | } |
| 120 | 109 | if (level == 0) { |
| 121 | return writer.writeAll("@enumFromInt(...)"); | |
| 110 | return bw.writeAll("@enumFromInt(...)"); | |
| 122 | 111 | } |
| 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(")"); | |
| 126 | 115 | }, |
| 127 | .empty_enum_value => try writer.writeAll("(empty enum value)"), | |
| 116 | .empty_enum_value => try bw.writeAll("(empty enum value)"), | |
| 128 | 117 | .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))}), | |
| 130 | 119 | }, |
| 131 | 120 | .slice => |slice| { |
| 132 | 121 | if (ip.isUndef(slice.ptr)) { |
| 133 | 122 | if (slice.len == .zero_usize) { |
| 134 | return writer.writeAll("&.{}"); | |
| 123 | return bw.writeAll("&.{}"); | |
| 135 | 124 | } |
| 136 | try print(.fromInterned(slice.ptr), writer, level - 1, pt, opt_sema); | |
| 125 | try print(.fromInterned(slice.ptr), bw, level - 1, pt, opt_sema); | |
| 137 | 126 | } else { |
| 138 | 127 | const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) { |
| 139 | 128 | .field, .arr_elem, .eu_payload, .opt_payload => unreachable, |
| ... | ... | @@ -144,15 +133,15 @@ pub fn print( |
| 144 | 133 | // TODO: eventually we want to load the slice as an array with `sema`, but that's |
| 145 | 134 | // currently not possible without e.g. triggering compile errors. |
| 146 | 135 | } |
| 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); | |
| 148 | 137 | } |
| 149 | try writer.writeAll("[0.."); | |
| 138 | try bw.writeAll("[0.."); | |
| 150 | 139 | if (level == 0) { |
| 151 | try writer.writeAll("(...)"); | |
| 140 | try bw.writeAll("(...)"); | |
| 152 | 141 | } 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); | |
| 154 | 143 | } |
| 155 | try writer.writeAll("]"); | |
| 144 | try bw.writeAll("]"); | |
| 156 | 145 | }, |
| 157 | 146 | .ptr => { |
| 158 | 147 | const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) { |
| ... | ... | @@ -164,29 +153,29 @@ pub fn print( |
| 164 | 153 | // TODO: eventually we want to load the pointer with `sema`, but that's |
| 165 | 154 | // currently not possible without e.g. triggering compile errors. |
| 166 | 155 | } |
| 167 | try printPtr(val, .rvalue, writer, level, pt, opt_sema); | |
| 156 | try printPtr(val, .rvalue, bw, level, pt, opt_sema); | |
| 168 | 157 | }, |
| 169 | 158 | .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), | |
| 172 | 161 | }, |
| 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), | |
| 174 | 163 | .un => |un| { |
| 175 | 164 | if (level == 0) { |
| 176 | try writer.writeAll(".{ ... }"); | |
| 165 | try bw.writeAll(".{ ... }"); | |
| 177 | 166 | return; |
| 178 | 167 | } |
| 179 | 168 | if (un.tag == .none) { |
| 180 | 169 | 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("))"); | |
| 184 | 173 | } 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(" }"); | |
| 190 | 179 | } |
| 191 | 180 | }, |
| 192 | 181 | .memoized_call => unreachable, |
| ... | ... | @@ -197,33 +186,33 @@ fn printAggregate( |
| 197 | 186 | val: Value, |
| 198 | 187 | aggregate: InternPool.Key.Aggregate, |
| 199 | 188 | is_ref: bool, |
| 200 | writer: *std.io.BufferedWriter, | |
| 189 | bw: *std.io.BufferedWriter, | |
| 201 | 190 | level: u8, |
| 202 | 191 | pt: Zcu.PerThread, |
| 203 | 192 | opt_sema: ?*Sema, |
| 204 | 193 | ) anyerror!void { |
| 205 | 194 | 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(".{ ... }"); | |
| 208 | 197 | } |
| 209 | 198 | const zcu = pt.zcu; |
| 210 | 199 | const ip = &zcu.intern_pool; |
| 211 | 200 | const ty = Type.fromInterned(aggregate.ty); |
| 212 | 201 | switch (ty.zigTypeTag(zcu)) { |
| 213 | 202 | .@"struct" => if (!ty.isTuple(zcu)) { |
| 214 | if (is_ref) try writer.writeByte('&'); | |
| 203 | if (is_ref) try bw.writeByte('&'); | |
| 215 | 204 | if (ty.structFieldCount(zcu) == 0) { |
| 216 | return writer.writeAll(".{}"); | |
| 205 | return bw.writeAll(".{}"); | |
| 217 | 206 | } |
| 218 | try writer.writeAll(".{ "); | |
| 207 | try bw.writeAll(".{ "); | |
| 219 | 208 | const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items); |
| 220 | 209 | for (0..max_len) |i| { |
| 221 | if (i != 0) try writer.writeAll(", "); | |
| 210 | if (i != 0) try bw.writeAll(", "); | |
| 222 | 211 | 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); | |
| 225 | 214 | } |
| 226 | try writer.writeAll(" }"); | |
| 215 | try bw.writeAll(" }"); | |
| 227 | 216 | return; |
| 228 | 217 | }, |
| 229 | 218 | .array => { |
| ... | ... | @@ -232,16 +221,16 @@ fn printAggregate( |
| 232 | 221 | const len = ty.arrayLenIncludingSentinel(zcu); |
| 233 | 222 | if (len == 0) break :string; |
| 234 | 223 | 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(".*"); | |
| 237 | 226 | return; |
| 238 | 227 | }, |
| 239 | 228 | .elems, .repeated_elem => {}, |
| 240 | 229 | } |
| 241 | 230 | switch (ty.arrayLen(zcu)) { |
| 242 | 231 | 0 => { |
| 243 | if (is_ref) try writer.writeByte('&'); | |
| 244 | return writer.writeAll(".{}"); | |
| 232 | if (is_ref) try bw.writeByte('&'); | |
| 233 | return bw.writeAll(".{}"); | |
| 245 | 234 | }, |
| 246 | 235 | 1 => one_byte_str: { |
| 247 | 236 | // The repr isn't `bytes`, but we might still be able to print this as a string |
| ... | ... | @@ -249,47 +238,47 @@ fn printAggregate( |
| 249 | 238 | const elem_val = Value.fromInterned(aggregate.storage.values()[0]); |
| 250 | 239 | if (elem_val.isUndef(zcu)) break :one_byte_str; |
| 251 | 240 | 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(".*"); | |
| 254 | 243 | return; |
| 255 | 244 | }, |
| 256 | 245 | else => {}, |
| 257 | 246 | } |
| 258 | 247 | }, |
| 259 | 248 | .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(".{}"); | |
| 262 | 251 | }, |
| 263 | 252 | else => unreachable, |
| 264 | 253 | } |
| 265 | 254 | |
| 266 | 255 | const len = ty.arrayLen(zcu); |
| 267 | 256 | |
| 268 | if (is_ref) try writer.writeByte('&'); | |
| 269 | try writer.writeAll(".{ "); | |
| 257 | if (is_ref) try bw.writeByte('&'); | |
| 258 | try bw.writeAll(".{ "); | |
| 270 | 259 | |
| 271 | 260 | const max_len = @min(len, max_aggregate_items); |
| 272 | 261 | 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); | |
| 275 | 264 | } |
| 276 | 265 | if (len > max_aggregate_items) { |
| 277 | try writer.writeAll(", ..."); | |
| 266 | try bw.writeAll(", ..."); | |
| 278 | 267 | } |
| 279 | return writer.writeAll(" }"); | |
| 268 | return bw.writeAll(" }"); | |
| 280 | 269 | } |
| 281 | 270 | |
| 282 | 271 | fn printPtr( |
| 283 | 272 | ptr_val: Value, |
| 284 | 273 | /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen. |
| 285 | 274 | want_kind: ?PrintPtrKind, |
| 286 | writer: *std.io.BufferedWriter, | |
| 275 | bw: *std.io.BufferedWriter, | |
| 287 | 276 | level: u8, |
| 288 | 277 | pt: Zcu.PerThread, |
| 289 | 278 | opt_sema: ?*Sema, |
| 290 | 279 | ) anyerror!void { |
| 291 | 280 | const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) { |
| 292 | .undef => return writer.writeAll("undefined"), | |
| 281 | .undef => return bw.writeAll("undefined"), | |
| 293 | 282 | .ptr => |ptr| ptr, |
| 294 | 283 | else => unreachable, |
| 295 | 284 | }; |
| ... | ... | @@ -301,7 +290,7 @@ fn printPtr( |
| 301 | 290 | Value.fromInterned(ptr.base_addr.uav.val), |
| 302 | 291 | agg, |
| 303 | 292 | true, |
| 304 | writer, | |
| 293 | bw, | |
| 305 | 294 | level, |
| 306 | 295 | pt, |
| 307 | 296 | opt_sema, |
| ... | ... | @@ -317,7 +306,7 @@ fn printPtr( |
| 317 | 306 | else |
| 318 | 307 | try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, false, null); |
| 319 | 308 | |
| 320 | _ = try printPtrDerivation(derivation, writer, pt, want_kind, .{ .print_val = .{ | |
| 309 | _ = try printPtrDerivation(derivation, bw, pt, want_kind, .{ .print_val = .{ | |
| 321 | 310 | .level = level, |
| 322 | 311 | .opt_sema = opt_sema, |
| 323 | 312 | } }, 20); |
| ... | ... | @@ -329,7 +318,7 @@ const PrintPtrKind = enum { lvalue, rvalue }; |
| 329 | 318 | /// Returns the root derivation, which may be ignored. |
| 330 | 319 | pub fn printPtrDerivation( |
| 331 | 320 | derivation: Value.PointerDeriveStep, |
| 332 | writer: *std.io.BufferedWriter, | |
| 321 | bw: *std.io.BufferedWriter, | |
| 333 | 322 | pt: Zcu.PerThread, |
| 334 | 323 | /// Whether to print `derivation` as an lvalue or rvalue. If `null`, the more concise option is chosen. |
| 335 | 324 | /// 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( |
| 361 | 350 | => |step| continue :root step.parent.*, |
| 362 | 351 | else => |step| break :root step, |
| 363 | 352 | }; |
| 364 | try writer.writeAll("..."); | |
| 353 | try bw.writeAll("..."); | |
| 365 | 354 | return root_step; |
| 366 | 355 | } |
| 367 | 356 | |
| ... | ... | @@ -384,39 +373,39 @@ pub fn printPtrDerivation( |
| 384 | 373 | const need_kind = want_kind orelse result_kind; |
| 385 | 374 | |
| 386 | 375 | if (need_kind == .rvalue and result_kind == .lvalue) { |
| 387 | try writer.writeByte('&'); | |
| 376 | try bw.writeByte('&'); | |
| 388 | 377 | } |
| 389 | 378 | |
| 390 | 379 | // null if `derivation` is the root. |
| 391 | 380 | const root_or_null: ?Value.PointerDeriveStep = switch (derivation) { |
| 392 | 381 | .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)"); | |
| 396 | 385 | break :root root; |
| 397 | 386 | }, |
| 398 | 387 | .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(".?"); | |
| 401 | 390 | break :root root; |
| 402 | 391 | }, |
| 403 | 392 | .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); | |
| 405 | 394 | const agg_ty = (try field.parent.ptrType(pt)).childType(zcu); |
| 406 | 395 | switch (agg_ty.zigTypeTag(zcu)) { |
| 407 | 396 | .@"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)}); | |
| 409 | 398 | } else { |
| 410 | try writer.print("[{d}]", .{field.field_idx}); | |
| 399 | try bw.print("[{d}]", .{field.field_idx}); | |
| 411 | 400 | }, |
| 412 | 401 | .@"union" => { |
| 413 | 402 | const tag_ty = agg_ty.unionTagTypeHypothetical(zcu); |
| 414 | 403 | 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)}); | |
| 416 | 405 | }, |
| 417 | 406 | .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"), | |
| 420 | 409 | else => unreachable, |
| 421 | 410 | }, |
| 422 | 411 | else => unreachable, |
| ... | ... | @@ -424,20 +413,20 @@ pub fn printPtrDerivation( |
| 424 | 413 | break :root root; |
| 425 | 414 | }, |
| 426 | 415 | .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}); | |
| 429 | 418 | break :root root; |
| 430 | 419 | }, |
| 431 | 420 | |
| 432 | 421 | .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("))"); | |
| 436 | 425 | break :root root; |
| 437 | 426 | } 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}); | |
| 441 | 430 | break :root root; |
| 442 | 431 | }, |
| 443 | 432 | |
| ... | ... | @@ -445,33 +434,33 @@ pub fn printPtrDerivation( |
| 445 | 434 | }; |
| 446 | 435 | |
| 447 | 436 | if (root_or_null == null) switch (root_strat) { |
| 448 | .str => |x| try writer.writeAll(x), | |
| 437 | .str => |x| try bw.writeAll(x), | |
| 449 | 438 | .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)}), | |
| 452 | 441 | .uav_ptr => |uav| { |
| 453 | 442 | 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(')'); | |
| 457 | 446 | }, |
| 458 | 447 | .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(')'); | |
| 462 | 451 | }, |
| 463 | 452 | .comptime_field_ptr => |val| { |
| 464 | 453 | 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(')'); | |
| 468 | 457 | }, |
| 469 | 458 | else => unreachable, |
| 470 | 459 | }, |
| 471 | 460 | }; |
| 472 | 461 | |
| 473 | 462 | if (need_kind == .lvalue and result_kind == .rvalue) { |
| 474 | try writer.writeAll(".*"); | |
| 463 | try bw.writeAll(".*"); | |
| 475 | 464 | } |
| 476 | 465 | |
| 477 | 466 | 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 |
| 41 | 41 | extra_index = item.end; |
| 42 | 42 | |
| 43 | 43 | const import_path = zir.nullTerminatedString(item.data.name); |
| 44 | try bw.print(" @import(\"{}\") ", .{ | |
| 44 | try bw.print(" @import(\"{f}\") ", .{ | |
| 45 | 45 | std.zig.fmtEscapes(import_path), |
| 46 | 46 | }); |
| 47 | 47 | try writer.writeSrcTokAbs(bw, item.data.token); |
| ... | ... | @@ -783,7 +783,7 @@ const Writer = struct { |
| 783 | 783 | ) anyerror!void { |
| 784 | 784 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str; |
| 785 | 785 | const str = inst_data.get(self.code); |
| 786 | try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)}); | |
| 786 | try stream.print("\"{f}\")", .{std.zig.fmtEscapes(str)}); | |
| 787 | 787 | } |
| 788 | 788 | |
| 789 | 789 | fn writeSliceStart(self: *Writer, stream: *std.io.BufferedWriter, inst: Zir.Inst.Index) !void { |
| ... | ... | @@ -939,7 +939,7 @@ const Writer = struct { |
| 939 | 939 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok; |
| 940 | 940 | const extra = self.code.extraData(Zir.Inst.Param, inst_data.payload_index); |
| 941 | 941 | const body = self.code.bodySlice(extra.end, extra.data.type.body_len); |
| 942 | try stream.print("\"{}\", ", .{ | |
| 942 | try stream.print("\"{f}\", ", .{ | |
| 943 | 943 | std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)), |
| 944 | 944 | }); |
| 945 | 945 | |
| ... | ... | @@ -1210,7 +1210,7 @@ const Writer = struct { |
| 1210 | 1210 | try stream.writeAll(", "); |
| 1211 | 1211 | } else { |
| 1212 | 1212 | 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)}); | |
| 1214 | 1214 | } |
| 1215 | 1215 | try stream.writeAll(", "); |
| 1216 | 1216 | |
| ... | ... | @@ -1227,7 +1227,7 @@ const Writer = struct { |
| 1227 | 1227 | |
| 1228 | 1228 | const name = self.code.nullTerminatedString(output.data.name); |
| 1229 | 1229 | const constraint = self.code.nullTerminatedString(output.data.constraint); |
| 1230 | try stream.print("output({p}, \"{}\", ", .{ | |
| 1230 | try stream.print("output({fp}, \"{f}\", ", .{ | |
| 1231 | 1231 | std.zig.fmtId(name), std.zig.fmtEscapes(constraint), |
| 1232 | 1232 | }); |
| 1233 | 1233 | try self.writeFlag(stream, "->", is_type); |
| ... | ... | @@ -1246,7 +1246,7 @@ const Writer = struct { |
| 1246 | 1246 | |
| 1247 | 1247 | const name = self.code.nullTerminatedString(input.data.name); |
| 1248 | 1248 | const constraint = self.code.nullTerminatedString(input.data.constraint); |
| 1249 | try stream.print("input({p}, \"{}\", ", .{ | |
| 1249 | try stream.print("input({fp}, \"{f}\", ", .{ | |
| 1250 | 1250 | std.zig.fmtId(name), std.zig.fmtEscapes(constraint), |
| 1251 | 1251 | }); |
| 1252 | 1252 | try self.writeInstRef(stream, input.data.operand); |
| ... | ... | @@ -1262,7 +1262,7 @@ const Writer = struct { |
| 1262 | 1262 | const str_index = self.code.extra[extra_i]; |
| 1263 | 1263 | extra_i += 1; |
| 1264 | 1264 | 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)}); | |
| 1266 | 1266 | if (i + 1 < clobbers_len) { |
| 1267 | 1267 | try stream.writeAll(", "); |
| 1268 | 1268 | } |
| ... | ... | @@ -1306,7 +1306,7 @@ const Writer = struct { |
| 1306 | 1306 | .field => { |
| 1307 | 1307 | const field_name = self.code.nullTerminatedString(extra.data.field_name_start); |
| 1308 | 1308 | 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)}); | |
| 1310 | 1310 | }, |
| 1311 | 1311 | } |
| 1312 | 1312 | try stream.writeAll(", ["); |
| ... | ... | @@ -1526,7 +1526,7 @@ const Writer = struct { |
| 1526 | 1526 | try self.writeFlag(stream, "comptime ", field.is_comptime); |
| 1527 | 1527 | if (field.name != .empty) { |
| 1528 | 1528 | 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)}); | |
| 1530 | 1530 | } else { |
| 1531 | 1531 | try stream.print("@\"{d}\": ", .{i}); |
| 1532 | 1532 | } |
| ... | ... | @@ -1689,7 +1689,7 @@ const Writer = struct { |
| 1689 | 1689 | extra_index += 1; |
| 1690 | 1690 | |
| 1691 | 1691 | 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)}); | |
| 1693 | 1693 | |
| 1694 | 1694 | if (has_type) { |
| 1695 | 1695 | const field_type = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); |
| ... | ... | @@ -1823,7 +1823,7 @@ const Writer = struct { |
| 1823 | 1823 | extra_index += 1; |
| 1824 | 1824 | |
| 1825 | 1825 | 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)}); | |
| 1827 | 1827 | |
| 1828 | 1828 | if (has_tag_value) { |
| 1829 | 1829 | const tag_value_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); |
| ... | ... | @@ -1928,7 +1928,7 @@ const Writer = struct { |
| 1928 | 1928 | const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); |
| 1929 | 1929 | const name = self.code.nullTerminatedString(name_index); |
| 1930 | 1930 | 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)}); | |
| 1932 | 1932 | } |
| 1933 | 1933 | |
| 1934 | 1934 | self.indent -= 2; |
| ... | ... | @@ -2210,7 +2210,7 @@ const Writer = struct { |
| 2210 | 2210 | const extra = self.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 2211 | 2211 | const name = self.code.nullTerminatedString(extra.field_name_start); |
| 2212 | 2212 | try self.writeInstRef(stream, extra.lhs); |
| 2213 | try stream.print(", \"{}\") ", .{std.zig.fmtEscapes(name)}); | |
| 2213 | try stream.print(", \"{f}\") ", .{std.zig.fmtEscapes(name)}); | |
| 2214 | 2214 | try self.writeSrcNode(stream, inst_data.src_node); |
| 2215 | 2215 | } |
| 2216 | 2216 | |
| ... | ... | @@ -2251,7 +2251,7 @@ const Writer = struct { |
| 2251 | 2251 | ) anyerror!void { |
| 2252 | 2252 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; |
| 2253 | 2253 | const str = inst_data.get(self.code); |
| 2254 | try stream.print("\"{}\") ", .{std.zig.fmtEscapes(str)}); | |
| 2254 | try stream.print("\"{f}\") ", .{std.zig.fmtEscapes(str)}); | |
| 2255 | 2255 | try self.writeSrcTok(stream, inst_data.src_tok); |
| 2256 | 2256 | } |
| 2257 | 2257 | |
| ... | ... | @@ -2259,7 +2259,7 @@ const Writer = struct { |
| 2259 | 2259 | const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str_op; |
| 2260 | 2260 | const str = inst_data.getStr(self.code); |
| 2261 | 2261 | try self.writeInstRef(stream, inst_data.operand); |
| 2262 | try stream.print(", \"{}\")", .{std.zig.fmtEscapes(str)}); | |
| 2262 | try stream.print(", \"{f}\")", .{std.zig.fmtEscapes(str)}); | |
| 2263 | 2263 | } |
| 2264 | 2264 | |
| 2265 | 2265 | fn writeFunc( |
| ... | ... | @@ -2700,10 +2700,10 @@ const Writer = struct { |
| 2700 | 2700 | try stream.writeAll("load "); |
| 2701 | 2701 | try self.writeInstIndex(stream, ptr_inst); |
| 2702 | 2702 | }, |
| 2703 | .decl_val => |str| try stream.print("decl_val \"{}\"", .{ | |
| 2703 | .decl_val => |str| try stream.print("decl_val \"{f}\"", .{ | |
| 2704 | 2704 | std.zig.fmtEscapes(self.code.nullTerminatedString(str)), |
| 2705 | 2705 | }), |
| 2706 | .decl_ref => |str| try stream.print("decl_ref \"{}\"", .{ | |
| 2706 | .decl_ref => |str| try stream.print("decl_ref \"{f}\"", .{ | |
| 2707 | 2707 | std.zig.fmtEscapes(self.code.nullTerminatedString(str)), |
| 2708 | 2708 | }), |
| 2709 | 2709 | } |
| ... | ... | @@ -2837,7 +2837,7 @@ const Writer = struct { |
| 2837 | 2837 | const extra = self.code.extraData(Zir.Inst.Import, inst_data.payload_index).data; |
| 2838 | 2838 | try self.writeInstRef(stream, extra.res_ty); |
| 2839 | 2839 | 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)}); | |
| 2841 | 2841 | try self.writeSrcTok(stream, inst_data.src_tok); |
| 2842 | 2842 | } |
| 2843 | 2843 | }; |
src/print_zoir.zig+3-3| ... | ... | @@ -70,8 +70,8 @@ const PrintZon = struct { |
| 70 | 70 | }, |
| 71 | 71 | .float_literal => |x| try pz.w.print("float({d})", .{x}), |
| 72 | 72 | .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)}), | |
| 75 | 75 | .empty_literal => try pz.w.writeAll("empty_literal(.{})"), |
| 76 | 76 | .array_literal => |vals| { |
| 77 | 77 | try pz.w.writeAll("array_literal({"); |
| ... | ... | @@ -90,7 +90,7 @@ const PrintZon = struct { |
| 90 | 90 | pz.indent += 1; |
| 91 | 91 | for (s.names, 0..s.vals.len) |name, idx| { |
| 92 | 92 | 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))}); | |
| 94 | 94 | try pz.renderNode(s.vals.at(@intCast(idx))); |
| 95 | 95 | try pz.w.writeByte(','); |
| 96 | 96 | } |
src/register_manager.zig+3-3| ... | ... | @@ -238,7 +238,7 @@ pub fn RegisterManager( |
| 238 | 238 | if (i < count) return null; |
| 239 | 239 | |
| 240 | 240 | for (regs, insts) |reg, inst| { |
| 241 | log.debug("tryAllocReg {} for inst {?}", .{ reg, inst }); | |
| 241 | log.debug("tryAllocReg {} for inst {?f}", .{ reg, inst }); | |
| 242 | 242 | self.markRegAllocated(reg); |
| 243 | 243 | |
| 244 | 244 | if (inst) |tracked_inst| { |
| ... | ... | @@ -317,7 +317,7 @@ pub fn RegisterManager( |
| 317 | 317 | tracked_index: TrackedIndex, |
| 318 | 318 | inst: ?Air.Inst.Index, |
| 319 | 319 | ) AllocationError!void { |
| 320 | log.debug("getReg {} for inst {?}", .{ regAtTrackedIndex(tracked_index), inst }); | |
| 320 | log.debug("getReg {} for inst {?f}", .{ regAtTrackedIndex(tracked_index), inst }); | |
| 321 | 321 | if (!self.isRegIndexFree(tracked_index)) { |
| 322 | 322 | // Move the instruction that was previously there to a |
| 323 | 323 | // stack allocation. |
| ... | ... | @@ -349,7 +349,7 @@ pub fn RegisterManager( |
| 349 | 349 | tracked_index: TrackedIndex, |
| 350 | 350 | inst: ?Air.Inst.Index, |
| 351 | 351 | ) void { |
| 352 | log.debug("getRegAssumeFree {} for inst {?}", .{ regAtTrackedIndex(tracked_index), inst }); | |
| 352 | log.debug("getRegAssumeFree {} for inst {?f}", .{ regAtTrackedIndex(tracked_index), inst }); | |
| 353 | 353 | self.markRegIndexAllocated(tracked_index); |
| 354 | 354 | |
| 355 | 355 | 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 |
| 357 | 357 | var len: usize = undefined; |
| 358 | 358 | const bytes_ptr = asm_string.getString_bytes_begin_size(&len); |
| 359 | 359 | |
| 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])}); | |
| 361 | 361 | const str_node = try Tag.string_literal.create(c.arena, str); |
| 362 | 362 | |
| 363 | 363 | const asm_node = try Tag.asm_simple.create(c.arena, str_node); |
| ... | ... | @@ -2276,7 +2276,7 @@ fn transNarrowStringLiteral( |
| 2276 | 2276 | var len: usize = undefined; |
| 2277 | 2277 | const bytes_ptr = stmt.getString_bytes_begin_size(&len); |
| 2278 | 2278 | |
| 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])}); | |
| 2280 | 2280 | const node = try Tag.string_literal.create(c.arena, str); |
| 2281 | 2281 | return maybeSuppressResult(c, result_used, node); |
| 2282 | 2282 | } |
| ... | ... | @@ -3338,7 +3338,7 @@ fn transPredefinedExpr(c: *Context, scope: *Scope, expr: *const clang.Predefined |
| 3338 | 3338 | |
| 3339 | 3339 | fn transCreateCharLitNode(c: *Context, narrow: bool, val: u32) TransError!Node { |
| 3340 | 3340 | 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))})}) | |
| 3342 | 3342 | else |
| 3343 | 3343 | try std.fmt.allocPrint(c.arena, "'\\u{{{x}}}'", .{val})); |
| 3344 | 3344 | } |
| ... | ... | @@ -5832,7 +5832,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 { |
| 5832 | 5832 | num += c - 'A' + 10; |
| 5833 | 5833 | }, |
| 5834 | 5834 | 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 }); | |
| 5836 | 5836 | num = 0; |
| 5837 | 5837 | if (c == '\\') |
| 5838 | 5838 | state = .escape |
| ... | ... | @@ -5858,7 +5858,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 { |
| 5858 | 5858 | }; |
| 5859 | 5859 | num += c - '0'; |
| 5860 | 5860 | } 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 }); | |
| 5862 | 5862 | num = 0; |
| 5863 | 5863 | count = 0; |
| 5864 | 5864 | if (c == '\\') |
| ... | ... | @@ -5872,7 +5872,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 { |
| 5872 | 5872 | } |
| 5873 | 5873 | } |
| 5874 | 5874 | 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 }); | |
| 5876 | 5876 | return bytes[0..i]; |
| 5877 | 5877 | } |
| 5878 | 5878 | |
| ... | ... | @@ -5884,9 +5884,9 @@ fn escapeUnprintables(ctx: *Context, m: *MacroCtx) ![]const u8 { |
| 5884 | 5884 | if (std.unicode.utf8ValidateSlice(zigified)) return zigified; |
| 5885 | 5885 | |
| 5886 | 5886 | 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}); | |
| 5888 | 5888 | 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) { | |
| 5890 | 5890 | error.NoSpaceLeft => unreachable, |
| 5891 | 5891 | else => |e| return e, |
| 5892 | 5892 | }; |