authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-20 23:20:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:27-07:00
log6a0f2227e8b40e3456d3c85c72f68f483b239af3
tree11649e598ed1bc743ed946318fea1f47708d72d2
parent7b0d826849f5def7b5c847a35e9e54ef81d70dc7

build_runner: port to `std.io.BufferedReader` API changes


20 files changed, 302 insertions(+), 356 deletions(-)

lib/std/Build/Fuzz/WebServer.zig+14-24
...@@ -100,8 +100,7 @@ fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {...@@ -100,8 +100,7 @@ fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {
100100
101 var sr = connection.stream.reader();101 var sr = connection.stream.reader();
102 var rb: [0x4000]u8 = undefined;102 var rb: [0x4000]u8 = undefined;
103 var br: std.io.BufferedReader = undefined;103 var br = sr.interface().buffered(&rb);
104 br.init(sr.interface(), &rb);
105104
106 var sw = connection.stream.writer();105 var sw = connection.stream.writer();
107 var wb: [0x4000]u8 = undefined;106 var wb: [0x4000]u8 = undefined;
...@@ -109,7 +108,6 @@ fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {...@@ -109,7 +108,6 @@ fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {
109108
110 var server: std.http.Server = .init(&br, &bw);109 var server: std.http.Server = .init(&br, &bw);
111 var web_socket: std.http.WebSocket = undefined;110 var web_socket: std.http.WebSocket = undefined;
112 var send_buffer: [0x4000]u8 = undefined;
113 var ws_recv_buffer: [0x4000]u8 align(4) = undefined;111 var ws_recv_buffer: [0x4000]u8 align(4) = undefined;
114 while (server.state == .ready) {112 while (server.state == .ready) {
115 var request = server.receiveHead() catch |err| switch (err) {113 var request = server.receiveHead() catch |err| switch (err) {
...@@ -119,7 +117,7 @@ fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {...@@ -119,7 +117,7 @@ fn accept(ws: *WebServer, connection: std.net.Server.Connection) void {
119 return;117 return;
120 },118 },
121 };119 };
122 if (web_socket.init(&request, &send_buffer, &ws_recv_buffer) catch |err| {120 if (web_socket.init(&request, &ws_recv_buffer) catch |err| {
123 log.err("initializing web socket: {s}", .{@errorName(err)});121 log.err("initializing web socket: {s}", .{@errorName(err)});
124 return;122 return;
125 }) {123 }) {
...@@ -281,19 +279,16 @@ fn buildWasmBinary(...@@ -281,19 +279,16 @@ fn buildWasmBinary(
281 try sendMessage(child.stdin.?, .update);279 try sendMessage(child.stdin.?, .update);
282 try sendMessage(child.stdin.?, .exit);280 try sendMessage(child.stdin.?, .exit);
283281
284 const Header = std.zig.Server.Message.Header;
285 var result: ?Path = null;282 var result: ?Path = null;
286 var result_error_bundle = std.zig.ErrorBundle.empty;283 var result_error_bundle = std.zig.ErrorBundle.empty;
287284
288 const stdout = poller.fifo(.stdout);285 const stdout_br = poller.reader(.stdout);
289
290 poll: while (true) {286 poll: while (true) {
291 while (stdout.readableLength() < @sizeOf(Header)) if (!try poller.poll()) break :poll;287 const Header = std.zig.Server.Message.Header;
292 var header: Header = undefined;288 while (stdout_br.bufferContents().len < @sizeOf(Header)) if (!try poller.poll()) break :poll;
293 assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(Header));289 const header = (stdout_br.takeStruct(Header) catch unreachable).*;
294 while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll;290 while (stdout_br.bufferContents().len < header.bytes_len) if (!try poller.poll()) break :poll;
295 const body = stdout.readableSliceOfLen(header.bytes_len);291 const body = stdout_br.take(header.bytes_len) catch unreachable;
296
297 switch (header.tag) {292 switch (header.tag) {
298 .zig_version => {293 .zig_version => {
299 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {294 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {
...@@ -330,15 +325,12 @@ fn buildWasmBinary(...@@ -330,15 +325,12 @@ fn buildWasmBinary(
330 },325 },
331 else => {}, // ignore other messages326 else => {}, // ignore other messages
332 }327 }
333
334 stdout.discard(body.len);
335 }328 }
336329
337 const stderr = poller.fifo(.stderr);330 const stderr_br = poller.reader(.stderr);
338 if (stderr.readableLength() > 0) {331 const stderr_contents = stderr_br.bufferContents();
339 const owned_stderr = try stderr.toOwnedSlice();332 if (stderr_contents.len > 0) {
340 defer gpa.free(owned_stderr);333 std.debug.print("{s}", .{stderr_contents});
341 std.debug.print("{s}", .{owned_stderr});
342 }334 }
343335
344 // Send EOF to stdin.336 // Send EOF to stdin.
...@@ -484,9 +476,7 @@ fn serveSourcesTar(ws: *WebServer, request: *std.http.Server.Request) !void {...@@ -484,9 +476,7 @@ fn serveSourcesTar(ws: *WebServer, request: *std.http.Server.Request) !void {
484 defer arena_instance.deinit();476 defer arena_instance.deinit();
485 const arena = arena_instance.allocator();477 const arena = arena_instance.allocator();
486478
487 var send_buffer: [0x4000]u8 = undefined;479 var response = try request.respondStreaming(.{
488 var response = request.respondStreaming(.{
489 .send_buffer = &send_buffer,
490 .respond_options = .{480 .respond_options = .{
491 .extra_headers = &.{481 .extra_headers = &.{
492 .{ .name = "content-type", .value = "application/x-tar" },482 .{ .name = "content-type", .value = "application/x-tar" },
...@@ -538,7 +528,7 @@ fn serveSourcesTar(ws: *WebServer, request: *std.http.Server.Request) !void {...@@ -538,7 +528,7 @@ fn serveSourcesTar(ws: *WebServer, request: *std.http.Server.Request) !void {
538 defer file.close();528 defer file.close();
539529
540 archiver.prefix = joined_path.root_dir.path orelse try memoizedCwd(arena, &cwd_cache);530 archiver.prefix = joined_path.root_dir.path orelse try memoizedCwd(arena, &cwd_cache);
541 try archiver.writeFile(joined_path.sub_path, file);531 try archiver.writeFile(joined_path.sub_path, file, try file.stat());
542 }532 }
543533
544 // intentionally omitting the pointless trailer534 // intentionally omitting the pointless trailer
lib/std/Build/Step.zig+12-19
...@@ -511,18 +511,15 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {...@@ -511,18 +511,15 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {
511 try sendMessage(zp.child.stdin.?, .update);511 try sendMessage(zp.child.stdin.?, .update);
512 if (!watch) try sendMessage(zp.child.stdin.?, .exit);512 if (!watch) try sendMessage(zp.child.stdin.?, .exit);
513513
514 const Header = std.zig.Server.Message.Header;
515 var result: ?Path = null;514 var result: ?Path = null;
516515
517 const stdout = zp.poller.fifo(.stdout);516 const stdout_br = zp.poller.reader(.stdout);
518
519 poll: while (true) {517 poll: while (true) {
520 while (stdout.readableLength() < @sizeOf(Header)) if (!try zp.poller.poll()) break :poll;518 const Header = std.zig.Server.Message.Header;
521 var header: Header = undefined;519 while (stdout_br.bufferContents().len < @sizeOf(Header)) if (!try zp.poller.poll()) break :poll;
522 assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(Header));520 const header = (stdout_br.takeStruct(Header) catch unreachable).*;
523 while (stdout.readableLength() < header.bytes_len) if (!try zp.poller.poll()) break :poll;521 while (stdout_br.bufferContents().len < header.bytes_len) if (!try zp.poller.poll()) break :poll;
524 const body = stdout.readableSliceOfLen(header.bytes_len);522 const body = stdout_br.take(header.bytes_len) catch unreachable;
525
526 switch (header.tag) {523 switch (header.tag) {
527 .zig_version => {524 .zig_version => {
528 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {525 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {
...@@ -547,11 +544,8 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {...@@ -547,11 +544,8 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {
547 .string_bytes = try arena.dupe(u8, string_bytes),544 .string_bytes = try arena.dupe(u8, string_bytes),
548 .extra = extra_array,545 .extra = extra_array,
549 };546 };
550 if (watch) {547 // This message indicates the end of the update.
551 // This message indicates the end of the update.548 if (watch) break :poll;
552 stdout.discard(body.len);
553 break;
554 }
555 },549 },
556 .emit_digest => {550 .emit_digest => {
557 const EmitDigest = std.zig.Server.Message.EmitDigest;551 const EmitDigest = std.zig.Server.Message.EmitDigest;
...@@ -611,15 +605,14 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {...@@ -611,15 +605,14 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {
611 },605 },
612 else => {}, // ignore other messages606 else => {}, // ignore other messages
613 }607 }
614
615 stdout.discard(body.len);
616 }608 }
617609
618 s.result_duration_ns = timer.read();610 s.result_duration_ns = timer.read();
619611
620 const stderr = zp.poller.fifo(.stderr);612 const stderr_br = zp.poller.reader(.stderr);
621 if (stderr.readableLength() > 0) {613 const stderr_contents = stderr_br.bufferContents();
622 try s.result_error_msgs.append(arena, try stderr.toOwnedSlice());614 if (stderr_contents.len > 0) {
615 try s.result_error_msgs.append(arena, try arena.dupe(u8, stderr_contents));
623 }616 }
624617
625 return result;618 return result;
lib/std/Build/Step/CheckObject.zig+12-12
...@@ -1239,7 +1239,7 @@ const MachODumper = struct {...@@ -1239,7 +1239,7 @@ const MachODumper = struct {
12391239
1240 fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.ArrayList(u64)) !void {1240 fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.ArrayList(u64)) !void {
1241 var br: std.io.BufferedReader = undefined;1241 var br: std.io.BufferedReader = undefined;
1242 br.initFixed(data);1242 br.initFixed(@constCast(data));
12431243
1244 var seg_id: ?u8 = null;1244 var seg_id: ?u8 = null;
1245 var offset: u64 = 0;1245 var offset: u64 = 0;
...@@ -1350,7 +1350,7 @@ const MachODumper = struct {...@@ -1350,7 +1350,7 @@ const MachODumper = struct {
13501350
1351 fn parseBindInfo(ctx: ObjectContext, data: []const u8, bindings: *std.ArrayList(Binding)) !void {1351 fn parseBindInfo(ctx: ObjectContext, data: []const u8, bindings: *std.ArrayList(Binding)) !void {
1352 var br: std.io.BufferedReader = undefined;1352 var br: std.io.BufferedReader = undefined;
1353 br.initFixed(data);1353 br.initFixed(@constCast(data));
13541354
1355 var seg_id: ?u8 = null;1355 var seg_id: ?u8 = null;
1356 var tag: Binding.Tag = .self;1356 var tag: Binding.Tag = .self;
...@@ -1448,7 +1448,7 @@ const MachODumper = struct {...@@ -1448,7 +1448,7 @@ const MachODumper = struct {
14481448
1449 var exports: std.ArrayList(Export) = .init(arena.allocator());1449 var exports: std.ArrayList(Export) = .init(arena.allocator());
1450 var br: std.io.BufferedReader = undefined;1450 var br: std.io.BufferedReader = undefined;
1451 br.initFixed(data);1451 br.initFixed(@constCast(data));
1452 try parseTrieNode(arena.allocator(), &br, "", &exports);1452 try parseTrieNode(arena.allocator(), &br, "", &exports);
14531453
1454 mem.sort(Export, exports.items, {}, Export.lessThan);1454 mem.sort(Export, exports.items, {}, Export.lessThan);
...@@ -1706,7 +1706,7 @@ const ElfDumper = struct {...@@ -1706,7 +1706,7 @@ const ElfDumper = struct {
1706 fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 {1706 fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
1707 const gpa = step.owner.allocator;1707 const gpa = step.owner.allocator;
1708 var br: std.io.BufferedReader = undefined;1708 var br: std.io.BufferedReader = undefined;
1709 br.initFixed(bytes);1709 br.initFixed(@constCast(bytes));
17101710
1711 if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber;1711 if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber;
17121712
...@@ -1781,7 +1781,7 @@ const ElfDumper = struct {...@@ -1781,7 +1781,7 @@ const ElfDumper = struct {
17811781
1782 fn parseSymtab(ctx: *ArchiveContext, data: []const u8, ptr_width: enum { p32, p64 }) !void {1782 fn parseSymtab(ctx: *ArchiveContext, data: []const u8, ptr_width: enum { p32, p64 }) !void {
1783 var br: std.io.BufferedReader = undefined;1783 var br: std.io.BufferedReader = undefined;
1784 br.initFixed(data);1784 br.initFixed(@constCast(data));
1785 const num = switch (ptr_width) {1785 const num = switch (ptr_width) {
1786 .p32 => try br.takeInt(u32, .big),1786 .p32 => try br.takeInt(u32, .big),
1787 .p64 => try br.takeInt(u64, .big),1787 .p64 => try br.takeInt(u64, .big),
...@@ -1791,7 +1791,7 @@ const ElfDumper = struct {...@@ -1791,7 +1791,7 @@ const ElfDumper = struct {
1791 .p64 => @sizeOf(u64),1791 .p64 => @sizeOf(u64),
1792 };1792 };
1793 try br.discard(num * ptr_size);1793 try br.discard(num * ptr_size);
1794 const strtab = try br.peekGreedy(0);1794 const strtab = br.bufferContents();
17951795
1796 assert(ctx.symtab.len == 0);1796 assert(ctx.symtab.len == 0);
1797 ctx.symtab = try ctx.gpa.alloc(ArSymtabEntry, num);1797 ctx.symtab = try ctx.gpa.alloc(ArSymtabEntry, num);
...@@ -1852,7 +1852,7 @@ const ElfDumper = struct {...@@ -1852,7 +1852,7 @@ const ElfDumper = struct {
1852 fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 {1852 fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
1853 const gpa = step.owner.allocator;1853 const gpa = step.owner.allocator;
1854 var br: std.io.BufferedReader = undefined;1854 var br: std.io.BufferedReader = undefined;
1855 br.initFixed(bytes);1855 br.initFixed(@constCast(bytes));
18561856
1857 const hdr = try br.takeStruct(elf.Elf64_Ehdr);1857 const hdr = try br.takeStruct(elf.Elf64_Ehdr);
1858 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber;1858 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber;
...@@ -2355,7 +2355,7 @@ const WasmDumper = struct {...@@ -2355,7 +2355,7 @@ const WasmDumper = struct {
2355 fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 {2355 fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
2356 const gpa = step.owner.allocator;2356 const gpa = step.owner.allocator;
2357 var br: std.io.BufferedReader = undefined;2357 var br: std.io.BufferedReader = undefined;
2358 br.initFixed(bytes);2358 br.initFixed(@constCast(bytes));
23592359
2360 const buf = try br.takeArray(8);2360 const buf = try br.takeArray(8);
2361 if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte;2361 if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte;
...@@ -2402,7 +2402,7 @@ const WasmDumper = struct {...@@ -2402,7 +2402,7 @@ const WasmDumper = struct {
2402 try bw.print(2402 try bw.print(
2403 \\Section {s}2403 \\Section {s}
2404 \\size {d}2404 \\size {d}
2405 , .{ @tagName(section), br.storageBuffer().len });2405 , .{ @tagName(section), br.buffer.len });
24062406
2407 switch (section) {2407 switch (section) {
2408 .type,2408 .type,
...@@ -2615,7 +2615,7 @@ const WasmDumper = struct {...@@ -2615,7 +2615,7 @@ const WasmDumper = struct {
2615 /// https://webassembly.github.io/spec/core/appendix/custom.html2615 /// https://webassembly.github.io/spec/core/appendix/custom.html
2616 fn parseDumpNames(step: *Step, br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void {2616 fn parseDumpNames(step: *Step, br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void {
2617 var subsection_br: std.io.BufferedReader = undefined;2617 var subsection_br: std.io.BufferedReader = undefined;
2618 while (br.seek < br.storageBuffer().len) {2618 while (br.seek < br.buffer.len) {
2619 switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) {2619 switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) {
2620 // The module name subsection ... consists of a single name2620 // The module name subsection ... consists of a single name
2621 // that is assigned to the module itself.2621 // that is assigned to the module itself.
...@@ -2626,7 +2626,7 @@ const WasmDumper = struct {...@@ -2626,7 +2626,7 @@ const WasmDumper = struct {
2626 \\name {s}2626 \\name {s}
2627 \\2627 \\
2628 , .{name});2628 , .{name});
2629 if (subsection_br.seek != subsection_br.storageBuffer().len) return error.BadSubsectionSize;2629 if (subsection_br.seek != subsection_br.buffer.len) return error.BadSubsectionSize;
2630 },2630 },
26312631
2632 // The function name subsection ... consists of a name map2632 // The function name subsection ... consists of a name map
...@@ -2647,7 +2647,7 @@ const WasmDumper = struct {...@@ -2647,7 +2647,7 @@ const WasmDumper = struct {
2647 \\2647 \\
2648 , .{ index, name });2648 , .{ index, name });
2649 }2649 }
2650 if (subsection_br.seek != subsection_br.storageBuffer().len) return error.BadSubsectionSize;2650 if (subsection_br.seek != subsection_br.buffer.len) return error.BadSubsectionSize;
2651 },2651 },
26522652
2653 // The local name subsection ... consists of an indirect name2653 // The local name subsection ... consists of an indirect name
lib/std/Build/Step/Run.zig+18-24
...@@ -1517,11 +1517,6 @@ fn evalZigTest(...@@ -1517,11 +1517,6 @@ fn evalZigTest(
1517 break :failed false;1517 break :failed false;
1518 };1518 };
15191519
1520 const Header = std.zig.Server.Message.Header;
1521
1522 const stdout = poller.fifo(.stdout);
1523 const stderr = poller.fifo(.stderr);
1524
1525 var fail_count: u32 = 0;1520 var fail_count: u32 = 0;
1526 var skip_count: u32 = 0;1521 var skip_count: u32 = 0;
1527 var leak_count: u32 = 0;1522 var leak_count: u32 = 0;
...@@ -1534,13 +1529,14 @@ fn evalZigTest(...@@ -1534,13 +1529,14 @@ fn evalZigTest(
1534 var sub_prog_node: ?std.Progress.Node = null;1529 var sub_prog_node: ?std.Progress.Node = null;
1535 defer if (sub_prog_node) |n| n.end();1530 defer if (sub_prog_node) |n| n.end();
15361531
1532 const stdout_br = poller.reader(.stdout);
1533 const stderr_br = poller.reader(.stderr);
1537 const any_write_failed = first_write_failed or poll: while (true) {1534 const any_write_failed = first_write_failed or poll: while (true) {
1538 while (stdout.readableLength() < @sizeOf(Header)) if (!try poller.poll()) break :poll false;1535 const Header = std.zig.Server.Message.Header;
1539 var header: Header = undefined;1536 while (stdout_br.bufferContents().len < @sizeOf(Header)) if (!try poller.poll()) break :poll false;
1540 assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(Header));1537 const header = (stdout_br.takeStruct(Header) catch unreachable).*;
1541 while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll false;1538 while (stdout_br.bufferContents().len < header.bytes_len) if (!try poller.poll()) break :poll false;
1542 const body = stdout.readableSliceOfLen(header.bytes_len);1539 const body = stdout_br.take(header.bytes_len) catch unreachable;
1543
1544 switch (header.tag) {1540 switch (header.tag) {
1545 .zig_version => {1541 .zig_version => {
1546 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {1542 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {
...@@ -1597,9 +1593,9 @@ fn evalZigTest(...@@ -1597,9 +1593,9 @@ fn evalZigTest(
15971593
1598 if (tr_hdr.flags.fail or tr_hdr.flags.leak or tr_hdr.flags.log_err_count > 0) {1594 if (tr_hdr.flags.fail or tr_hdr.flags.leak or tr_hdr.flags.log_err_count > 0) {
1599 const name = std.mem.sliceTo(md.string_bytes[md.names[tr_hdr.index]..], 0);1595 const name = std.mem.sliceTo(md.string_bytes[md.names[tr_hdr.index]..], 0);
1600 const orig_msg = stderr.readableSlice(0);1596 const stderr_contents = stderr_br.bufferContents();
1601 defer stderr.discard(orig_msg.len);1597 stderr_br.toss(stderr_contents.len);
1602 const msg = std.mem.trim(u8, orig_msg, "\n");1598 const msg = std.mem.trim(u8, stderr_contents, "\n");
1603 const label = if (tr_hdr.flags.fail)1599 const label = if (tr_hdr.flags.fail)
1604 "failed"1600 "failed"
1605 else if (tr_hdr.flags.leak)1601 else if (tr_hdr.flags.leak)
...@@ -1650,8 +1646,6 @@ fn evalZigTest(...@@ -1650,8 +1646,6 @@ fn evalZigTest(
1650 },1646 },
1651 else => {}, // ignore other messages1647 else => {}, // ignore other messages
1652 }1648 }
1653
1654 stdout.discard(body.len);
1655 };1649 };
16561650
1657 if (any_write_failed) {1651 if (any_write_failed) {
...@@ -1660,9 +1654,9 @@ fn evalZigTest(...@@ -1660,9 +1654,9 @@ fn evalZigTest(
1660 while (try poller.poll()) {}1654 while (try poller.poll()) {}
1661 }1655 }
16621656
1663 if (stderr.readableLength() > 0) {1657 const stderr_contents = std.mem.trim(u8, stderr_br.bufferContents(), "\n");
1664 const msg = std.mem.trim(u8, try stderr.toOwnedSlice(), "\n");1658 if (stderr_contents.len > 0) {
1665 if (msg.len > 0) run.step.result_stderr = msg;1659 run.step.result_stderr = try arena.dupe(u8, stderr_contents);
1666 }1660 }
16671661
1668 // Send EOF to stdin.1662 // Send EOF to stdin.
...@@ -1776,7 +1770,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {...@@ -1776,7 +1770,7 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
1776 var stdout_bytes: ?[]const u8 = null;1770 var stdout_bytes: ?[]const u8 = null;
1777 var stderr_bytes: ?[]const u8 = null;1771 var stderr_bytes: ?[]const u8 = null;
17781772
1779 run.stdio_limit = .limited(run.stdio_limit.min(run.max_stdio_size));1773 run.stdio_limit = run.stdio_limit.min(.limited(run.max_stdio_size));
1780 if (child.stdout) |stdout| {1774 if (child.stdout) |stdout| {
1781 if (child.stderr) |stderr| {1775 if (child.stderr) |stderr| {
1782 var poller = std.io.poll(arena, enum { stdout, stderr }, .{1776 var poller = std.io.poll(arena, enum { stdout, stderr }, .{
...@@ -1787,15 +1781,15 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {...@@ -1787,15 +1781,15 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
17871781
1788 while (try poller.poll()) {1782 while (try poller.poll()) {
1789 if (run.stdio_limit.toInt()) |limit| {1783 if (run.stdio_limit.toInt()) |limit| {
1790 if (poller.fifo(.stderr).count > limit)1784 if (poller.reader(.stderr).bufferContents().len > limit)
1791 return error.StdoutStreamTooLong;1785 return error.StdoutStreamTooLong;
1792 if (poller.fifo(.stderr).count > limit)1786 if (poller.reader(.stderr).bufferContents().len > limit)
1793 return error.StderrStreamTooLong;1787 return error.StderrStreamTooLong;
1794 }1788 }
1795 }1789 }
17961790
1797 stdout_bytes = try poller.fifo(.stdout).toOwnedSlice();1791 stdout_bytes = poller.reader(.stdout).bufferContents();
1798 stderr_bytes = try poller.fifo(.stderr).toOwnedSlice();1792 stderr_bytes = poller.reader(.stderr).bufferContents();
1799 } else {1793 } else {
1800 stdout_bytes = try stdout.readToEndAlloc(arena, run.stdio_limit);1794 stdout_bytes = try stdout.readToEndAlloc(arena, run.stdio_limit);
1801 }1795 }
lib/std/fs/path.zig+5-6
...@@ -150,27 +150,26 @@ pub fn fmtJoin(paths: []const []const u8) std.fmt.Formatter(formatJoin) {...@@ -150,27 +150,26 @@ pub fn fmtJoin(paths: []const []const u8) std.fmt.Formatter(formatJoin) {
150 return .{ .data = paths };150 return .{ .data = paths };
151}151}
152152
153fn formatJoin(paths: []const []const u8, comptime fmt: []const u8, options: std.fmt.FormatOptions, w: anytype) !void {153fn formatJoin(paths: []const []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
154 _ = fmt;154 _ = fmt;
155 _ = options;
156155
157 const first_path_idx = for (paths, 0..) |p, idx| {156 const first_path_idx = for (paths, 0..) |p, idx| {
158 if (p.len != 0) break idx;157 if (p.len != 0) break idx;
159 } else return;158 } else return;
160159
161 try w.writeAll(paths[first_path_idx]); // first component160 try bw.writeAll(paths[first_path_idx]); // first component
162 var prev_path = paths[first_path_idx];161 var prev_path = paths[first_path_idx];
163 for (paths[first_path_idx + 1 ..]) |this_path| {162 for (paths[first_path_idx + 1 ..]) |this_path| {
164 if (this_path.len == 0) continue; // skip empty components163 if (this_path.len == 0) continue; // skip empty components
165 const prev_sep = isSep(prev_path[prev_path.len - 1]);164 const prev_sep = isSep(prev_path[prev_path.len - 1]);
166 const this_sep = isSep(this_path[0]);165 const this_sep = isSep(this_path[0]);
167 if (!prev_sep and !this_sep) {166 if (!prev_sep and !this_sep) {
168 try w.writeByte(sep);167 try bw.writeByte(sep);
169 }168 }
170 if (prev_sep and this_sep) {169 if (prev_sep and this_sep) {
171 try w.writeAll(this_path[1..]); // skip redundant separator170 try bw.writeAll(this_path[1..]); // skip redundant separator
172 } else {171 } else {
173 try w.writeAll(this_path);172 try bw.writeAll(this_path);
174 }173 }
175 prev_path = this_path;174 prev_path = this_path;
176 }175 }
lib/std/http/WebSocket.zig+7-11
...@@ -9,7 +9,7 @@ const native_endian = builtin.cpu.arch.endian();...@@ -9,7 +9,7 @@ const native_endian = builtin.cpu.arch.endian();
9key: []const u8,9key: []const u8,
10request: *std.http.Server.Request,10request: *std.http.Server.Request,
11recv_fifo: std.fifo.LinearFifo(u8, .Slice),11recv_fifo: std.fifo.LinearFifo(u8, .Slice),
12reader: *std.io.BufferedReader,12reader: std.io.BufferedReader,
13response: std.http.Server.Response,13response: std.http.Server.Response,
14/// Number of bytes that have been peeked but not discarded yet.14/// Number of bytes that have been peeked but not discarded yet.
15outstanding_len: usize,15outstanding_len: usize,
...@@ -20,7 +20,6 @@ pub const InitError = error{WebSocketUpgradeMissingKey} ||...@@ -20,7 +20,6 @@ pub const InitError = error{WebSocketUpgradeMissingKey} ||
20pub fn init(20pub fn init(
21 ws: *WebSocket,21 ws: *WebSocket,
22 request: *std.http.Server.Request,22 request: *std.http.Server.Request,
23 send_buffer: []u8,
24 recv_buffer: []align(4) u8,23 recv_buffer: []align(4) u8,
25) InitError!bool {24) InitError!bool {
26 switch (request.head.version) {25 switch (request.head.version) {
...@@ -58,9 +57,8 @@ pub fn init(...@@ -58,9 +57,8 @@ pub fn init(
58 ws.* = .{57 ws.* = .{
59 .key = key,58 .key = key,
60 .recv_fifo = .init(recv_buffer),59 .recv_fifo = .init(recv_buffer),
61 .reader = undefined,60 .reader = (try request.reader()).unbuffered(),
62 .response = request.respondStreaming(.{61 .response = try request.respondStreaming(.{
63 .send_buffer = send_buffer,
64 .respond_options = .{62 .respond_options = .{
65 .status = .switching_protocols,63 .status = .switching_protocols,
66 .extra_headers = &.{64 .extra_headers = &.{
...@@ -74,7 +72,6 @@ pub fn init(...@@ -74,7 +72,6 @@ pub fn init(
74 .request = request,72 .request = request,
75 .outstanding_len = 0,73 .outstanding_len = 0,
76 };74 };
77 ws.reader.init(try request.reader(), &.{});
78 return true;75 return true;
79}76}
8077
...@@ -239,9 +236,8 @@ pub fn writeMessagev(ws: *WebSocket, message: []const std.posix.iovec_const, opc...@@ -239,9 +236,8 @@ pub fn writeMessagev(ws: *WebSocket, message: []const std.posix.iovec_const, opc
239 },236 },
240 };237 };
241238
242 const response = &ws.response;239 var bw = ws.response.writer().unbuffered();
243 try response.writeAll(header);240 try bw.writeAll(header);
244 for (message) |iovec|241 for (message) |iovec| try bw.writeAll(iovec.base[0..iovec.len]);
245 try response.writeAll(iovec.base[0..iovec.len]);242 try bw.flush();
246 try response.flush();
247}243}
lib/std/io.zig+6-7
...@@ -53,7 +53,12 @@ pub fn poll(...@@ -53,7 +53,12 @@ pub fn poll(
53 const enum_fields = @typeInfo(StreamEnum).@"enum".fields;53 const enum_fields = @typeInfo(StreamEnum).@"enum".fields;
54 var result: Poller(StreamEnum) = .{54 var result: Poller(StreamEnum) = .{
55 .gpa = gpa,55 .gpa = gpa,
56 .readers = undefined,56 .readers = @splat(.{
57 .unbuffered_reader = .failing,
58 .buffer = &.{},
59 .end = 0,
60 .seek = 0,
61 }),
57 .poll_fds = undefined,62 .poll_fds = undefined,
58 .windows = if (is_windows) .{63 .windows = if (is_windows) .{
59 .first_read_done = false,64 .first_read_done = false,
...@@ -70,12 +75,6 @@ pub fn poll(...@@ -70,12 +75,6 @@ pub fn poll(
70 };75 };
7176
72 inline for (enum_fields, 0..) |field, i| {77 inline for (enum_fields, 0..) |field, i| {
73 result.readers[i] = .{
74 .unbuffered_reader = .failing,
75 .buffer = &.{},
76 .end = 0,
77 .seek = 0,
78 };
79 if (is_windows) {78 if (is_windows) {
80 result.windows.active.handles_buf[i] = @field(files, field.name).handle;79 result.windows.active.handles_buf[i] = @field(files, field.name).handle;
81 } else {80 } else {
lib/std/io/BufferedReader.zig+57-18
...@@ -51,6 +51,23 @@ pub fn readVec(br: *BufferedReader, data: []const []u8) Reader.Error!usize {...@@ -51,6 +51,23 @@ pub fn readVec(br: *BufferedReader, data: []const []u8) Reader.Error!usize {
51 return passthruReadVec(br, data);51 return passthruReadVec(br, data);
52}52}
5353
54pub fn readVecAll(br: *BufferedReader, data: [][]u8) Reader.Error!void {
55 var index: usize = 0;
56 var truncate: usize = 0;
57 while (index < data.len) {
58 {
59 const untruncated = data[index];
60 data[index] = untruncated[truncate..];
61 defer data[index] = untruncated;
62 truncate += try br.readVec(data[index..]);
63 }
64 while (index < data.len and truncate <= data[index].len) {
65 truncate -= data[index].len;
66 index += 1;
67 }
68 }
69}
70
54pub fn read(br: *BufferedReader, bw: *BufferedWriter, limit: Reader.Limit) Reader.RwError!usize {71pub fn read(br: *BufferedReader, bw: *BufferedWriter, limit: Reader.Limit) Reader.RwError!usize {
55 return passthruRead(br, bw, limit);72 return passthruRead(br, bw, limit);
56}73}
...@@ -58,8 +75,8 @@ pub fn read(br: *BufferedReader, bw: *BufferedWriter, limit: Reader.Limit) Reade...@@ -58,8 +75,8 @@ pub fn read(br: *BufferedReader, bw: *BufferedWriter, limit: Reader.Limit) Reade
58/// "Pump" data from the reader to the writer.75/// "Pump" data from the reader to the writer.
59pub fn readAll(br: *BufferedReader, bw: *BufferedWriter, limit: Reader.Limit) Reader.RwError!void {76pub fn readAll(br: *BufferedReader, bw: *BufferedWriter, limit: Reader.Limit) Reader.RwError!void {
60 var remaining = limit;77 var remaining = limit;
61 while (true) {78 while (remaining.nonzero()) {
62 const n = try passthruRead(br, bw, remaining);79 const n = try br.read(bw, remaining);
63 remaining = remaining.subtract(n).?;80 remaining = remaining.subtract(n).?;
64 }81 }
65}82}
...@@ -68,7 +85,7 @@ fn passthruRead(ctx: ?*anyopaque, bw: *BufferedWriter, limit: Reader.Limit) Read...@@ -68,7 +85,7 @@ fn passthruRead(ctx: ?*anyopaque, bw: *BufferedWriter, limit: Reader.Limit) Read
68 const br: *BufferedReader = @alignCast(@ptrCast(ctx));85 const br: *BufferedReader = @alignCast(@ptrCast(ctx));
69 const buffer = br.buffer[0..br.end];86 const buffer = br.buffer[0..br.end];
70 const buffered = buffer[br.seek..];87 const buffered = buffer[br.seek..];
71 const limited = buffered[0..limit.min(buffered.len)];88 const limited = buffered[0..limit.minInt(buffered.len)];
72 if (limited.len > 0) {89 if (limited.len > 0) {
73 const n = try bw.write(limited);90 const n = try bw.write(limited);
74 br.seek += n;91 br.seek += n;
...@@ -93,7 +110,7 @@ fn passthruReadVec(ctx: ?*anyopaque, data: []const []u8) Reader.Error!usize {...@@ -93,7 +110,7 @@ fn passthruReadVec(ctx: ?*anyopaque, data: []const []u8) Reader.Error!usize {
93 vecs[0] = buf[copy_len..];110 vecs[0] = buf[copy_len..];
94 const vecs_len: usize = @min(vecs.len, data.len - i);111 const vecs_len: usize = @min(vecs.len, data.len - i);
95 var vec_data_len: usize = vecs[0].len;112 var vec_data_len: usize = vecs[0].len;
96 for (&vecs[1..vecs_len], data[i + 1 ..][0 .. vecs_len - 1]) |*v, d| {113 for (vecs[1..vecs_len], data[i + 1 ..][0 .. vecs_len - 1]) |*v, d| {
97 vec_data_len += d.len;114 vec_data_len += d.len;
98 v.* = d;115 v.* = d;
99 }116 }
...@@ -149,7 +166,6 @@ pub fn seekForwardBy(br: *BufferedReader, seek_by: u64) !void {...@@ -149,7 +166,6 @@ pub fn seekForwardBy(br: *BufferedReader, seek_by: u64) !void {
149/// * `peek`166/// * `peek`
150/// * `toss`167/// * `toss`
151pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {168pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {
152 assert(n <= br.buffer.len);
153 try br.fill(n);169 try br.fill(n);
154 return br.buffer[br.seek..][0..n];170 return br.buffer[br.seek..][0..n];
155}171}
...@@ -169,7 +185,6 @@ pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {...@@ -169,7 +185,6 @@ pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {
169/// * `peek`185/// * `peek`
170/// * `toss`186/// * `toss`
171pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {187pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {
172 assert(n <= br.buffer.len);
173 try br.fill(n);188 try br.fill(n);
174 return br.buffer[br.seek..br.end];189 return br.buffer[br.seek..br.end];
175}190}
...@@ -448,10 +463,12 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter...@@ -448,10 +463,12 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter
448 @branchHint(.likely);463 @branchHint(.likely);
449 return buffer[seek .. end + 1];464 return buffer[seek .. end + 1];
450 }465 }
451 const remainder = buffer[seek..];466 if (seek > 0) {
452 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);467 const remainder = buffer[seek..];
453 br.end = remainder.len;468 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
454 br.seek = 0;469 br.end = remainder.len;
470 br.seek = 0;
471 }
455 while (br.end < br.buffer.len) {472 while (br.end < br.buffer.len) {
456 const n = try br.unbuffered_reader.readVec(&.{br.buffer[br.end..]});473 const n = try br.unbuffered_reader.readVec(&.{br.buffer[br.end..]});
457 const prev_end = br.end;474 const prev_end = br.end;
...@@ -550,10 +567,12 @@ pub fn fill(br: *BufferedReader, n: usize) Reader.Error!void {...@@ -550,10 +567,12 @@ pub fn fill(br: *BufferedReader, n: usize) Reader.Error!void {
550 @branchHint(.likely);567 @branchHint(.likely);
551 return;568 return;
552 }569 }
553 const remainder = buffer[seek..];570 if (seek > 0) {
554 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);571 const remainder = buffer[seek..];
555 br.end = remainder.len;572 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
556 br.seek = 0;573 br.end = remainder.len;
574 br.seek = 0;
575 }
557 while (true) {576 while (true) {
558 br.end += try br.unbuffered_reader.readVec(&.{br.buffer[br.end..]});577 br.end += try br.unbuffered_reader.readVec(&.{br.buffer[br.end..]});
559 if (n <= br.end) return;578 if (n <= br.end) return;
...@@ -665,15 +684,35 @@ pub fn writableSliceGreedyAlloc(...@@ -665,15 +684,35 @@ pub fn writableSliceGreedyAlloc(
665 allocator: Allocator,684 allocator: Allocator,
666 min_len: usize,685 min_len: usize,
667) error{OutOfMemory}![]u8 {686) error{OutOfMemory}![]u8 {
668 _ = br;687 {
669 _ = allocator;688 const unused = br.buffer[br.end..];
670 _ = min_len;689 if (unused.len >= min_len) return unused;
671 @panic("TODO");690 }
691 const seek = br.seek;
692 if (seek > 0) {
693 const buffer = br.buffer[0..br.end];
694 const remainder = buffer[seek..];
695 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
696 br.end = remainder.len;
697 br.seek = 0;
698 }
699 {
700 var list: std.ArrayListUnmanaged(u8) = .{
701 .items = br.buffer[0..br.end],
702 .capacity = br.buffer.len,
703 };
704 defer br.buffer = list.allocatedSlice();
705 try list.ensureUnusedCapacity(allocator, min_len);
706 }
707 const unused = br.buffer[br.end..];
708 assert(unused.len >= min_len);
709 return unused;
672}710}
673711
674/// After writing directly into the unused capacity of `buffer`, this function712/// After writing directly into the unused capacity of `buffer`, this function
675/// updates `end` so that users of `BufferedReader` can receive the data.713/// updates `end` so that users of `BufferedReader` can receive the data.
676pub fn advanceBufferEnd(br: *BufferedReader, n: usize) void {714pub fn advanceBufferEnd(br: *BufferedReader, n: usize) void {
715 assert(n <= br.buffer.len - br.end);
677 br.end += n;716 br.end += n;
678}717}
679718
lib/std/io/BufferedWriter.zig+12-9
...@@ -141,16 +141,19 @@ pub fn advance(bw: *BufferedWriter, n: usize) void {...@@ -141,16 +141,19 @@ pub fn advance(bw: *BufferedWriter, n: usize) void {
141/// The `data` parameter is mutable because this function needs to mutate the141/// The `data` parameter is mutable because this function needs to mutate the
142/// fields in order to handle partial writes from `Writer.VTable.writeVec`.142/// fields in order to handle partial writes from `Writer.VTable.writeVec`.
143pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void {143pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void {
144 var i: usize = 0;144 var index: usize = 0;
145 while (true) {145 var truncate: usize = 0;
146 var n = try passthruWriteSplat(bw, data[i..], 1);146 while (index < data.len) {
147 const len = data[i].len;147 {
148 while (n >= len) {148 const untruncated = data[index];
149 n -= len;149 data[index] = untruncated[truncate..];
150 i += 1;150 defer data[index] = untruncated;
151 if (i >= data.len) return;151 truncate += try bw.writeVec(data[index..]);
152 }
153 while (index < data.len and truncate <= data[index].len) {
154 truncate -= data[index].len;
155 index += 1;
152 }156 }
153 data[i] = data[i][n..];
154 }157 }
155}158}
156159
lib/std/io/Reader.zig+1-1
...@@ -94,7 +94,7 @@ pub const Limit = enum(usize) {...@@ -94,7 +94,7 @@ pub const Limit = enum(usize) {
94 }94 }
9595
96 pub fn slice(l: Limit, s: []u8) []u8 {96 pub fn slice(l: Limit, s: []u8) []u8 {
97 return s[0..min(l, s.len)];97 return s[0..l.minInt(s.len)];
98 }98 }
9999
100 pub fn toInt(l: Limit) ?usize {100 pub fn toInt(l: Limit) ?usize {
lib/std/process/Child.zig+9-10
...@@ -348,16 +348,15 @@ pub const RunResult = struct {...@@ -348,16 +348,15 @@ pub const RunResult = struct {
348 stderr: []u8,348 stderr: []u8,
349};349};
350350
351fn writeFifoDataToArrayList(allocator: Allocator, list: *std.ArrayListUnmanaged(u8), fifo: *std.io.PollFifo) !void {351fn writeBufferedReaderToArrayList(allocator: Allocator, list: *std.ArrayListUnmanaged(u8), br: *std.io.BufferedReader) !void {
352 if (fifo.head != 0) fifo.realign();352 assert(br.seek == 0);
353 if (list.capacity == 0) {353 if (list.capacity == 0) {
354 list.* = .{354 list.* = .{
355 .items = fifo.buf[0..fifo.count],355 .items = br.bufferContents(),
356 .capacity = fifo.buf.len,356 .capacity = br.buffer.len,
357 };357 };
358 fifo.* = std.io.PollFifo.init(fifo.allocator);
359 } else {358 } else {
360 try list.appendSlice(allocator, fifo.buf[0..fifo.count]);359 try list.appendSlice(allocator, br.bufferContents());
361 }360 }
362}361}
363362
...@@ -384,14 +383,14 @@ pub fn collectOutput(...@@ -384,14 +383,14 @@ pub fn collectOutput(
384 defer poller.deinit();383 defer poller.deinit();
385384
386 while (try poller.poll()) {385 while (try poller.poll()) {
387 if (poller.fifo(.stdout).count > max_output_bytes)386 if (poller.reader(.stdout).bufferContents().len > max_output_bytes)
388 return error.StdoutStreamTooLong;387 return error.StdoutStreamTooLong;
389 if (poller.fifo(.stderr).count > max_output_bytes)388 if (poller.reader(.stderr).bufferContents().len > max_output_bytes)
390 return error.StderrStreamTooLong;389 return error.StderrStreamTooLong;
391 }390 }
392391
393 try writeFifoDataToArrayList(allocator, stdout, poller.fifo(.stdout));392 try writeBufferedReaderToArrayList(allocator, stdout, poller.reader(.stdout));
394 try writeFifoDataToArrayList(allocator, stderr, poller.fifo(.stderr));393 try writeBufferedReaderToArrayList(allocator, stderr, poller.reader(.stderr));
395}394}
396395
397pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{396pub const RunError = posix.GetCwdError || posix.ReadError || SpawnError || posix.PollError || error{
lib/std/zig/ZonGen.zig+1-1
...@@ -522,7 +522,7 @@ pub fn parseStrLit(...@@ -522,7 +522,7 @@ pub fn parseStrLit(
522 tree: Ast,522 tree: Ast,
523 node: Ast.Node.Index,523 node: Ast.Node.Index,
524 writer: *std.io.BufferedWriter,524 writer: *std.io.BufferedWriter,
525) error{OutOfMemory}!std.zig.string_literal.Result {525) std.io.Writer.Error!std.zig.string_literal.Result {
526 switch (tree.nodeTag(node)) {526 switch (tree.nodeTag(node)) {
527 .string_literal => {527 .string_literal => {
528 const token = tree.nodeMainToken(node);528 const token = tree.nodeMainToken(node);
src/Air/print.zig+3-3
...@@ -72,9 +72,9 @@ pub fn writeInst(...@@ -72,9 +72,9 @@ pub fn writeInst(
72}72}
7373
74pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {74pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
75 var bw = std.debug.lockStdErr2(&.{});75 const stderr_bw = std.debug.lockStderrWriter(&.{});
76 defer std.debug.unlockStdErr();76 defer std.debug.unlockStderrWriter();
77 air.write(&bw, pt, liveness);77 air.write(stderr_bw, pt, liveness);
78}78}
7979
80pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {80pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
src/Compilation.zig+6-8
...@@ -1881,14 +1881,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1881,14 +1881,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
18811881
1882 if (options.verbose_llvm_cpu_features) {1882 if (options.verbose_llvm_cpu_features) {
1883 if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {1883 if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {
1884 var stderr = std.debug.lockStdErr2(&.{});1884 const stderr_bw = std.debug.lockStderrWriter(&.{});
1885 defer std.debug.unlockStdErr();1885 defer std.debug.unlockStderrWriter();
1886 nosuspend {1886 stderr_bw.print("compilation: {s}\n", .{options.root_name}) catch break :print;
1887 stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print;1887 stderr_bw.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;
1888 stderr.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;1888 stderr_bw.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print;
1889 stderr.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print;1889 stderr_bw.print(" features: {s}\n", .{cf}) catch {};
1890 stderr.print(" features: {s}\n", .{cf}) catch {};
1891 }
1892 }1890 }
1893 }1891 }
18941892
src/InternPool.zig+14-17
...@@ -11263,8 +11263,8 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -11263,8 +11263,8 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1126311263
11264fn dumpAllFallible(ip: *const InternPool) anyerror!void {11264fn dumpAllFallible(ip: *const InternPool) anyerror!void {
11265 var buffer: [4096]u8 = undefined;11265 var buffer: [4096]u8 = undefined;
11266 var bw = std.debug.lockStdErr2(&buffer);11266 const stderr_bw = std.debug.lockStderrWriter(&buffer);
11267 defer std.debug.unlockStdErr();11267 defer std.debug.unlockStderrWriter();
11268 for (ip.locals, 0..) |*local, tid| {11268 for (ip.locals, 0..) |*local, tid| {
11269 const items = local.shared.items.view();11269 const items = local.shared.items.view();
11270 for (11270 for (
...@@ -11273,12 +11273,12 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -11273,12 +11273,12 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
11273 0..,11273 0..,
11274 ) |tag, data, index| {11274 ) |tag, data, index| {
11275 const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip);11275 const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip);
11276 try bw.print("${d} = {s}(", .{ i, @tagName(tag) });11276 try stderr_bw.print("${d} = {s}(", .{ i, @tagName(tag) });
11277 switch (tag) {11277 switch (tag) {
11278 .removed => {},11278 .removed => {},
1127911279
11280 .simple_type => try bw.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}),11280 .simple_type => try stderr_bw.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(@intFromEnum(i))))}),
11281 .simple_value => try bw.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}),11281 .simple_value => try stderr_bw.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(@intFromEnum(i))))}),
1128211282
11283 .type_int_signed,11283 .type_int_signed,
11284 .type_int_unsigned,11284 .type_int_unsigned,
...@@ -11351,17 +11351,16 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -11351,17 +11351,16 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
11351 .func_coerced,11351 .func_coerced,
11352 .union_value,11352 .union_value,
11353 .memoized_call,11353 .memoized_call,
11354 => try bw.print("{d}", .{data}),11354 => try stderr_bw.print("{d}", .{data}),
1135511355
11356 .opt_null,11356 .opt_null,
11357 .type_slice,11357 .type_slice,
11358 .only_possible_value,11358 .only_possible_value,
11359 => try bw.print("${d}", .{data}),11359 => try stderr_bw.print("${d}", .{data}),
11360 }11360 }
11361 try bw.writeAll(")\n");11361 try stderr_bw.writeAll(")\n");
11362 }11362 }
11363 }11363 }
11364 try bw.flush();
11365}11364}
1136611365
11367pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void {11366pub fn dumpGenericInstances(ip: *const InternPool, allocator: Allocator) void {
...@@ -11396,8 +11395,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -11396,8 +11395,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
11396 }11395 }
1139711396
11398 var buffer: [4096]u8 = undefined;11397 var buffer: [4096]u8 = undefined;
11399 var bw = std.debug.lockStdErr2(&buffer);11398 const stderr_bw = std.debug.lockStderrWriter(&buffer);
11400 defer std.debug.unlockStdErr();11399 defer std.debug.unlockStderrWriter();
1140111400
11402 const SortContext = struct {11401 const SortContext = struct {
11403 values: []std.ArrayListUnmanaged(Index),11402 values: []std.ArrayListUnmanaged(Index),
...@@ -11410,23 +11409,21 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -11410,23 +11409,21 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
11410 var it = instances.iterator();11409 var it = instances.iterator();
11411 while (it.next()) |entry| {11410 while (it.next()) |entry| {
11412 const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);11411 const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);
11413 try bw.print("{f} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });11412 try stderr_bw.print("{f} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
11414 for (entry.value_ptr.items) |index| {11413 for (entry.value_ptr.items) |index| {
11415 const unwrapped_index = index.unwrap(ip);11414 const unwrapped_index = index.unwrap(ip);
11416 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));11415 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
11417 const owner_nav = ip.getNav(func.owner_nav);11416 const owner_nav = ip.getNav(func.owner_nav);
11418 try bw.print(" {f}: (", .{owner_nav.name.fmt(ip)});11417 try stderr_bw.print(" {f}: (", .{owner_nav.name.fmt(ip)});
11419 for (func.comptime_args.get(ip)) |arg| {11418 for (func.comptime_args.get(ip)) |arg| {
11420 if (arg != .none) {11419 if (arg != .none) {
11421 const key = ip.indexToKey(arg);11420 const key = ip.indexToKey(arg);
11422 try bw.print(" {} ", .{key});11421 try stderr_bw.print(" {} ", .{key});
11423 }11422 }
11424 }11423 }
11425 try bw.writeAll(")\n");11424 try stderr_bw.writeAll(")\n");
11426 }11425 }
11427 }11426 }
11428
11429 try bw.flush();
11430}11427}
1143111428
11432pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav {11429pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav {
src/Zcu.zig+61-140
...@@ -1043,12 +1043,12 @@ pub const File = struct {...@@ -1043,12 +1043,12 @@ pub const File = struct {
1043 if (stat.size > std.math.maxInt(u32))1043 if (stat.size > std.math.maxInt(u32))
1044 return error.FileTooBig;1044 return error.FileTooBig;
10451045
1046 const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);1046 const source = try gpa.allocSentinel(u8, @intCast(stat.size), 0);
1047 errdefer gpa.free(source);1047 errdefer gpa.free(source);
10481048
1049 const amt = try f.readAll(source);1049 var fr = f.reader();
1050 if (amt != stat.size)1050 var br = fr.interface().unbuffered();
1051 return error.UnexpectedEndOfFile;1051 try br.readSlice(source);
10521052
1053 // Here we do not modify stat fields because this function is the one1053 // Here we do not modify stat fields because this function is the one
1054 // used for error reporting. We need to keep the stat fields stale so that1054 // used for error reporting. We need to keep the stat fields stale so that
...@@ -2845,34 +2845,21 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.F...@@ -2845,34 +2845,21 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.F
2845 undefined;2845 undefined;
2846 defer if (data_has_safety_tag) gpa.free(safety_buffer);2846 defer if (data_has_safety_tag) gpa.free(safety_buffer);
28472847
2848 const data_ptr = if (data_has_safety_tag)2848 var vecs = [_][]u8{
2849 @as([*]u8, @ptrCast(safety_buffer.ptr))2849 @ptrCast(zir.instructions.items(.tag)),
2850 else2850 if (data_has_safety_tag)
2851 @as([*]u8, @ptrCast(zir.instructions.items(.data).ptr));2851 @ptrCast(safety_buffer)
28522852 else
2853 var iovecs = [_]std.posix.iovec{2853 zir.instructions.items(.data),
2854 .{2854 zir.string_bytes,
2855 .base = @as([*]u8, @ptrCast(zir.instructions.items(.tag).ptr)),2855 @ptrCast(zir.extra),
2856 .len = header.instructions_len,2856 };
2857 },2857 var cache_fr = cache_file.reader();
2858 .{2858 var cache_br = cache_fr.interface().unbuffered();
2859 .base = data_ptr,2859 cache_br.readVecAll(&vecs) catch |err| switch (err) {
2860 .len = header.instructions_len * 8,2860 error.ReadFailed => if (cache_fr.err) |_| unreachable else |e| return e,
2861 },2861 error.EndOfStream => return error.UnexpectedFileSize,
2862 .{
2863 .base = zir.string_bytes.ptr,
2864 .len = header.string_bytes_len,
2865 },
2866 .{
2867 .base = @as([*]u8, @ptrCast(zir.extra.ptr)),
2868 .len = header.extra_len * 4,
2869 },
2870 };2862 };
2871 const amt_read = try cache_file.readvAll(&iovecs);
2872 const amt_expected = zir.instructions.len * 9 +
2873 zir.string_bytes.len +
2874 zir.extra.len * 4;
2875 if (amt_read != amt_expected) return error.UnexpectedFileSize;
2876 if (data_has_safety_tag) {2863 if (data_has_safety_tag) {
2877 const tags = zir.instructions.items(.tag);2864 const tags = zir.instructions.items(.tag);
2878 for (zir.instructions.items(.data), 0..) |*data, i| {2865 for (zir.instructions.items(.data), 0..) |*data, i| {
...@@ -2895,14 +2882,6 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S...@@ -2895,14 +2882,6 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S
2895 undefined;2882 undefined;
2896 defer if (data_has_safety_tag) gpa.free(safety_buffer);2883 defer if (data_has_safety_tag) gpa.free(safety_buffer);
28972884
2898 const data_ptr: [*]const u8 = if (data_has_safety_tag)
2899 if (zir.instructions.len == 0)
2900 undefined
2901 else
2902 @ptrCast(safety_buffer.ptr)
2903 else
2904 @ptrCast(zir.instructions.items(.data).ptr);
2905
2906 if (data_has_safety_tag) {2885 if (data_has_safety_tag) {
2907 // The `Data` union has a safety tag but in the file format we store it without.2886 // The `Data` union has a safety tag but in the file format we store it without.
2908 for (zir.instructions.items(.data), 0..) |*data, i| {2887 for (zir.instructions.items(.data), 0..) |*data, i| {
...@@ -2920,29 +2899,21 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S...@@ -2920,29 +2899,21 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S
2920 .stat_inode = stat.inode,2899 .stat_inode = stat.inode,
2921 .stat_mtime = stat.mtime,2900 .stat_mtime = stat.mtime,
2922 };2901 };
2923 var iovecs: [5]std.posix.iovec_const = .{2902 var vecs = [_][]const u8{
2924 .{2903 @ptrCast((&header)[0..1]),
2925 .base = @ptrCast(&header),2904 @ptrCast(zir.instructions.items(.tag)),
2926 .len = @sizeOf(Zir.Header),2905 if (data_has_safety_tag)
2927 },2906 @ptrCast(safety_buffer)
2928 .{2907 else
2929 .base = @ptrCast(zir.instructions.items(.tag).ptr),2908 @ptrCast(zir.instructions.items(.data)),
2930 .len = zir.instructions.len,2909 zir.string_bytes,
2931 },2910 @ptrCast(zir.extra),
2932 .{2911 };
2933 .base = data_ptr,2912 var cache_fw = cache_file.writer();
2934 .len = zir.instructions.len * 8,2913 var cache_bw = cache_fw.interface().unbuffered();
2935 },2914 cache_bw.writeVecAll(&vecs) catch |err| switch (err) {
2936 .{2915 error.WriteFailed => if (cache_fw.err) |_| unreachable else |e| return e,
2937 .base = zir.string_bytes.ptr,
2938 .len = zir.string_bytes.len,
2939 },
2940 .{
2941 .base = @ptrCast(zir.extra.ptr),
2942 .len = zir.extra.len * 4,
2943 },
2944 };2916 };
2945 try cache_file.writevAll(&iovecs);
2946}2917}
29472918
2948pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir) std.fs.File.WriteError!void {2919pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir) std.fs.File.WriteError!void {
...@@ -2958,45 +2929,22 @@ pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir...@@ -2958,45 +2929,22 @@ pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir
2958 .stat_inode = stat.inode,2929 .stat_inode = stat.inode,
2959 .stat_mtime = stat.mtime,2930 .stat_mtime = stat.mtime,
2960 };2931 };
2961 var iovecs: [9]std.posix.iovec_const = .{2932 var vecs = [_][]const u8{
2962 .{2933 @ptrCast((&header)[0..1]),
2963 .base = @ptrCast(&header),2934 @ptrCast(zoir.nodes.items(.tag)),
2964 .len = @sizeOf(Zoir.Header),2935 @ptrCast(zoir.nodes.items(.data)),
2965 },2936 @ptrCast(zoir.nodes.items(.ast_node)),
2966 .{2937 @ptrCast(zoir.extra),
2967 .base = @ptrCast(zoir.nodes.items(.tag)),2938 @ptrCast(zoir.limbs),
2968 .len = zoir.nodes.len * @sizeOf(Zoir.Node.Repr.Tag),2939 zoir.string_bytes,
2969 },2940 @ptrCast(zoir.compile_errors),
2970 .{2941 @ptrCast(zoir.error_notes),
2971 .base = @ptrCast(zoir.nodes.items(.data)),2942 };
2972 .len = zoir.nodes.len * 4,2943 var cache_fw = cache_file.writer();
2973 },2944 var cache_bw = cache_fw.interface().unbuffered();
2974 .{2945 cache_bw.writeVecAll(&vecs) catch |err| switch (err) {
2975 .base = @ptrCast(zoir.nodes.items(.ast_node)),2946 error.WriteFailed => if (cache_fw.err) |_| unreachable else |e| return e,
2976 .len = zoir.nodes.len * 4,
2977 },
2978 .{
2979 .base = @ptrCast(zoir.extra),
2980 .len = zoir.extra.len * 4,
2981 },
2982 .{
2983 .base = @ptrCast(zoir.limbs),
2984 .len = zoir.limbs.len * @sizeOf(std.math.big.Limb),
2985 },
2986 .{
2987 .base = zoir.string_bytes.ptr,
2988 .len = zoir.string_bytes.len,
2989 },
2990 .{
2991 .base = @ptrCast(zoir.compile_errors),
2992 .len = zoir.compile_errors.len * @sizeOf(Zoir.CompileError),
2993 },
2994 .{
2995 .base = @ptrCast(zoir.error_notes),
2996 .len = zoir.error_notes.len * @sizeOf(Zoir.CompileError.Note),
2997 },
2998 };2947 };
2999 try cache_file.writevAll(&iovecs);
3000}2948}
30012949
3002pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs.File) !Zoir {2950pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs.File) !Zoir {
...@@ -3025,49 +2973,22 @@ pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs...@@ -3025,49 +2973,22 @@ pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs
3025 zoir.compile_errors = try gpa.alloc(Zoir.CompileError, header.compile_errors_len);2973 zoir.compile_errors = try gpa.alloc(Zoir.CompileError, header.compile_errors_len);
3026 zoir.error_notes = try gpa.alloc(Zoir.CompileError.Note, header.error_notes_len);2974 zoir.error_notes = try gpa.alloc(Zoir.CompileError.Note, header.error_notes_len);
30272975
3028 var iovecs: [8]std.posix.iovec = .{2976 var vecs = [_][]u8{
3029 .{2977 @ptrCast(zoir.nodes.items(.tag)),
3030 .base = @ptrCast(zoir.nodes.items(.tag)),2978 @ptrCast(zoir.nodes.items(.data)),
3031 .len = header.nodes_len * @sizeOf(Zoir.Node.Repr.Tag),2979 @ptrCast(zoir.nodes.items(.ast_node)),
3032 },2980 @ptrCast(zoir.extra),
3033 .{2981 @ptrCast(zoir.limbs),
3034 .base = @ptrCast(zoir.nodes.items(.data)),2982 zoir.string_bytes,
3035 .len = header.nodes_len * 4,2983 @ptrCast(zoir.compile_errors),
3036 },2984 @ptrCast(zoir.error_notes),
3037 .{
3038 .base = @ptrCast(zoir.nodes.items(.ast_node)),
3039 .len = header.nodes_len * 4,
3040 },
3041 .{
3042 .base = @ptrCast(zoir.extra),
3043 .len = header.extra_len * 4,
3044 },
3045 .{
3046 .base = @ptrCast(zoir.limbs),
3047 .len = header.limbs_len * @sizeOf(std.math.big.Limb),
3048 },
3049 .{
3050 .base = zoir.string_bytes.ptr,
3051 .len = header.string_bytes_len,
3052 },
3053 .{
3054 .base = @ptrCast(zoir.compile_errors),
3055 .len = header.compile_errors_len * @sizeOf(Zoir.CompileError),
3056 },
3057 .{
3058 .base = @ptrCast(zoir.error_notes),
3059 .len = header.error_notes_len * @sizeOf(Zoir.CompileError.Note),
3060 },
3061 };2985 };
30622986 var cache_fr = cache_file.reader();
3063 const bytes_expected = expected: {2987 var cache_br = cache_fr.interface().unbuffered();
3064 var n: usize = 0;2988 cache_br.readVecAll(&vecs) catch |err| switch (err) {
3065 for (iovecs) |v| n += v.len;2989 error.ReadFailed => if (cache_fr.err) |_| unreachable else |e| return e,
3066 break :expected n;2990 error.EndOfStream => return error.UnexpectedFileSize,
3067 };2991 };
3068
3069 const bytes_read = try cache_file.readvAll(&iovecs);
3070 if (bytes_read != bytes_expected) return error.UnexpectedFileSize;
3071 return zoir;2992 return zoir;
3072}2993}
30732994
src/Zcu/PerThread.zig+19-8
...@@ -249,11 +249,14 @@ pub fn updateFile(...@@ -249,11 +249,14 @@ pub fn updateFile(
249 if (stat.size > std.math.maxInt(u32))249 if (stat.size > std.math.maxInt(u32))
250 return error.FileTooBig;250 return error.FileTooBig;
251251
252 const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);252 const source = try gpa.allocSentinel(u8, @intCast(stat.size), 0);
253 defer if (file.source == null) gpa.free(source);253 defer if (file.source == null) gpa.free(source);
254 const amt = try source_file.readAll(source);254 var source_fr = source_file.reader();
255 if (amt != stat.size)255 var source_br = source_fr.interface().unbuffered();
256 return error.UnexpectedEndOfFile;256 source_br.readSlice(source) catch |err| switch (err) {
257 error.ReadFailed => if (source_fr.err) |_| unreachable else |e| return e,
258 error.EndOfStream => return error.UnexpectedEndOfFile,
259 };
257260
258 file.source = source;261 file.source = source;
259262
...@@ -340,13 +343,17 @@ fn loadZirZoirCache(...@@ -340,13 +343,17 @@ fn loadZirZoirCache(
340 .zon => Zoir.Header,343 .zon => Zoir.Header,
341 };344 };
342345
346 var buffer: [@sizeOf(Header)]u8 = undefined;
347 var cache_fr = cache_file.reader();
348 var cache_br = cache_fr.interface().buffered(&buffer);
349
343 // First we read the header to determine the lengths of arrays.350 // First we read the header to determine the lengths of arrays.
344 const header = cache_file.reader().readStruct(Header) catch |err| switch (err) {351 const header = (cache_br.takeStruct(Header) catch |err| switch (err) {
345 // This can happen if Zig bails out of this function between creating352 // This can happen if Zig bails out of this function between creating
346 // the cached file and writing it.353 // the cached file and writing it.
347 error.EndOfStream => return .invalid,354 error.EndOfStream => return .invalid,
348 else => |e| return e,355 else => |e| return e,
349 };356 }).*;
350357
351 const unchanged_metadata =358 const unchanged_metadata =
352 stat.size == header.stat_size and359 stat.size == header.stat_size and
...@@ -2433,8 +2440,12 @@ fn updateEmbedFileInner(...@@ -2433,8 +2440,12 @@ fn updateEmbedFileInner(
2433 const old_len = strings.mutate.len;2440 const old_len = strings.mutate.len;
2434 errdefer strings.shrinkRetainingCapacity(old_len);2441 errdefer strings.shrinkRetainingCapacity(old_len);
2435 const bytes = (try strings.addManyAsSlice(size_plus_one))[0];2442 const bytes = (try strings.addManyAsSlice(size_plus_one))[0];
2436 const actual_read = try file.readAll(bytes[0..size]);2443 var fr = file.reader();
2437 if (actual_read != size) return error.UnexpectedEof;2444 var br = fr.interface().unbuffered();
2445 br.readSlice(bytes[0..size]) catch |err| switch (err) {
2446 error.ReadFailed => if (fr.err) |_| unreachable else |e| return e,
2447 error.EndOfStream => return error.UnexpectedEof,
2448 };
2438 bytes[size] = 0;2449 bytes[size] = 0;
2439 break :str try ip.getOrPutTrailingString(gpa, tid, @intCast(bytes.len), .maybe_embedded_nulls);2450 break :str try ip.getOrPutTrailingString(gpa, tid, @intCast(bytes.len), .maybe_embedded_nulls);
2440 };2451 };
src/crash_report.zig+40-33
...@@ -80,18 +80,19 @@ fn dumpStatusReport() !void {...@@ -80,18 +80,19 @@ fn dumpStatusReport() !void {
80 var fba = std.heap.FixedBufferAllocator.init(&crash_heap);80 var fba = std.heap.FixedBufferAllocator.init(&crash_heap);
81 const allocator = fba.allocator();81 const allocator = fba.allocator();
8282
83 var stderr = std.fs.File.stderr().writer().unbuffered();83 var stderr_fw = std.fs.File.stderr().writer();
84 var stderr_bw = stderr_fw.interface().unbuffered();
84 const block: *Sema.Block = anal.block;85 const block: *Sema.Block = anal.block;
85 const zcu = anal.sema.pt.zcu;86 const zcu = anal.sema.pt.zcu;
8687
87 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse {88 const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse {
88 const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool));89 const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool));
89 try stderr.print("Analyzing lost instruction in file '{f}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)});90 try stderr_bw.print("Analyzing lost instruction in file '{f}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)});
90 return;91 return;
91 };92 };
9293
93 try stderr.writeAll("Analyzing ");94 try stderr_bw.writeAll("Analyzing ");
94 try stderr.print("Analyzing '{f}'\n", .{file.path.fmt(zcu.comp)});95 try stderr_bw.print("Analyzing '{f}'\n", .{file.path.fmt(zcu.comp)});
9596
96 print_zir.renderInstructionContext(97 print_zir.renderInstructionContext(
97 allocator,98 allocator,
...@@ -100,12 +101,12 @@ fn dumpStatusReport() !void {...@@ -100,12 +101,12 @@ fn dumpStatusReport() !void {
100 file,101 file,
101 src_base_node,102 src_base_node,
102 6, // indent103 6, // indent
103 &stderr,104 &stderr_bw,
104 ) catch |err| switch (err) {105 ) catch |err| switch (err) {
105 error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"),106 error.OutOfMemory => try stderr_bw.writeAll(" <out of memory dumping zir>\n"),
106 else => |e| return e,107 else => |e| return e,
107 };108 };
108 try stderr.print(109 try stderr_bw.print(
109 \\ For full context, use the command110 \\ For full context, use the command
110 \\ zig ast-check -t {f}111 \\ zig ast-check -t {f}
111 \\112 \\
...@@ -116,30 +117,30 @@ fn dumpStatusReport() !void {...@@ -116,30 +117,30 @@ fn dumpStatusReport() !void {
116 while (parent) |curr| {117 while (parent) |curr| {
117 fba.reset();118 fba.reset();
118 const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool));119 const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool));
119 try stderr.print(" in {f}\n", .{cur_block_file.path.fmt(zcu.comp)});120 try stderr_bw.print(" in {f}\n", .{cur_block_file.path.fmt(zcu.comp)});
120 _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse {121 _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse {
121 try stderr.writeAll(" > [lost instruction; this should not happen]\n");122 try stderr_bw.writeAll(" > [lost instruction; this should not happen]\n");
122 parent = curr.parent;123 parent = curr.parent;
123 continue;124 continue;
124 };125 };
125 try stderr.writeAll(" > ");126 try stderr_bw.writeAll(" > ");
126 print_zir.renderSingleInstruction(127 print_zir.renderSingleInstruction(
127 allocator,128 allocator,
128 curr.body[curr.body_index],129 curr.body[curr.body_index],
129 cur_block_file,130 cur_block_file,
130 cur_block_src_base_node,131 cur_block_src_base_node,
131 6, // indent132 6, // indent
132 &stderr,133 &stderr_bw,
133 ) catch |err| switch (err) {134 ) catch |err| switch (err) {
134 error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"),135 error.OutOfMemory => try stderr_bw.writeAll(" <out of memory dumping zir>\n"),
135 else => |e| return e,136 else => |e| return e,
136 };137 };
137 try stderr.writeAll("\n");138 try stderr_bw.writeAll("\n");
138139
139 parent = curr.parent;140 parent = curr.parent;
140 }141 }
141142
142 try stderr.writeByte('\n');143 try stderr_bw.writeByte('\n');
143}144}
144145
145var crash_heap: [16 * 4096]u8 = undefined;146var crash_heap: [16 * 4096]u8 = undefined;
...@@ -268,8 +269,9 @@ const StackContext = union(enum) {...@@ -268,8 +269,9 @@ const StackContext = union(enum) {
268 debug.dumpCurrentStackTrace(ct.ret_addr);269 debug.dumpCurrentStackTrace(ct.ret_addr);
269 },270 },
270 .exception => |context| {271 .exception => |context| {
271 var stderr = std.fs.File.stderr().writer().unbuffered();272 var stderr_fw = std.fs.File.stderr().writer();
272 debug.dumpStackTraceFromBase(context, &stderr);273 var stderr_bw = stderr_fw.interface().unbuffered();
274 debug.dumpStackTraceFromBase(context, &stderr_bw);
273 },275 },
274 .not_supported => {276 .not_supported => {
275 std.fs.File.stderr().writeAll("Stack trace not supported on this platform.\n") catch {};277 std.fs.File.stderr().writeAll("Stack trace not supported on this platform.\n") catch {};
...@@ -379,19 +381,20 @@ const PanicSwitch = struct {...@@ -379,19 +381,20 @@ const PanicSwitch = struct {
379381
380 state.recover_stage = .release_mutex;382 state.recover_stage = .release_mutex;
381383
382 var stderr = std.fs.File.stderr().writer().unbuffered();384 var stderr_fw = std.fs.File.stderr().writer();
385 var stderr_bw = stderr_fw.interface().unbuffered();
383 if (builtin.single_threaded) {386 if (builtin.single_threaded) {
384 stderr.print("panic: ", .{}) catch goTo(releaseMutex, .{state});387 stderr_bw.print("panic: ", .{}) catch goTo(releaseMutex, .{state});
385 } else {388 } else {
386 const current_thread_id = std.Thread.getCurrentId();389 const current_thread_id = std.Thread.getCurrentId();
387 stderr.print("thread {} panic: ", .{current_thread_id}) catch goTo(releaseMutex, .{state});390 stderr_bw.print("thread {} panic: ", .{current_thread_id}) catch goTo(releaseMutex, .{state});
388 }391 }
389 stderr.print("{s}\n", .{msg}) catch goTo(releaseMutex, .{state});392 stderr_bw.print("{s}\n", .{msg}) catch goTo(releaseMutex, .{state});
390393
391 state.recover_stage = .report_stack;394 state.recover_stage = .report_stack;
392395
393 dumpStatusReport() catch |err| {396 dumpStatusReport() catch |err| {
394 stderr.print("\nIntercepted error.{} while dumping current state. Continuing...\n", .{err}) catch {};397 stderr_bw.print("\nIntercepted error.{} while dumping current state. Continuing...\n", .{err}) catch {};
395 };398 };
396399
397 goTo(reportStack, .{state});400 goTo(reportStack, .{state});
...@@ -406,8 +409,9 @@ const PanicSwitch = struct {...@@ -406,8 +409,9 @@ const PanicSwitch = struct {
406 recover(state, trace, stack, msg);409 recover(state, trace, stack, msg);
407410
408 state.recover_stage = .release_mutex;411 state.recover_stage = .release_mutex;
409 var stderr = std.fs.File.stderr().writer().unbuffered();412 var stderr_fw = std.fs.File.stderr().writer();
410 stderr.writeAll("\nOriginal Error:\n") catch {};413 var stderr_bw = stderr_fw.interface().unbuffered();
414 stderr_bw.writeAll("\nOriginal Error:\n") catch {};
411 goTo(reportStack, .{state});415 goTo(reportStack, .{state});
412 }416 }
413417
...@@ -477,8 +481,9 @@ const PanicSwitch = struct {...@@ -477,8 +481,9 @@ const PanicSwitch = struct {
477 recover(state, trace, stack, msg);481 recover(state, trace, stack, msg);
478482
479 state.recover_stage = .silent_abort;483 state.recover_stage = .silent_abort;
480 var stderr = std.fs.File.stderr().writer().unbuffered();484 var stderr_fw = std.fs.File.stderr().writer();
481 stderr.writeAll("Aborting...\n") catch {};485 var stderr_bw = stderr_fw.interface().unbuffered();
486 stderr_bw.writeAll("Aborting...\n") catch {};
482 goTo(abort, .{});487 goTo(abort, .{});
483 }488 }
484489
...@@ -505,10 +510,11 @@ const PanicSwitch = struct {...@@ -505,10 +510,11 @@ const PanicSwitch = struct {
505 // lower the verbosity, and restore it at the end if we don't panic.510 // lower the verbosity, and restore it at the end if we don't panic.
506 state.recover_verbosity = .message_only;511 state.recover_verbosity = .message_only;
507512
508 var stderr = std.fs.File.stderr().writer().unbuffered();513 var stderr_fw = std.fs.File.stderr().writer();
509 stderr.writeAll("\nPanicked during a panic: ") catch {};514 var stderr_bw = stderr_fw.interface().unbuffered();
510 stderr.writeAll(msg) catch {};515 stderr_bw.writeAll("\nPanicked during a panic: ") catch {};
511 stderr.writeAll("\nInner panic stack:\n") catch {};516 stderr_bw.writeAll(msg) catch {};
517 stderr_bw.writeAll("\nInner panic stack:\n") catch {};
512 if (trace) |t| {518 if (trace) |t| {
513 debug.dumpStackTrace(t.*);519 debug.dumpStackTrace(t.*);
514 }520 }
...@@ -519,10 +525,11 @@ const PanicSwitch = struct {...@@ -519,10 +525,11 @@ const PanicSwitch = struct {
519 .message_only => {525 .message_only => {
520 state.recover_verbosity = .silent;526 state.recover_verbosity = .silent;
521527
522 var stderr = std.fs.File.stderr().writer().unbuffered();528 var stderr_fw = std.fs.File.stderr().writer();
523 stderr.writeAll("\nPanicked while dumping inner panic stack: ") catch {};529 var stderr_bw = stderr_fw.interface().unbuffered();
524 stderr.writeAll(msg) catch {};530 stderr_bw.writeAll("\nPanicked while dumping inner panic stack: ") catch {};
525 stderr.writeByte('\n') catch {};531 stderr_bw.writeAll(msg) catch {};
532 stderr_bw.writeByte('\n') catch {};
526533
527 // If we succeed, restore all the way to dumping the stack.534 // If we succeed, restore all the way to dumping the stack.
528 state.recover_verbosity = .message_and_stack;535 state.recover_verbosity = .message_and_stack;
src/print_value.zig+4-4
...@@ -47,7 +47,7 @@ pub fn print(...@@ -47,7 +47,7 @@ pub fn print(
47 level: u8,47 level: u8,
48 pt: Zcu.PerThread,48 pt: Zcu.PerThread,
49 opt_sema: ?*Sema,49 opt_sema: ?*Sema,
50) std.io.Writer.Error!void {50) (std.io.Writer.Error || Zcu.CompileError)!void {
51 const zcu = pt.zcu;51 const zcu = pt.zcu;
52 const ip = &zcu.intern_pool;52 const ip = &zcu.intern_pool;
53 switch (ip.indexToKey(val.toIntern())) {53 switch (ip.indexToKey(val.toIntern())) {
...@@ -190,7 +190,7 @@ fn printAggregate(...@@ -190,7 +190,7 @@ fn printAggregate(
190 level: u8,190 level: u8,
191 pt: Zcu.PerThread,191 pt: Zcu.PerThread,
192 opt_sema: ?*Sema,192 opt_sema: ?*Sema,
193) std.io.Writer.Error!void {193) (std.io.Writer.Error || Zcu.CompileError)!void {
194 if (level == 0) {194 if (level == 0) {
195 if (is_ref) try bw.writeByte('&');195 if (is_ref) try bw.writeByte('&');
196 return bw.writeAll(".{ ... }");196 return bw.writeAll(".{ ... }");
...@@ -276,7 +276,7 @@ fn printPtr(...@@ -276,7 +276,7 @@ fn printPtr(
276 level: u8,276 level: u8,
277 pt: Zcu.PerThread,277 pt: Zcu.PerThread,
278 opt_sema: ?*Sema,278 opt_sema: ?*Sema,
279) std.io.Writer.Error!void {279) (std.io.Writer.Error || Zcu.CompileError)!void {
280 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {280 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
281 .undef => return bw.writeAll("undefined"),281 .undef => return bw.writeAll("undefined"),
282 .ptr => |ptr| ptr,282 .ptr => |ptr| ptr,
...@@ -336,7 +336,7 @@ pub fn printPtrDerivation(...@@ -336,7 +336,7 @@ pub fn printPtrDerivation(
336 /// The maximum recursion depth. We can never recurse infinitely here, but the depth can be arbitrary,336 /// The maximum recursion depth. We can never recurse infinitely here, but the depth can be arbitrary,
337 /// so at this depth we just write "..." to prevent stack overflow.337 /// so at this depth we just write "..." to prevent stack overflow.
338 ptr_depth: u8,338 ptr_depth: u8,
339) std.io.Writer.Error!Value.PointerDeriveStep {339) (std.io.Writer.Error || Zcu.CompileError)!Value.PointerDeriveStep {
340 const zcu = pt.zcu;340 const zcu = pt.zcu;
341 const ip = &zcu.intern_pool;341 const ip = &zcu.intern_pool;
342342
src/print_zir.zig+1-1
...@@ -176,7 +176,7 @@ const Writer = struct {...@@ -176,7 +176,7 @@ const Writer = struct {
176 }176 }
177 } = .{},177 } = .{},
178178
179 const Error = std.io.Writer.Error;179 const Error = std.io.Writer.Error || std.mem.Allocator.Error;
180180
181 fn writeInstToStream(181 fn writeInstToStream(
182 self: *Writer,182 self: *Writer,