From 93378e2e7be964a7362a9875e3292e9d6a697177 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 16 Jul 2025 19:47:58 -0700 Subject: [PATCH 01/10] std.zig: finish updating to new I/O API --- lib/compiler/objcopy.zig | 18 +- lib/compiler/resinator/main.zig | 6 +- lib/compiler/test_runner.zig | 11 +- lib/std/zig.zig | 1 + lib/std/zig/LibCInstallation.zig | 7 +- lib/std/zig/Server.zig | 214 +++++++---------------- lib/std/zig/WindowsSdk.zig | 14 +- lib/std/zig/llvm.zig | 6 + lib/std/zig/llvm/BitcodeReader.zig | 28 +-- lib/std/zig/perf_test.zig | 14 +- lib/std/zig/system/linux.zig | 35 ++-- src/Compilation.zig | 85 +++++----- src/deprecated.zig | 262 ----------------------------- src/main.zig | 46 ++--- 14 files changed, 201 insertions(+), 546 deletions(-) diff --git a/lib/compiler/objcopy.zig b/lib/compiler/objcopy.zig index 98bf5d2bcfe0..52ffe208f621 100644 --- a/lib/compiler/objcopy.zig +++ b/lib/compiler/objcopy.zig @@ -10,6 +10,9 @@ const assert = std.debug.assert; const fatal = std.process.fatal; const Server = std.zig.Server; +var stdin_buffer: [1024]u8 = undefined; +var stdout_buffer: [1024]u8 = undefined; + pub fn main() !void { var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena_instance.deinit(); @@ -22,11 +25,8 @@ pub fn main() !void { return cmdObjCopy(gpa, arena, args[1..]); } -fn cmdObjCopy( - gpa: Allocator, - arena: Allocator, - args: []const []const u8, -) !void { +fn cmdObjCopy(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { + _ = gpa; var i: usize = 0; var opt_out_fmt: ?std.Target.ObjectFormat = null; var opt_input: ?[]const u8 = null; @@ -225,13 +225,13 @@ fn cmdObjCopy( } if (listen) { + var stdin_reader = fs.File.stdin().reader(&stdin_buffer); + var stdout_writer = fs.File.stdout().writer(&stdout_buffer); var server = try Server.init(.{ - .gpa = gpa, - .in = .stdin(), - .out = .stdout(), + .in = &stdin_reader.interface, + .out = &stdout_writer.interface, .zig_version = builtin.zig_version_string, }); - defer server.deinit(); var seen_update = false; while (true) { diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 903e0a2f719a..4c952c03c4a4 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -13,6 +13,8 @@ const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePag const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType; const aro = @import("aro"); +var stdout_buffer: [1024]u8 = undefined; + pub fn main() !void { var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; defer std.debug.assert(gpa.deinit() == .ok); @@ -41,12 +43,12 @@ pub fn main() !void { cli_args = args[3..]; } + var stdout_writer2 = std.fs.File.stdout().writer(&stdout_buffer); var error_handler: ErrorHandler = switch (zig_integration) { true => .{ .server = .{ - .out = std.fs.File.stdout(), + .out = &stdout_writer2.interface, .in = undefined, // won't be receiving messages - .receive_fifo = undefined, // won't be receiving messages }, }, false => .{ diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 929bd1c417f9..a69066f09cb9 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -2,7 +2,6 @@ const builtin = @import("builtin"); const std = @import("std"); -const io = std.io; const testing = std.testing; const assert = std.debug.assert; @@ -13,6 +12,8 @@ pub const std_options: std.Options = .{ var log_err_count: usize = 0; var fba_buffer: [8192]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&fba_buffer); +var stdin_buffer: [std.heap.page_size_min]u8 align(std.heap.page_size_min) = undefined; +var stdout_buffer: [std.heap.page_size_min]u8 align(std.heap.page_size_min) = undefined; const crippled = switch (builtin.zig_backend) { .stage2_powerpc, @@ -67,13 +68,13 @@ pub fn main() void { fn mainServer() !void { @disableInstrumentation(); + var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer); + var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); var server = try std.zig.Server.init(.{ - .gpa = fba.allocator(), - .in = .stdin(), - .out = .stdout(), + .in = &stdin_reader.interface, + .out = &stdout_writer.interface, .zig_version = builtin.zig_version_string, }); - defer server.deinit(); if (builtin.fuzz) { const coverage_id = fuzzer_coverage_id(); diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 51eac1b0a6fa..ad264a9b3377 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -905,4 +905,5 @@ test { _ = system; _ = target; _ = c_translation; + _ = llvm; } diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index e2b7cd233ddb..3e03d1ff2e74 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -370,7 +370,7 @@ fn findNativeIncludeDirWindows( for (installs) |install| { result_buf.shrinkAndFree(0); - try result_buf.writer().print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); + try result_buf.print("{s}\\Include\\{s}\\ucrt", .{ install.path, install.version }); var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, @@ -417,7 +417,7 @@ fn findNativeCrtDirWindows( for (installs) |install| { result_buf.shrinkAndFree(0); - try result_buf.writer().print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); + try result_buf.print("{s}\\Lib\\{s}\\ucrt\\{s}", .{ install.path, install.version, arch_sub_dir }); var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, @@ -484,8 +484,7 @@ fn findNativeKernel32LibDir( for (installs) |install| { result_buf.shrinkAndFree(0); - const stream = result_buf.writer(); - try stream.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); + try result_buf.print("{s}\\Lib\\{s}\\um\\{s}", .{ install.path, install.version, arch_sub_dir }); var dir = fs.cwd().openDir(result_buf.items, .{}) catch |err| switch (err) { error.FileNotFound, diff --git a/lib/std/zig/Server.zig b/lib/std/zig/Server.zig index 2f03c7808318..38ad45e1e161 100644 --- a/lib/std/zig/Server.zig +++ b/lib/std/zig/Server.zig @@ -1,6 +1,20 @@ -in: std.fs.File, -out: std.fs.File, -receive_fifo: std.fifo.LinearFifo(u8, .Dynamic), +const Server = @This(); + +const builtin = @import("builtin"); + +const std = @import("std"); +const Allocator = std.mem.Allocator; +const assert = std.debug.assert; +const native_endian = builtin.target.cpu.arch.endian(); +const need_bswap = native_endian != .little; +const Cache = std.Build.Cache; +const OutMessage = std.zig.Server.Message; +const InMessage = std.zig.Client.Message; +const Reader = std.Io.Reader; +const Writer = std.Io.Writer; + +in: *Reader, +out: *Writer, pub const Message = struct { pub const Header = extern struct { @@ -94,9 +108,8 @@ pub const Message = struct { }; pub const Options = struct { - gpa: Allocator, - in: std.fs.File, - out: std.fs.File, + in: *Reader, + out: *Writer, zig_version: []const u8, }; @@ -104,96 +117,40 @@ pub fn init(options: Options) !Server { var s: Server = .{ .in = options.in, .out = options.out, - .receive_fifo = std.fifo.LinearFifo(u8, .Dynamic).init(options.gpa), }; try s.serveStringMessage(.zig_version, options.zig_version); return s; } -pub fn deinit(s: *Server) void { - s.receive_fifo.deinit(); - s.* = undefined; -} - pub fn receiveMessage(s: *Server) !InMessage.Header { - const Header = InMessage.Header; - const fifo = &s.receive_fifo; - var last_amt_zero = false; - - while (true) { - const buf = fifo.readableSlice(0); - assert(fifo.readableLength() == buf.len); - if (buf.len >= @sizeOf(Header)) { - const header: *align(1) const Header = @ptrCast(buf[0..@sizeOf(Header)]); - const bytes_len = bswap(header.bytes_len); - const tag = bswap(header.tag); - - if (buf.len - @sizeOf(Header) >= bytes_len) { - fifo.discard(@sizeOf(Header)); - return .{ - .tag = tag, - .bytes_len = bytes_len, - }; - } else { - const needed = bytes_len - (buf.len - @sizeOf(Header)); - const write_buffer = try fifo.writableWithSize(needed); - const amt = try s.in.read(write_buffer); - fifo.update(amt); - continue; - } - } - - const write_buffer = try fifo.writableWithSize(256); - const amt = try s.in.read(write_buffer); - fifo.update(amt); - if (amt == 0) { - if (last_amt_zero) return error.BrokenPipe; - last_amt_zero = true; - } - } + return s.in.takeStruct(InMessage.Header, .little); } pub fn receiveBody_u32(s: *Server) !u32 { - const fifo = &s.receive_fifo; - const buf = fifo.readableSlice(0); - const result = @as(*align(1) const u32, @ptrCast(buf[0..4])).*; - fifo.discard(4); - return bswap(result); + return s.in.takeInt(u32, .little); } pub fn serveStringMessage(s: *Server, tag: OutMessage.Tag, msg: []const u8) !void { - return s.serveMessage(.{ + try s.serveMessageHeader(.{ .tag = tag, - .bytes_len = @as(u32, @intCast(msg.len)), - }, &.{msg}); + .bytes_len = @intCast(msg.len), + }); + try s.out.writeAll(msg); + try s.out.flush(); } -pub fn serveMessage( - s: *const Server, - header: OutMessage.Header, - bufs: []const []const u8, -) !void { - var iovecs: [10]std.posix.iovec_const = undefined; - const header_le = bswap(header); - iovecs[0] = .{ - .base = @as([*]const u8, @ptrCast(&header_le)), - .len = @sizeOf(OutMessage.Header), - }; - for (bufs, iovecs[1 .. bufs.len + 1]) |buf, *iovec| { - iovec.* = .{ - .base = buf.ptr, - .len = buf.len, - }; - } - try s.out.writevAll(iovecs[0 .. bufs.len + 1]); +/// Don't forget to flush! +pub fn serveMessageHeader(s: *const Server, header: OutMessage.Header) !void { + try s.out.writeStruct(header, .little); } -pub fn serveU64Message(s: *Server, tag: OutMessage.Tag, int: u64) !void { - const msg_le = bswap(int); - return s.serveMessage(.{ +pub fn serveU64Message(s: *const Server, tag: OutMessage.Tag, int: u64) !void { + try serveMessageHeader(s, .{ .tag = tag, .bytes_len = @sizeOf(u64), - }, &.{std.mem.asBytes(&msg_le)}); + }); + try s.out.writeInt(u64, int, .little); + try s.out.flush(); } pub fn serveEmitDigest( @@ -201,26 +158,22 @@ pub fn serveEmitDigest( digest: *const [Cache.bin_digest_len]u8, header: OutMessage.EmitDigest, ) !void { - try s.serveMessage(.{ + try s.serveMessageHeader(.{ .tag = .emit_digest, .bytes_len = @intCast(digest.len + @sizeOf(OutMessage.EmitDigest)), - }, &.{ - std.mem.asBytes(&header), - digest, }); + try s.out.writeStruct(header, .little); + try s.out.writeAll(digest); + try s.out.flush(); } -pub fn serveTestResults( - s: *Server, - msg: OutMessage.TestResults, -) !void { - const msg_le = bswap(msg); - try s.serveMessage(.{ +pub fn serveTestResults(s: *Server, msg: OutMessage.TestResults) !void { + try s.serveMessageHeader(.{ .tag = .test_results, .bytes_len = @intCast(@sizeOf(OutMessage.TestResults)), - }, &.{ - std.mem.asBytes(&msg_le), }); + try s.out.writeStruct(msg, .little); + try s.out.flush(); } pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void { @@ -230,91 +183,38 @@ pub fn serveErrorBundle(s: *Server, error_bundle: std.zig.ErrorBundle) !void { }; const bytes_len = @sizeOf(OutMessage.ErrorBundle) + 4 * error_bundle.extra.len + error_bundle.string_bytes.len; - try s.serveMessage(.{ + try s.serveMessageHeader(.{ .tag = .error_bundle, .bytes_len = @intCast(bytes_len), - }, &.{ - std.mem.asBytes(&eb_hdr), - // TODO: implement @ptrCast between slices changing the length - std.mem.sliceAsBytes(error_bundle.extra), - error_bundle.string_bytes, }); + try s.out.writeStruct(eb_hdr, .little); + try s.out.writeSliceEndian(u32, error_bundle.extra, .little); + try s.out.writeAll(error_bundle.string_bytes); + try s.out.flush(); } pub const TestMetadata = struct { - names: []u32, - expected_panic_msgs: []u32, + names: []const u32, + expected_panic_msgs: []const u32, string_bytes: []const u8, }; pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { const header: OutMessage.TestMetadata = .{ - .tests_len = bswap(@as(u32, @intCast(test_metadata.names.len))), - .string_bytes_len = bswap(@as(u32, @intCast(test_metadata.string_bytes.len))), + .tests_len = @as(u32, @intCast(test_metadata.names.len)), + .string_bytes_len = @as(u32, @intCast(test_metadata.string_bytes.len)), }; const trailing = 2; const bytes_len = @sizeOf(OutMessage.TestMetadata) + trailing * @sizeOf(u32) * test_metadata.names.len + test_metadata.string_bytes.len; - if (need_bswap) { - bswap_u32_array(test_metadata.names); - bswap_u32_array(test_metadata.expected_panic_msgs); - } - defer if (need_bswap) { - bswap_u32_array(test_metadata.names); - bswap_u32_array(test_metadata.expected_panic_msgs); - }; - - return s.serveMessage(.{ + try s.serveMessageHeader(.{ .tag = .test_metadata, .bytes_len = @intCast(bytes_len), - }, &.{ - std.mem.asBytes(&header), - // TODO: implement @ptrCast between slices changing the length - std.mem.sliceAsBytes(test_metadata.names), - std.mem.sliceAsBytes(test_metadata.expected_panic_msgs), - test_metadata.string_bytes, }); + try s.out.writeStruct(header, .little); + try s.out.writeSliceEndian(u32, test_metadata.names, .little); + try s.out.writeSliceEndian(u32, test_metadata.expected_panic_msgs, .little); + try s.out.writeAll(test_metadata.string_bytes); + try s.out.flush(); } - -fn bswap(x: anytype) @TypeOf(x) { - if (!need_bswap) return x; - - const T = @TypeOf(x); - switch (@typeInfo(T)) { - .@"enum" => return @as(T, @enumFromInt(@byteSwap(@intFromEnum(x)))), - .int => return @byteSwap(x), - .@"struct" => |info| switch (info.layout) { - .@"extern" => { - var result: T = undefined; - inline for (info.fields) |field| { - @field(result, field.name) = bswap(@field(x, field.name)); - } - return result; - }, - .@"packed" => { - const I = info.backing_integer.?; - return @as(T, @bitCast(@byteSwap(@as(I, @bitCast(x))))); - }, - .auto => @compileError("auto layout struct"), - }, - else => @compileError("bswap on type " ++ @typeName(T)), - } -} - -fn bswap_u32_array(slice: []u32) void { - comptime assert(need_bswap); - for (slice) |*elem| elem.* = @byteSwap(elem.*); -} - -const OutMessage = std.zig.Server.Message; -const InMessage = std.zig.Client.Message; - -const Server = @This(); -const builtin = @import("builtin"); -const std = @import("std"); -const Allocator = std.mem.Allocator; -const assert = std.debug.assert; -const native_endian = builtin.target.cpu.arch.endian(); -const need_bswap = native_endian != .little; -const Cache = std.Build.Cache; diff --git a/lib/std/zig/WindowsSdk.zig b/lib/std/zig/WindowsSdk.zig index 1bcf45fb7451..61e1defb1290 100644 --- a/lib/std/zig/WindowsSdk.zig +++ b/lib/std/zig/WindowsSdk.zig @@ -1,11 +1,12 @@ +const WindowsSdk = @This(); +const builtin = @import("builtin"); +const std = @import("std"); +const Writer = std.Io.Writer; + windows10sdk: ?Installation, windows81sdk: ?Installation, msvc_lib_dir: ?[]const u8, -const WindowsSdk = @This(); -const std = @import("std"); -const builtin = @import("builtin"); - const windows = std.os.windows; const RRF = windows.advapi32.RRF; @@ -759,14 +760,13 @@ const MsvcLibDir = struct { while (instances_dir_it.next() catch return error.PathNotFound) |entry| { if (entry.kind != .directory) continue; - var fbs = std.io.fixedBufferStream(&state_subpath_buf); - const writer = fbs.writer(); + var writer: Writer = .fixed(&state_subpath_buf); writer.writeAll(entry.name) catch unreachable; writer.writeByte(std.fs.path.sep) catch unreachable; writer.writeAll("state.json") catch unreachable; - const json_contents = instances_dir.readFileAlloc(allocator, fbs.getWritten(), std.math.maxInt(usize)) catch continue; + const json_contents = instances_dir.readFileAlloc(allocator, writer.buffered(), std.math.maxInt(usize)) catch continue; defer allocator.free(json_contents); var parsed = std.json.parseFromSlice(std.json.Value, allocator, json_contents, .{}) catch continue; diff --git a/lib/std/zig/llvm.zig b/lib/std/zig/llvm.zig index c2e1ed9c56bf..c45ffe90836c 100644 --- a/lib/std/zig/llvm.zig +++ b/lib/std/zig/llvm.zig @@ -1,3 +1,9 @@ pub const BitcodeReader = @import("llvm/BitcodeReader.zig"); pub const bitcode_writer = @import("llvm/bitcode_writer.zig"); pub const Builder = @import("llvm/Builder.zig"); + +test { + _ = BitcodeReader; + _ = bitcode_writer; + _ = Builder; +} diff --git a/lib/std/zig/llvm/BitcodeReader.zig b/lib/std/zig/llvm/BitcodeReader.zig index ea18b7978eb6..f1d47e93c013 100644 --- a/lib/std/zig/llvm/BitcodeReader.zig +++ b/lib/std/zig/llvm/BitcodeReader.zig @@ -1,6 +1,11 @@ +const BitcodeReader = @This(); + +const std = @import("../../std.zig"); +const assert = std.debug.assert; + allocator: std.mem.Allocator, record_arena: std.heap.ArenaAllocator.State, -reader: std.io.AnyReader, +reader: *std.Io.Reader, keep_names: bool, bit_buffer: u32, bit_offset: u5, @@ -93,7 +98,7 @@ pub const Record = struct { }; pub const InitOptions = struct { - reader: std.io.AnyReader, + reader: *std.Io.Reader, keep_names: bool = false, }; pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader { @@ -172,7 +177,7 @@ pub fn next(bc: *BitcodeReader) !?Item { pub fn skipBlock(bc: *BitcodeReader, block: Block) !void { assert(bc.bit_offset == 0); - try bc.reader.skipBytes(@as(u34, block.len) * 4, .{}); + try bc.reader.discardAll(4 * @as(u34, block.len)); try bc.endBlock(); } @@ -371,19 +376,19 @@ fn align32Bits(bc: *BitcodeReader) void { fn read32Bits(bc: *BitcodeReader) !u32 { assert(bc.bit_offset == 0); - return bc.reader.readInt(u32, .little); + return bc.reader.takeInt(u32, .little); } fn readBytes(bc: *BitcodeReader, bytes: []u8) !void { assert(bc.bit_offset == 0); - try bc.reader.readNoEof(bytes); + try bc.reader.readSliceAll(bytes); const trailing_bytes = bytes.len % 4; if (trailing_bytes > 0) { - var bit_buffer = [1]u8{0} ** 4; - try bc.reader.readNoEof(bit_buffer[trailing_bytes..]); + var bit_buffer: [4]u8 = @splat(0); + try bc.reader.readSliceAll(bit_buffer[trailing_bytes..]); bc.bit_buffer = std.mem.readInt(u32, &bit_buffer, .little); - bc.bit_offset = @intCast(trailing_bytes * 8); + bc.bit_offset = @intCast(8 * trailing_bytes); } } @@ -509,7 +514,6 @@ const Abbrev = struct { }; }; -const assert = std.debug.assert; -const std = @import("../../std.zig"); - -const BitcodeReader = @This(); +test { + _ = &skipBlock; +} diff --git a/lib/std/zig/perf_test.zig b/lib/std/zig/perf_test.zig index 087b08147559..1566a15d2dc1 100644 --- a/lib/std/zig/perf_test.zig +++ b/lib/std/zig/perf_test.zig @@ -1,7 +1,6 @@ const std = @import("std"); const mem = std.mem; const Tokenizer = std.zig.Tokenizer; -const io = std.io; const fmtIntSizeBin = std.fmt.fmtIntSizeBin; const source = @embedFile("../os.zig"); @@ -22,16 +21,15 @@ pub fn main() !void { const bytes_per_sec_float = @as(f64, @floatFromInt(source.len * iterations)) / elapsed_s; const bytes_per_sec = @as(u64, @intFromFloat(@floor(bytes_per_sec_float))); - var stdout_file: std.fs.File = .stdout(); - const stdout = stdout_file.deprecatedWriter(); - try stdout.print("parsing speed: {:.2}/s, {:.2} used \n", .{ - fmtIntSizeBin(bytes_per_sec), - fmtIntSizeBin(memory_used), - }); + var stdout_buffer: [1024]u8 = undefined; + var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + const stdout = &stdout_writer.interface; + try stdout.print("parsing speed: {Bi:.2}/s, {Bi:.2} used \n", .{ bytes_per_sec, memory_used }); + try stdout.flush(); } fn testOnce() usize { - var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(&fixed_buffer_mem); const allocator = fixed_buf_alloc.allocator(); _ = std.zig.Ast.parse(allocator, source, .zig) catch @panic("parse failure"); return fixed_buf_alloc.end_index; diff --git a/lib/std/zig/system/linux.zig b/lib/std/zig/system/linux.zig index 8044e1969d4c..df70e71f5b3a 100644 --- a/lib/std/zig/system/linux.zig +++ b/lib/std/zig/system/linux.zig @@ -1,7 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); const mem = std.mem; -const io = std.io; const fs = std.fs; const fmt = std.fmt; const testing = std.testing; @@ -344,8 +343,8 @@ fn testParser( expected_model: *const Target.Cpu.Model, input: []const u8, ) !void { - var fbs = io.fixedBufferStream(input); - const result = try parser.parse(arch, fbs.reader()); + var r: std.Io.Reader = .fixed(input); + const result = try parser.parse(arch, &r); try testing.expectEqual(expected_model, result.?.model); try testing.expect(expected_model.features.eql(result.?.features)); } @@ -357,20 +356,17 @@ fn testParser( // When all the lines have been analyzed the finalize method is called. fn CpuinfoParser(comptime impl: anytype) type { return struct { - fn parse(arch: Target.Cpu.Arch, reader: anytype) anyerror!?Target.Cpu { - var line_buf: [1024]u8 = undefined; + fn parse(arch: Target.Cpu.Arch, reader: *std.Io.Reader) !?Target.Cpu { var obj: impl = .{}; - - while (true) { - const line = (try reader.readUntilDelimiterOrEof(&line_buf, '\n')) orelse break; + while (reader.takeDelimiterExclusive('\n')) |line| { const colon_pos = mem.indexOfScalar(u8, line, ':') orelse continue; const key = mem.trimEnd(u8, line[0..colon_pos], " \t"); const value = mem.trimStart(u8, line[colon_pos + 1 ..], " \t"); - - if (!try obj.line_hook(key, value)) - break; + if (!try obj.line_hook(key, value)) break; + } else |err| switch (err) { + error.EndOfStream => {}, + else => |e| return e, } - return obj.finalize(arch); } }; @@ -383,15 +379,18 @@ inline fn getAArch64CpuFeature(comptime feat_reg: []const u8) u64 { } pub fn detectNativeCpuAndFeatures() ?Target.Cpu { - var f = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { + var file = fs.openFileAbsolute("/proc/cpuinfo", .{}) catch |err| switch (err) { else => return null, }; - defer f.close(); + defer file.close(); + + var buffer: [4096]u8 = undefined; // "flags" lines can get pretty long. + var file_reader = file.reader(&buffer); const current_arch = builtin.cpu.arch; switch (current_arch) { .arm, .armeb, .thumb, .thumbeb => { - return ArmCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; + return ArmCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; }, .aarch64, .aarch64_be => { const registers = [12]u64{ @@ -413,13 +412,13 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { return core; }, .sparc64 => { - return SparcCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; + return SparcCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; }, .powerpc, .powerpcle, .powerpc64, .powerpc64le => { - return PowerpcCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; + return PowerpcCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; }, .riscv64, .riscv32 => { - return RiscvCpuinfoParser.parse(current_arch, f.deprecatedReader()) catch null; + return RiscvCpuinfoParser.parse(current_arch, &file_reader.interface) catch null; }, else => {}, } diff --git a/src/Compilation.zig b/src/Compilation.zig index 2e20c6edbee6..469a13b4a9ec 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -12,6 +12,7 @@ const ThreadPool = std.Thread.Pool; const WaitGroup = std.Thread.WaitGroup; const ErrorBundle = std.zig.ErrorBundle; const fatal = std.process.fatal; +const Writer = std.io.Writer; const Value = @import("Value.zig"); const Type = @import("Type.zig"); @@ -44,6 +45,8 @@ const Builtin = @import("Builtin.zig"); const LlvmObject = @import("codegen/llvm.zig").Object; const dev = @import("dev.zig"); +const DeprecatedLinearFifo = @import("deprecated.zig").LinearFifo; + pub const Config = @import("Compilation/Config.zig"); /// General-purpose allocator. Used for both temporary and long-term storage. @@ -121,15 +124,15 @@ work_queues: [ } break :len len; } -]std.fifo.LinearFifo(Job, .Dynamic), +]DeprecatedLinearFifo(Job), /// These jobs are to invoke the Clang compiler to create an object file, which /// gets linked with the Compilation. -c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic), +c_object_work_queue: DeprecatedLinearFifo(*CObject), /// These jobs are to invoke the RC compiler to create a compiled resource file (.res), which /// gets linked with the Compilation. -win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic) else struct { +win32_resource_work_queue: if (dev.env.supports(.win32_resource)) DeprecatedLinearFifo(*Win32Resource) else struct { pub fn ensureUnusedCapacity(_: @This(), _: u0) error{}!void {} pub fn readItem(_: @This()) ?noreturn { return null; @@ -995,13 +998,13 @@ pub const CObject = struct { const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; defer file.close(); - file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; - - var line = std.ArrayList(u8).init(eb.gpa); - defer line.deinit(); - file.deprecatedReader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0; - - break :source_line try eb.addString(line.items); + var buffer: [1024]u8 = undefined; + var file_reader = file.reader(&buffer); + file_reader.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; + var aw: Writer.Allocating = .init(eb.gpa); + defer aw.deinit(); + _ = file_reader.interface.streamDelimiterEnding(&aw.writer, '\n') catch break :source_line 0; + break :source_line try eb.addString(aw.getWritten()); }; return .{ @@ -1067,11 +1070,11 @@ pub const CObject = struct { } }; + var buffer: [1024]u8 = undefined; const file = try fs.cwd().openFile(path, .{}); defer file.close(); - var br = std.io.bufferedReader(file.deprecatedReader()); - const reader = br.reader(); - var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = reader.any() }); + var file_reader = file.reader(&buffer); + var bc = std.zig.llvm.BitcodeReader.init(gpa, .{ .reader = &file_reader.interface }); defer bc.deinit(); var file_names: std.AutoArrayHashMapUnmanaged(u32, []const u8) = .empty; @@ -1873,15 +1876,12 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil if (options.verbose_llvm_cpu_features) { if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: { - std.debug.lockStdErr(); - defer std.debug.unlockStdErr(); - const stderr = fs.File.stderr().deprecatedWriter(); - nosuspend { - stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print; - stderr.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; - stderr.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; - stderr.print(" features: {s}\n", .{cf}) catch {}; - } + const stderr_w = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print; + stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print; + stderr_w.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print; + stderr_w.print(" features: {s}\n", .{cf}) catch {}; } } @@ -2483,7 +2483,7 @@ pub fn destroy(comp: *Compilation) void { if (comp.zcu) |zcu| zcu.deinit(); comp.cache_use.deinit(); - for (comp.work_queues) |work_queue| work_queue.deinit(); + for (&comp.work_queues) |*work_queue| work_queue.deinit(); comp.c_object_work_queue.deinit(); comp.win32_resource_work_queue.deinit(); @@ -3931,11 +3931,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error. // However, we haven't reported any such error. // This is a compiler bug. - const stderr = fs.File.stderr().deprecatedWriter(); - try stderr.writeAll("referenced transitive analysis errors, but none actually emitted\n"); - try stderr.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); + var stderr_w = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + try stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n"); + try stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); while (ref) |r| { - try stderr.print("referenced by: {f}{s}\n", .{ + try stderr_w.print("referenced by: {f}{s}\n", .{ zcu.fmtAnalUnit(r.referencer), if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "", }); @@ -5849,7 +5850,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr try child.spawn(); - const stderr = try child.stderr.?.deprecatedReader().readAllAlloc(arena, std.math.maxInt(usize)); + var small_buffer: [1]u8 = undefined; + var stderr_reader = child.stderr.?.reader(&small_buffer); + const stderr = try stderr_reader.interface.allocRemaining(arena, .unlimited); const term = child.wait() catch |err| { return comp.failCObj(c_object, "failed to spawn zig clang {s}: {s}", .{ argv.items[0], @errorName(err) }); @@ -6213,13 +6216,10 @@ fn spawnZigRc( const stdout = poller.fifo(.stdout); poll: while (true) { - while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) { - if (!(try poller.poll())) break :poll; - } - const header = stdout.reader().readStruct(std.zig.Server.Message.Header) catch unreachable; - while (stdout.readableLength() < header.bytes_len) { - if (!(try poller.poll())) break :poll; - } + while (stdout.readableLength() < @sizeOf(std.zig.Server.Message.Header)) if (!try poller.poll()) break :poll; + var header: std.zig.Server.Message.Header = undefined; + assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(std.zig.Server.Message.Header)); + while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll; const body = stdout.readableSliceOfLen(header.bytes_len); switch (header.tag) { @@ -7209,13 +7209,16 @@ pub fn lockAndSetMiscFailure( } pub fn dump_argv(argv: []const []const u8) void { - std.debug.lockStdErr(); - defer std.debug.unlockStdErr(); - const stderr = fs.File.stderr().deprecatedWriter(); - for (argv[0 .. argv.len - 1]) |arg| { - nosuspend stderr.print("{s} ", .{arg}) catch return; + var buffer: [64]u8 = undefined; + const stderr = std.debug.lockStderrWriter(&buffer); + defer std.debug.unlockStderrWriter(); + nosuspend { + for (argv) |arg| { + stderr.writeAll(arg) catch return; + (stderr.writableArray(1) catch return)[0] = ' '; + } + stderr.buffer[stderr.end - 1] = '\n'; } - nosuspend stderr.print("{s}\n", .{argv[argv.len - 1]}) catch {}; } pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend { diff --git a/src/deprecated.zig b/src/deprecated.zig index 1f7d5c8c25ef..68c712b3b183 100644 --- a/src/deprecated.zig +++ b/src/deprecated.zig @@ -52,15 +52,6 @@ pub fn LinearFifo(comptime T: type) type { } } - /// Reduce allocated capacity to `size`. - pub fn shrink(self: *Self, size: usize) void { - assert(size >= self.count); - self.realign(); - self.buf = self.allocator.realloc(self.buf, size) catch |e| switch (e) { - error.OutOfMemory => return, // no problem, capacity is still correct then. - }; - } - /// Ensure that the buffer can fit at least `size` items pub fn ensureTotalCapacity(self: *Self, size: usize) !void { if (self.buf.len >= size) return; @@ -76,11 +67,6 @@ pub fn LinearFifo(comptime T: type) type { return try self.ensureTotalCapacity(math.add(usize, self.count, size) catch return error.OutOfMemory); } - /// Returns number of items currently in fifo - pub fn readableLength(self: Self) usize { - return self.count; - } - /// Returns a writable slice from the 'read' end of the fifo fn readableSliceMut(self: Self, offset: usize) []T { if (offset > self.count) return &[_]T{}; @@ -95,22 +81,6 @@ pub fn LinearFifo(comptime T: type) type { } } - /// Returns a readable slice from `offset` - pub fn readableSlice(self: Self, offset: usize) []const T { - return self.readableSliceMut(offset); - } - - pub fn readableSliceOfLen(self: *Self, len: usize) []const T { - assert(len <= self.count); - const buf = self.readableSlice(0); - if (buf.len >= len) { - return buf[0..len]; - } else { - self.realign(); - return self.readableSlice(0)[0..len]; - } - } - /// Discard first `count` items in the fifo pub fn discard(self: *Self, count: usize) void { assert(count <= self.count); @@ -143,28 +113,6 @@ pub fn LinearFifo(comptime T: type) type { return c; } - /// Read data from the fifo into `dst`, returns number of items copied. - pub fn read(self: *Self, dst: []T) usize { - var dst_left = dst; - - while (dst_left.len > 0) { - const slice = self.readableSlice(0); - if (slice.len == 0) break; - const n = @min(slice.len, dst_left.len); - @memcpy(dst_left[0..n], slice[0..n]); - self.discard(n); - dst_left = dst_left[n..]; - } - - return dst.len - dst_left.len; - } - - /// Same as `read` except it returns an error union - /// The purpose of this function existing is to match `std.io.Reader` API. - fn readFn(self: *Self, dest: []u8) error{}!usize { - return self.read(dest); - } - /// Returns number of items available in fifo pub fn writableLength(self: Self) usize { return self.buf.len - self.count; @@ -183,20 +131,6 @@ pub fn LinearFifo(comptime T: type) type { } } - /// Returns a writable buffer of at least `size` items, allocating memory as needed. - /// Use `fifo.update` once you've written data to it. - pub fn writableWithSize(self: *Self, size: usize) ![]T { - try self.ensureUnusedCapacity(size); - - // try to avoid realigning buffer - var slice = self.writableSlice(0); - if (slice.len < size) { - self.realign(); - slice = self.writableSlice(0); - } - return slice; - } - /// Update the tail location of the buffer (usually follows use of writable/writableWithSize) pub fn update(self: *Self, count: usize) void { assert(self.count + count <= self.buf.len); @@ -231,201 +165,5 @@ pub fn LinearFifo(comptime T: type) type { self.buf[tail] = item; self.update(1); } - - /// Appends the data in `src` to the fifo. - /// Allocates more memory as necessary - pub fn write(self: *Self, src: []const T) !void { - try self.ensureUnusedCapacity(src.len); - - return self.writeAssumeCapacity(src); - } - - /// Same as `write` except it returns the number of bytes written, which is always the same - /// as `bytes.len`. The purpose of this function existing is to match `std.io.Writer` API. - fn appendWrite(self: *Self, bytes: []const u8) error{OutOfMemory}!usize { - try self.write(bytes); - return bytes.len; - } - - /// Make `count` items available before the current read location - fn rewind(self: *Self, count: usize) void { - assert(self.writableLength() >= count); - - var head = self.head + (self.buf.len - count); - head &= self.buf.len - 1; - self.head = head; - self.count += count; - } - - /// Place data back into the read stream - pub fn unget(self: *Self, src: []const T) !void { - try self.ensureUnusedCapacity(src.len); - - self.rewind(src.len); - - const slice = self.readableSliceMut(0); - if (src.len < slice.len) { - @memcpy(slice[0..src.len], src); - } else { - @memcpy(slice, src[0..slice.len]); - const slice2 = self.readableSliceMut(slice.len); - @memcpy(slice2[0 .. src.len - slice.len], src[slice.len..]); - } - } - - /// Returns the item at `offset`. - /// Asserts offset is within bounds. - pub fn peekItem(self: Self, offset: usize) T { - assert(offset < self.count); - - var index = self.head + offset; - index &= self.buf.len - 1; - return self.buf[index]; - } - - pub fn toOwnedSlice(self: *Self) Allocator.Error![]T { - if (self.head != 0) self.realign(); - assert(self.head == 0); - assert(self.count <= self.buf.len); - const allocator = self.allocator; - if (allocator.resize(self.buf, self.count)) { - const result = self.buf[0..self.count]; - self.* = Self.init(allocator); - return result; - } - const new_memory = try allocator.dupe(T, self.buf[0..self.count]); - allocator.free(self.buf); - self.* = Self.init(allocator); - return new_memory; - } }; } - -test "LinearFifo(u8, .Dynamic) discard(0) from empty buffer should not error on overflow" { - var fifo = LinearFifo(u8, .Dynamic).init(testing.allocator); - defer fifo.deinit(); - - // If overflow is not explicitly allowed this will crash in debug / safe mode - fifo.discard(0); -} - -test "LinearFifo(u8, .Dynamic)" { - var fifo = LinearFifo(u8, .Dynamic).init(testing.allocator); - defer fifo.deinit(); - - try fifo.write("HELLO"); - try testing.expectEqual(@as(usize, 5), fifo.readableLength()); - try testing.expectEqualSlices(u8, "HELLO", fifo.readableSlice(0)); - - { - var i: usize = 0; - while (i < 5) : (i += 1) { - try fifo.write(&[_]u8{fifo.peekItem(i)}); - } - try testing.expectEqual(@as(usize, 10), fifo.readableLength()); - try testing.expectEqualSlices(u8, "HELLOHELLO", fifo.readableSlice(0)); - } - - { - try testing.expectEqual(@as(u8, 'H'), fifo.readItem().?); - try testing.expectEqual(@as(u8, 'E'), fifo.readItem().?); - try testing.expectEqual(@as(u8, 'L'), fifo.readItem().?); - try testing.expectEqual(@as(u8, 'L'), fifo.readItem().?); - try testing.expectEqual(@as(u8, 'O'), fifo.readItem().?); - } - try testing.expectEqual(@as(usize, 5), fifo.readableLength()); - - { // Writes that wrap around - try testing.expectEqual(@as(usize, 11), fifo.writableLength()); - try testing.expectEqual(@as(usize, 6), fifo.writableSlice(0).len); - fifo.writeAssumeCapacity("6 {}, .stdio => { + var stdin_reader = fs.File.stdin().reader(&stdin_buffer); + var stdout_writer = fs.File.stdout().writer(&stdout_buffer); try serve( comp, - .stdin(), - .stdout(), + &stdin_reader.interface, + &stdout_writer.interface, test_exec_args.items, self_exe_path, arg_mode, @@ -3584,10 +3588,13 @@ fn buildOutputType( const conn = try server.accept(); defer conn.stream.close(); + var input = conn.stream.reader(&stdin_buffer); + var output = conn.stream.writer(&stdout_buffer); + try serve( comp, - .{ .handle = conn.stream.handle }, - .{ .handle = conn.stream.handle }, + input.interface(), + &output.interface, test_exec_args.items, self_exe_path, arg_mode, @@ -4053,8 +4060,8 @@ fn saveState(comp: *Compilation, incremental: bool) void { fn serve( comp: *Compilation, - in: fs.File, - out: fs.File, + in: *std.Io.Reader, + out: *std.Io.Writer, test_exec_args: []const ?[]const u8, self_exe_path: ?[]const u8, arg_mode: ArgMode, @@ -4064,12 +4071,10 @@ fn serve( const gpa = comp.gpa; var server = try Server.init(.{ - .gpa = gpa, .in = in, .out = out, .zig_version = build_options.version, }); - defer server.deinit(); var child_pid: ?std.process.Child.Id = null; @@ -5491,10 +5496,10 @@ fn jitCmd( defer comp.destroy(); if (options.server) { + var stdout_writer = fs.File.stdout().writer(&stdout_buffer); var server: std.zig.Server = .{ - .out = fs.File.stdout(), + .out = &stdout_writer.interface, .in = undefined, // won't be receiving messages - .receive_fifo = undefined, // won't be receiving messages }; try comp.update(root_prog_node); @@ -6058,7 +6063,7 @@ fn cmdAstCheck( }; } else fs.File.stdin(); defer if (zig_source_path != null) f.close(); - var file_reader: fs.File.Reader = f.reader(&stdio_buffer); + var file_reader: fs.File.Reader = f.reader(&stdin_buffer); break :s std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| { fatal("unable to load file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); }; @@ -6076,7 +6081,7 @@ fn cmdAstCheck( const tree = try Ast.parse(arena, source, mode); - var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); + var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); const stdout_bw = &stdout_writer.interface; switch (mode) { .zig => { @@ -6291,7 +6296,7 @@ fn detectNativeCpuWithLLVM( } fn printCpu(cpu: std.Target.Cpu) !void { - var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); + var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); const stdout_bw = &stdout_writer.interface; if (cpu.model.llvm_name) |llvm_name| { @@ -6340,7 +6345,7 @@ fn cmdDumpLlvmInts( const dl = tm.createTargetDataLayout(); const context = llvm.Context.create(); - var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); + var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); const stdout_bw = &stdout_writer.interface; for ([_]u16{ 1, 8, 16, 32, 64, 128, 256 }) |bits| { const int_type = context.intType(bits); @@ -6369,9 +6374,8 @@ fn cmdDumpZir( defer f.close(); const zir = try Zcu.loadZirCache(arena, f); - var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); + var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); const stdout_bw = &stdout_writer.interface; - { const instruction_bytes = zir.instructions.len * // Here we don't use @sizeOf(Zir.Inst.Data) because it would include @@ -6417,7 +6421,7 @@ fn cmdChangelist( var f = fs.cwd().openFile(old_source_path, .{}) catch |err| fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); defer f.close(); - var file_reader: fs.File.Reader = f.reader(&stdio_buffer); + var file_reader: fs.File.Reader = f.reader(&stdin_buffer); break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); }; @@ -6425,7 +6429,7 @@ fn cmdChangelist( var f = fs.cwd().openFile(new_source_path, .{}) catch |err| fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); defer f.close(); - var file_reader: fs.File.Reader = f.reader(&stdio_buffer); + var file_reader: fs.File.Reader = f.reader(&stdin_buffer); break :source std.zig.readSourceFileToEndAlloc(arena, &file_reader) catch |err| fatal("unable to read new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); }; @@ -6457,7 +6461,7 @@ fn cmdChangelist( var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); - var stdout_writer = fs.File.stdout().writerStreaming(&stdio_buffer); + var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); const stdout_bw = &stdout_writer.interface; { try stdout_bw.print("Instruction mappings:\n", .{}); @@ -6917,7 +6921,7 @@ fn cmdFetch( const name = switch (save) { .no => { - var stdout = fs.File.stdout().writerStreaming(&stdio_buffer); + var stdout = fs.File.stdout().writerStreaming(&stdout_buffer); try stdout.interface.print("{s}\n", .{package_hash_slice}); try stdout.interface.flush(); return cleanExit(); From bad836a69bf3c1da29f39ed1a6c8bf6c66febfb6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 06:45:25 -0700 Subject: [PATCH 02/10] Compilation: revert some stuff --- src/Compilation.zig | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 469a13b4a9ec..916a025bc973 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -998,13 +998,13 @@ pub const CObject = struct { const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; defer file.close(); - var buffer: [1024]u8 = undefined; - var file_reader = file.reader(&buffer); - file_reader.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; - var aw: Writer.Allocating = .init(eb.gpa); - defer aw.deinit(); - _ = file_reader.interface.streamDelimiterEnding(&aw.writer, '\n') catch break :source_line 0; - break :source_line try eb.addString(aw.getWritten()); + file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; + + var line = std.ArrayList(u8).init(eb.gpa); + defer line.deinit(); + file.deprecatedReader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0; + + break :source_line try eb.addString(line.items); }; return .{ @@ -5850,9 +5850,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr try child.spawn(); - var small_buffer: [1]u8 = undefined; - var stderr_reader = child.stderr.?.reader(&small_buffer); - const stderr = try stderr_reader.interface.allocRemaining(arena, .unlimited); + const stderr = try child.stderr.?.deprecatedReader().readAllAlloc(arena, std.math.maxInt(usize)); const term = child.wait() catch |err| { return comp.failCObj(c_object, "failed to spawn zig clang {s}: {s}", .{ argv.items[0], @errorName(err) }); From 83d1f88ac5f053f11b91d9c3d51f5c63355b8ca3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 10:42:04 -0700 Subject: [PATCH 03/10] std.debug: add assertAligned --- lib/std/debug.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index a7b88e4257c1..655852c65e83 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -566,6 +566,13 @@ pub fn assertReadable(slice: []const volatile u8) void { for (slice) |*byte| _ = byte.*; } +/// Invokes detectable illegal behavior when the provided array is not aligned +/// to the provided amount. +pub fn assertAligned(ptr: anytype, comptime alignment: std.mem.Alignment) void { + const aligned_ptr: *align(alignment.toByteUnits()) anyopaque = @alignCast(@ptrCast(ptr)); + _ = aligned_ptr; +} + /// Equivalent to `@panic` but with a formatted message. pub fn panic(comptime format: []const u8, args: anytype) noreturn { @branchHint(.cold); From bd64bf0e47e75481569dcc3ba519e3d2e7f7b276 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 10:42:24 -0700 Subject: [PATCH 04/10] std.mem: add byteSwapAllElements --- lib/std/mem.zig | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 33e68eedad64..1a61076f32ca 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -2179,22 +2179,8 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { const BackingInt = std.meta.Int(.unsigned, @bitSizeOf(S)); ptr.* = @bitCast(@byteSwap(@as(BackingInt, @bitCast(ptr.*)))); }, - .array => { - for (ptr) |*item| { - switch (@typeInfo(@TypeOf(item.*))) { - .@"struct", .@"union", .array => byteSwapAllFields(@TypeOf(item.*), item), - .@"enum" => { - item.* = @enumFromInt(@byteSwap(@intFromEnum(item.*))); - }, - .bool => {}, - .float => |float_info| { - item.* = @bitCast(@byteSwap(@as(std.meta.Int(.unsigned, float_info.bits), @bitCast(item.*)))); - }, - else => { - item.* = @byteSwap(item.*); - }, - } - } + .array => |info| { + byteSwapAllElements(info.child, ptr); }, else => { ptr.* = @byteSwap(ptr.*); @@ -2258,6 +2244,24 @@ test byteSwapAllFields { }, k); } +pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void { + for (slice) |*elem| { + switch (@typeInfo(@TypeOf(elem.*))) { + .@"struct", .@"union", .array => byteSwapAllFields(@TypeOf(elem.*), elem), + .@"enum" => { + elem.* = @enumFromInt(@byteSwap(@intFromEnum(elem.*))); + }, + .bool => {}, + .float => |float_info| { + elem.* = @bitCast(@byteSwap(@as(std.meta.Int(.unsigned, float_info.bits), @bitCast(elem.*)))); + }, + else => { + elem.* = @byteSwap(elem.*); + }, + } + } +} + /// Returns an iterator that iterates over the slices of `buffer` that are not /// any of the items in `delimiters`. /// From 8489bab1f46ef7a5cdcf598b10f1150a9e0c2f0d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 10:43:02 -0700 Subject: [PATCH 05/10] std.Io.Writer: add missing writeSliceSwap --- lib/std/Io/Writer.zig | 28 +++++++++++++++++++++++++++- lib/std/zig/Server.zig | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 4b0e142fb0f1..11bc05a00d93 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -851,6 +851,9 @@ pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian } } +/// If, `endian` is not native, +/// * Asserts that the buffer storage capacity is at least enough to store `@sizeOf(Elem)` +/// * Asserts that the buffer is aligned enough for `@alignOf(Elem)`. pub inline fn writeSliceEndian( w: *Writer, Elem: type, @@ -860,7 +863,22 @@ pub inline fn writeSliceEndian( if (native_endian == endian) { return writeAll(w, @ptrCast(slice)); } else { - return w.writeArraySwap(w, Elem, slice); + return writeSliceSwap(w, Elem, slice); + } +} + +/// Asserts that the buffer storage capacity is at least enough to store `@sizeOf(Elem)` +/// +/// Asserts that the buffer is aligned enough for `@alignOf(Elem)`. +pub fn writeSliceSwap(w: *Writer, Elem: type, slice: []const Elem) Error!void { + var i: usize = 0; + while (i < slice.len) { + const dest_bytes = try w.writableSliceGreedy(@sizeOf(Elem)); + const dest: []Elem = @alignCast(@ptrCast(dest_bytes[0 .. dest_bytes.len - dest_bytes.len % @sizeOf(Elem)])); + const copy_len = @min(dest.len, slice.len - i); + @memcpy(dest[0..copy_len], slice[i..][0..copy_len]); + i += copy_len; + std.mem.byteSwapAllElements(Elem, dest); } } @@ -2630,3 +2648,11 @@ test writeStruct { }, &buffer); } } + +test writeSliceEndian { + var buffer: [4]u8 align(2) = undefined; + var w: Writer = .fixed(&buffer); + const array: [2]u16 = .{ 0x1234, 0x5678 }; + try writeSliceEndian(&w, u16, &array, .big); + try testing.expectEqualSlices(u8, &.{ 0x12, 0x34, 0x56, 0x78 }, &buffer); +} diff --git a/lib/std/zig/Server.zig b/lib/std/zig/Server.zig index 38ad45e1e161..8fc016d284da 100644 --- a/lib/std/zig/Server.zig +++ b/lib/std/zig/Server.zig @@ -118,6 +118,8 @@ pub fn init(options: Options) !Server { .in = options.in, .out = options.out, }; + assert(s.out.buffer.len >= 4); + std.debug.assertAligned(s.out.buffer.ptr, .@"4"); try s.serveStringMessage(.zig_version, options.zig_version); return s; } From b956ae20af86384ef5d15b2417b0bf095b5b3740 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 11:15:12 -0700 Subject: [PATCH 06/10] frontend: align those stdio buffers --- src/main.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.zig b/src/main.zig index 9958c461b13e..dc931f119bf2 100644 --- a/src/main.zig +++ b/src/main.zig @@ -66,9 +66,9 @@ pub fn wasi_cwd() std.os.wasi.fd_t { const fatal = std.process.fatal; /// This can be global since stdin is a singleton. -var stdin_buffer: [4096]u8 = undefined; +var stdin_buffer: [4096]u8 align(std.heap.page_size_min) = undefined; /// This can be global since stdout is a singleton. -var stdout_buffer: [4096]u8 = undefined; +var stdout_buffer: [4096]u8 align(std.heap.page_size_min) = undefined; /// Shaming all the locations that inappropriately use an O(N) search algorithm. /// Please delete this and fix the compilation errors! From d396780925914025c42576d45a2f668a64f7336b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 11:16:31 -0700 Subject: [PATCH 07/10] Compilation: unrevert some stuff --- src/Compilation.zig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 916a025bc973..b5597017c4b2 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -998,13 +998,13 @@ pub const CObject = struct { const file = fs.cwd().openFile(file_name, .{}) catch break :source_line 0; defer file.close(); - file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; - - var line = std.ArrayList(u8).init(eb.gpa); - defer line.deinit(); - file.deprecatedReader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0; - - break :source_line try eb.addString(line.items); + var buffer: [1024]u8 = undefined; + var file_reader = file.reader(&buffer); + file_reader.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; + var aw: Writer.Allocating = .init(eb.gpa); + defer aw.deinit(); + _ = file_reader.interface.streamDelimiterEnding(&aw.writer, '\n') catch break :source_line 0; + break :source_line try eb.addString(aw.getWritten()); }; return .{ From 83960e0eb068f786c46c3fe559016e1e9faea3cd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 17:38:13 -0700 Subject: [PATCH 08/10] disable -fno-llvm -target wasm32-wasi testing no active maintainer, and it's failing to lower some basic stuff --- test/src/Cases.zig | 2 -- test/tests.zig | 19 ++++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/test/src/Cases.zig b/test/src/Cases.zig index 522fe6b38557..a92f9fd158d3 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -800,8 +800,6 @@ const TestManifestConfigDefaults = struct { } // Windows defaults = defaults ++ "x86_64-windows" ++ ","; - // Wasm - defaults = defaults ++ "wasm32-wasi"; break :blk defaults; }; } else if (std.mem.eql(u8, key, "output_mode")) { diff --git a/test/tests.zig b/test/tests.zig index 2a6c4166fa51..db4407172f96 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -1335,15 +1335,16 @@ const test_targets = blk: { // WASI Targets - .{ - .target = .{ - .cpu_arch = .wasm32, - .os_tag = .wasi, - .abi = .none, - }, - .use_llvm = false, - .use_lld = false, - }, + // TODO: lowerTry for pointers + //.{ + // .target = .{ + // .cpu_arch = .wasm32, + // .os_tag = .wasi, + // .abi = .none, + // }, + // .use_llvm = false, + // .use_lld = false, + //}, .{ .target = .{ .cpu_arch = .wasm32, From 741a66e03cd8644d01b38849f2bd8f70cae6beca Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 18 Jul 2025 20:51:37 -0700 Subject: [PATCH 09/10] std.zig.llvm.BitcodeReader: fix 32-bit skipBlock --- lib/std/zig/llvm/BitcodeReader.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/zig/llvm/BitcodeReader.zig b/lib/std/zig/llvm/BitcodeReader.zig index f1d47e93c013..f691f12a8c9c 100644 --- a/lib/std/zig/llvm/BitcodeReader.zig +++ b/lib/std/zig/llvm/BitcodeReader.zig @@ -177,7 +177,7 @@ pub fn next(bc: *BitcodeReader) !?Item { pub fn skipBlock(bc: *BitcodeReader, block: Block) !void { assert(bc.bit_offset == 0); - try bc.reader.discardAll(4 * @as(u34, block.len)); + try bc.reader.discardAll(4 * @as(usize, block.len)); try bc.endBlock(); } From c40fb96ca358e2ef28aecc2b7ebc5ffab43ccac8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 19 Jul 2025 21:53:48 -0700 Subject: [PATCH 10/10] std.Io.Writer: fix writeSliceSwap tried to be too clever, wrote bad code --- lib/compiler/test_runner.zig | 12 ++++++------ lib/std/Build/Step/Run.zig | 2 +- lib/std/Io/Reader.zig | 34 +++++++++++++++++----------------- lib/std/Io/Writer.zig | 23 +++++++---------------- lib/std/zig/Server.zig | 6 ++---- src/Zcu.zig | 2 +- src/Zcu/PerThread.zig | 2 +- 7 files changed, 35 insertions(+), 46 deletions(-) diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index a69066f09cb9..8b60a75399a8 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -10,10 +10,10 @@ pub const std_options: std.Options = .{ }; var log_err_count: usize = 0; -var fba_buffer: [8192]u8 = undefined; var fba = std.heap.FixedBufferAllocator.init(&fba_buffer); -var stdin_buffer: [std.heap.page_size_min]u8 align(std.heap.page_size_min) = undefined; -var stdout_buffer: [std.heap.page_size_min]u8 align(std.heap.page_size_min) = undefined; +var fba_buffer: [8192]u8 = undefined; +var stdin_buffer: [4096]u8 = undefined; +var stdout_buffer: [4096]u8 = undefined; const crippled = switch (builtin.zig_backend) { .stage2_powerpc, @@ -68,8 +68,8 @@ pub fn main() void { fn mainServer() !void { @disableInstrumentation(); - var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer); - var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + var stdin_reader = std.fs.File.stdin().readerStreaming(&stdin_buffer); + var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer); var server = try std.zig.Server.init(.{ .in = &stdin_reader.interface, .out = &stdout_writer.interface, @@ -104,7 +104,7 @@ fn mainServer() !void { defer testing.allocator.free(expected_panic_msgs); for (test_fns, names, expected_panic_msgs) |test_fn, *name, *expected_panic_msg| { - name.* = @as(u32, @intCast(string_bytes.items.len)); + name.* = @intCast(string_bytes.items.len); try string_bytes.ensureUnusedCapacity(testing.allocator, test_fn.name.len + 1); string_bytes.appendSliceAssumeCapacity(test_fn.name); string_bytes.appendAssumeCapacity(0); diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index b4e2e73c0a0b..1742da33c8ff 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1742,7 +1742,7 @@ fn sendMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag) !void { .tag = tag, .bytes_len = 0, }; - try file.writeAll(std.mem.asBytes(&header)); + try file.writeAll(@ptrCast(&header)); } fn sendRunTestMessage(file: std.fs.File, tag: std.zig.Client.Message.Tag, index: u32) !void { diff --git a/lib/std/Io/Reader.zig b/lib/std/Io/Reader.zig index f2a1ec7287bc..497b906c9788 100644 --- a/lib/std/Io/Reader.zig +++ b/lib/std/Io/Reader.zig @@ -1108,9 +1108,9 @@ pub fn takeVarInt(r: *Reader, comptime Int: type, endian: std.builtin.Endian, n: /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`. /// /// See also: -/// * `peekStructReference` +/// * `peekStructPointer` /// * `takeStruct` -pub fn takeStructReference(r: *Reader, comptime T: type) Error!*align(1) T { +pub fn takeStructPointer(r: *Reader, comptime T: type) Error!*align(1) T { // Only extern and packed structs have defined in-memory layout. comptime assert(@typeInfo(T).@"struct".layout != .auto); return @ptrCast(try r.takeArray(@sizeOf(T))); @@ -1122,9 +1122,9 @@ pub fn takeStructReference(r: *Reader, comptime T: type) Error!*align(1) T { /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`. /// /// See also: -/// * `takeStructReference` +/// * `takeStructPointer` /// * `peekStruct` -pub fn peekStructReference(r: *Reader, comptime T: type) Error!*align(1) T { +pub fn peekStructPointer(r: *Reader, comptime T: type) Error!*align(1) T { // Only extern and packed structs have defined in-memory layout. comptime assert(@typeInfo(T).@"struct".layout != .auto); return @ptrCast(try r.peekArray(@sizeOf(T))); @@ -1136,14 +1136,14 @@ pub fn peekStructReference(r: *Reader, comptime T: type) Error!*align(1) T { /// when `endian` is comptime-known and matches the host endianness. /// /// See also: -/// * `takeStructReference` +/// * `takeStructPointer` /// * `peekStruct` pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T { switch (@typeInfo(T)) { .@"struct" => |info| switch (info.layout) { .auto => @compileError("ill-defined memory layout"), .@"extern" => { - var res = (try r.takeStructReference(T)).*; + var res = (try r.takeStructPointer(T)).*; if (native_endian != endian) std.mem.byteSwapAllFields(T, &res); return res; }, @@ -1162,13 +1162,13 @@ pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endia /// /// See also: /// * `takeStruct` -/// * `peekStructReference` +/// * `peekStructPointer` pub inline fn peekStruct(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T { switch (@typeInfo(T)) { .@"struct" => |info| switch (info.layout) { .auto => @compileError("ill-defined memory layout"), .@"extern" => { - var res = (try r.peekStructReference(T)).*; + var res = (try r.peekStructPointer(T)).*; if (native_endian != endian) std.mem.byteSwapAllFields(T, &res); return res; }, @@ -1557,27 +1557,27 @@ test takeVarInt { try testing.expectError(error.EndOfStream, r.takeVarInt(u16, .little, 1)); } -test takeStructReference { +test takeStructPointer { var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 }); const S = extern struct { a: u8, b: u16 }; switch (native_endian) { - .little => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.takeStructReference(S)).*), - .big => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.takeStructReference(S)).*), + .little => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.takeStructPointer(S)).*), + .big => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.takeStructPointer(S)).*), } - try testing.expectError(error.EndOfStream, r.takeStructReference(S)); + try testing.expectError(error.EndOfStream, r.takeStructPointer(S)); } -test peekStructReference { +test peekStructPointer { var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 }); const S = extern struct { a: u8, b: u16 }; switch (native_endian) { .little => { - try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructReference(S)).*); - try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructReference(S)).*); + try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructPointer(S)).*); + try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStructPointer(S)).*); }, .big => { - try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructReference(S)).*); - try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructReference(S)).*); + try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructPointer(S)).*); + try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStructPointer(S)).*); }, } } diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 11bc05a00d93..4d8f04b24674 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -851,9 +851,6 @@ pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian } } -/// If, `endian` is not native, -/// * Asserts that the buffer storage capacity is at least enough to store `@sizeOf(Elem)` -/// * Asserts that the buffer is aligned enough for `@alignOf(Elem)`. pub inline fn writeSliceEndian( w: *Writer, Elem: type, @@ -867,18 +864,11 @@ pub inline fn writeSliceEndian( } } -/// Asserts that the buffer storage capacity is at least enough to store `@sizeOf(Elem)` -/// -/// Asserts that the buffer is aligned enough for `@alignOf(Elem)`. pub fn writeSliceSwap(w: *Writer, Elem: type, slice: []const Elem) Error!void { - var i: usize = 0; - while (i < slice.len) { - const dest_bytes = try w.writableSliceGreedy(@sizeOf(Elem)); - const dest: []Elem = @alignCast(@ptrCast(dest_bytes[0 .. dest_bytes.len - dest_bytes.len % @sizeOf(Elem)])); - const copy_len = @min(dest.len, slice.len - i); - @memcpy(dest[0..copy_len], slice[i..][0..copy_len]); - i += copy_len; - std.mem.byteSwapAllElements(Elem, dest); + for (slice) |elem| { + var tmp = elem; + std.mem.byteSwapAllFields(Elem, &tmp); + try w.writeAll(@ptrCast(&tmp)); } } @@ -2650,9 +2640,10 @@ test writeStruct { } test writeSliceEndian { - var buffer: [4]u8 align(2) = undefined; + var buffer: [5]u8 align(2) = undefined; var w: Writer = .fixed(&buffer); + try w.writeByte('x'); const array: [2]u16 = .{ 0x1234, 0x5678 }; try writeSliceEndian(&w, u16, &array, .big); - try testing.expectEqualSlices(u8, &.{ 0x12, 0x34, 0x56, 0x78 }, &buffer); + try testing.expectEqualSlices(u8, &.{ 'x', 0x12, 0x34, 0x56, 0x78 }, &buffer); } diff --git a/lib/std/zig/Server.zig b/lib/std/zig/Server.zig index 8fc016d284da..12bd259b16d8 100644 --- a/lib/std/zig/Server.zig +++ b/lib/std/zig/Server.zig @@ -118,8 +118,6 @@ pub fn init(options: Options) !Server { .in = options.in, .out = options.out, }; - assert(s.out.buffer.len >= 4); - std.debug.assertAligned(s.out.buffer.ptr, .@"4"); try s.serveStringMessage(.zig_version, options.zig_version); return s; } @@ -203,8 +201,8 @@ pub const TestMetadata = struct { pub fn serveTestMetadata(s: *Server, test_metadata: TestMetadata) !void { const header: OutMessage.TestMetadata = .{ - .tests_len = @as(u32, @intCast(test_metadata.names.len)), - .string_bytes_len = @as(u32, @intCast(test_metadata.string_bytes.len)), + .tests_len = @intCast(test_metadata.names.len), + .string_bytes_len = @intCast(test_metadata.string_bytes.len), }; const trailing = 2; const bytes_len = @sizeOf(OutMessage.TestMetadata) + diff --git a/src/Zcu.zig b/src/Zcu.zig index 897bb6e89eb9..d337f0b943f7 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -2821,7 +2821,7 @@ pub fn loadZirCache(gpa: Allocator, cache_file: std.fs.File) !Zir { var buffer: [2000]u8 = undefined; var file_reader = cache_file.reader(&buffer); return result: { - const header = file_reader.interface.takeStructReference(Zir.Header) catch |err| break :result err; + const header = file_reader.interface.takeStructPointer(Zir.Header) catch |err| break :result err; break :result loadZirCacheBody(gpa, header.*, &file_reader.interface); } catch |err| switch (err) { error.ReadFailed => return file_reader.err.?, diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index dc2308add102..26f008e1c888 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -349,7 +349,7 @@ fn loadZirZoirCache( const cache_br = &cache_fr.interface; // First we read the header to determine the lengths of arrays. - const header = (cache_br.takeStructReference(Header) catch |err| switch (err) { + const header = (cache_br.takeStructPointer(Header) catch |err| switch (err) { error.ReadFailed => return cache_fr.err.?, // This can happen if Zig bails out of this function between creating // the cached file and writing it.