Merge remote-tracking branch 'origin/master' into wrangle-writer-buffering

This commit is contained in:
Andrew Kelley 2025-07-15 10:05:00 -07:00
commit 87be80f6e9
10 changed files with 100 additions and 187 deletions

View File

@ -1,8 +1,7 @@
const std = @import("std");
const expect = std.testing.expect;
const print = std.debug.print;
test "defer unwinding" {
pub fn main() void {
print("\n", .{});
defer {
@ -19,4 +18,4 @@ test "defer unwinding" {
}
}
// test
// exe=succeed

View File

@ -1,11 +1,14 @@
test "inline function call" {
const std = @import("std");
pub fn main() void {
if (foo(1200, 34) != 1234) {
@compileError("bad");
}
}
inline fn foo(a: i32, b: i32) i32 {
std.debug.print("runtime a = {} b = {}", .{ a, b });
return a + b;
}
// test
// exe=succeed

View File

@ -1096,33 +1096,41 @@ pub inline fn takeInt(r: *Reader, comptime T: type, endian: std.builtin.Endian)
return std.mem.readInt(T, try r.takeArray(n), endian);
}
/// Asserts the buffer was initialized with a capacity at least `@bitSizeOf(T) / 8`.
pub inline fn peekInt(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T {
const n = @divExact(@typeInfo(T).int.bits, 8);
return std.mem.readInt(T, try r.peekArray(n), endian);
}
/// Asserts the buffer was initialized with a capacity at least `n`.
pub fn takeVarInt(r: *Reader, comptime Int: type, endian: std.builtin.Endian, n: usize) Error!Int {
assert(n <= @sizeOf(Int));
return std.mem.readVarInt(Int, try r.take(n), endian);
}
/// Obtains an unaligned pointer to the beginning of the stream, reinterpreted
/// as a pointer to the provided type, advancing the seek position.
///
/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
///
/// Advances the seek position.
///
/// See also:
/// * `peekStruct`
/// * `takeStructEndian`
pub fn takeStruct(r: *Reader, comptime T: type) Error!*align(1) T {
/// * `peekStructReference`
/// * `takeStruct`
pub fn takeStructReference(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)));
}
/// Obtains an unaligned pointer to the beginning of the stream, reinterpreted
/// as a pointer to the provided type, without advancing the seek position.
///
/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
///
/// Does not advance the seek position.
///
/// See also:
/// * `takeStruct`
/// * `peekStructEndian`
pub fn peekStruct(r: *Reader, comptime T: type) Error!*align(1) T {
/// * `takeStructReference`
/// * `peekStruct`
pub fn peekStructReference(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)));
@ -1134,12 +1142,23 @@ pub fn peekStruct(r: *Reader, comptime T: type) Error!*align(1) T {
/// when `endian` is comptime-known and matches the host endianness.
///
/// See also:
/// * `takeStruct`
/// * `peekStructEndian`
pub inline fn takeStructEndian(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T {
var res = (try r.takeStruct(T)).*;
if (native_endian != endian) std.mem.byteSwapAllFields(T, &res);
return res;
/// * `takeStructReference`
/// * `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)).*;
if (native_endian != endian) std.mem.byteSwapAllFields(T, &res);
return res;
},
.@"packed" => {
return takeInt(r, info.backing_integer.?, endian);
},
},
else => @compileError("not a struct"),
}
}
/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
@ -1148,12 +1167,23 @@ pub inline fn takeStructEndian(r: *Reader, comptime T: type, endian: std.builtin
/// when `endian` is comptime-known and matches the host endianness.
///
/// See also:
/// * `takeStructEndian`
/// * `peekStruct`
pub inline fn peekStructEndian(r: *Reader, comptime T: type, endian: std.builtin.Endian) Error!T {
var res = (try r.peekStruct(T)).*;
if (native_endian != endian) std.mem.byteSwapAllFields(T, &res);
return res;
/// * `takeStruct`
/// * `peekStructReference`
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)).*;
if (native_endian != endian) std.mem.byteSwapAllFields(T, &res);
return res;
},
.@"packed" => {
return peekInt(r, info.backing_integer.?, endian);
},
},
else => @compileError("not a struct"),
}
}
pub const TakeEnumError = Error || error{InvalidEnumTag};
@ -1519,43 +1549,43 @@ test takeVarInt {
try testing.expectError(error.EndOfStream, r.takeVarInt(u16, .little, 1));
}
test takeStruct {
test takeStructReference {
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.takeStruct(S)).*),
.big => try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.takeStruct(S)).*),
.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)).*),
}
try testing.expectError(error.EndOfStream, r.takeStruct(S));
try testing.expectError(error.EndOfStream, r.takeStructReference(S));
}
test peekStructReference {
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)).*);
},
.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)).*);
},
}
}
test takeStruct {
var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 });
const S = extern struct { a: u8, b: u16 };
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), try r.takeStruct(S, .big));
try testing.expectError(error.EndOfStream, r.takeStruct(S, .little));
}
test peekStruct {
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.peekStruct(S)).*);
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), (try r.peekStruct(S)).*);
},
.big => {
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStruct(S)).*);
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), (try r.peekStruct(S)).*);
},
}
}
test takeStructEndian {
var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 });
const S = extern struct { a: u8, b: u16 };
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), try r.takeStructEndian(S, .big));
try testing.expectError(error.EndOfStream, r.takeStructEndian(S, .little));
}
test peekStructEndian {
var r: Reader = .fixed(&.{ 0x12, 0x00, 0x34, 0x56 });
const S = extern struct { a: u8, b: u16 };
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), try r.peekStructEndian(S, .big));
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), try r.peekStructEndian(S, .little));
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x3456 }), try r.peekStruct(S, .big));
try testing.expectEqual(@as(S, .{ .a = 0x12, .b = 0x5634 }), try r.peekStruct(S, .little));
}
test takeEnum {

View File

@ -796,16 +796,9 @@ pub inline fn writeInt(w: *Writer, comptime T: type, value: T, endian: std.built
return w.writeAll(&bytes);
}
pub fn writeStruct(w: *Writer, value: anytype) Error!void {
// Only extern and packed structs have defined in-memory layout.
comptime assert(@typeInfo(@TypeOf(value)).@"struct".layout != .auto);
return w.writeAll(std.mem.asBytes(&value));
}
/// The function is inline to avoid the dead code in case `endian` is
/// comptime-known and matches host endianness.
/// TODO: make sure this value is not a reference type
pub inline fn writeStructEndian(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void {
pub inline fn writeStruct(w: *Writer, value: anytype, endian: std.builtin.Endian) Error!void {
switch (@typeInfo(@TypeOf(value))) {
.@"struct" => |info| switch (info.layout) {
.auto => @compileError("ill-defined memory layout"),
@ -2446,12 +2439,14 @@ pub const Allocating = struct {
pub fn toOwnedSlice(a: *Allocating) error{OutOfMemory}![]u8 {
var list = a.toArrayList();
defer a.setArrayList(list);
return list.toOwnedSlice(a.allocator);
}
pub fn toOwnedSliceSentinel(a: *Allocating, comptime sentinel: u8) error{OutOfMemory}![:sentinel]u8 {
const gpa = a.allocator;
var list = toArrayList(a);
defer a.setArrayList(list);
return list.toOwnedSliceSentinel(gpa, sentinel);
}

View File

@ -507,7 +507,7 @@ pub const Os = struct {
.freebsd => .{
.semver = .{
.min = blk: {
const default_min: std.SemanticVersion = .{ .major = 13, .minor = 4, .patch = 0 };
const default_min: std.SemanticVersion = .{ .major = 14, .minor = 0, .patch = 0 };
for (std.zig.target.available_libcs) |libc| {
if (libc.arch != arch or libc.os != tag or libc.abi != abi) continue;
@ -525,7 +525,7 @@ pub const Os = struct {
.netbsd => .{
.semver = .{
.min = blk: {
const default_min: std.SemanticVersion = .{ .major = 9, .minor = 4, .patch = 0 };
const default_min: std.SemanticVersion = .{ .major = 10, .minor = 1, .patch = 0 };
for (std.zig.target.available_libcs) |libc| {
if (libc.arch != arch or libc.os != tag or libc.abi != abi) continue;

View File

@ -1001,6 +1001,11 @@ test "sigset_t bits" {
if (native_os == .wasi or native_os == .windows)
return error.SkipZigTest;
if (true) {
// https://github.com/ziglang/zig/issues/24380
return error.SkipZigTest;
}
const S = struct {
var expected_sig: i32 = undefined;
var handler_called_count: u32 = 0;

View File

@ -2809,7 +2809,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.takeStruct(Zir.Header) catch |err| break :result err;
const header = file_reader.interface.takeStructReference(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.?,

View File

@ -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.takeStruct(Header) catch |err| switch (err) {
const header = (cache_br.takeStructReference(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.

View File

@ -334,6 +334,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
return jitCmd(gpa, arena, cmd_args, .{
.cmd_name = "std",
.root_src_path = "std-docs.zig",
.windows_libs = &.{"ws2_32"},
.prepend_zig_lib_dir_path = true,
.prepend_zig_exe_path = true,
.prepend_global_cache_path = true,

View File

@ -104,12 +104,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .aarch64,
.os_tag = .freebsd,
// Remove this when we bump our baseline to 14.0.0.
.os_version_min = .{ .semver = .{
.major = 14,
.minor = 0,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -119,12 +113,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .arm,
.os_tag = .freebsd,
// Remove this when we bump our baseline to 14.0.0.
.os_version_min = .{ .semver = .{
.major = 14,
.minor = 0,
.patch = 0,
} },
.abi = .eabihf,
},
.link_libc = true,
@ -136,12 +124,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .powerpc64,
.os_tag = .freebsd,
// Remove this when we bump our baseline to 14.0.0.
.os_version_min = .{ .semver = .{
.major = 14,
.minor = 0,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -151,12 +133,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .powerpc64le,
.os_tag = .freebsd,
// Remove this when we bump our baseline to 14.0.0.
.os_version_min = .{ .semver = .{
.major = 14,
.minor = 0,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -166,12 +142,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .riscv64,
.os_tag = .freebsd,
// Remove this when we bump our baseline to 14.0.0.
.os_version_min = .{ .semver = .{
.major = 14,
.minor = 0,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -181,12 +151,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .x86_64,
.os_tag = .freebsd,
// Remove this when we bump our baseline to 14.0.0.
.os_version_min = .{ .semver = .{
.major = 14,
.minor = 0,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -1236,12 +1200,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .aarch64,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -1251,12 +1209,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .aarch64_be,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -1266,12 +1218,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .arm,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabi,
},
.link_libc = true,
@ -1280,12 +1226,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .arm,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabihf,
},
.link_libc = true,
@ -1295,12 +1235,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .armeb,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabi,
},
.link_libc = true,
@ -1309,12 +1243,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .armeb,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabihf,
},
.link_libc = true,
@ -1324,12 +1252,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .mips,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabi,
},
.link_libc = true,
@ -1338,12 +1260,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .mips,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabihf,
},
.link_libc = true,
@ -1353,12 +1269,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .mipsel,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabi,
},
.link_libc = true,
@ -1367,12 +1277,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .mipsel,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabihf,
},
.link_libc = true,
@ -1382,12 +1286,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .powerpc,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabi,
},
.link_libc = true,
@ -1396,12 +1294,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .powerpc,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .eabihf,
},
.link_libc = true,
@ -1411,12 +1303,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .x86,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,
@ -1426,12 +1312,6 @@ const test_targets = blk: {
.target = .{
.cpu_arch = .x86_64,
.os_tag = .netbsd,
// Remove this when we bump our baseline to 10.1.0.
.os_version_min = .{ .semver = .{
.major = 10,
.minor = 1,
.patch = 0,
} },
.abi = .none,
},
.link_libc = true,