@zigc/lib 0.15.1 → 0.15.2-test.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/build-web/fuzz.zig +6 -6
- package/build-web/time_report.zig +14 -13
- package/compiler/reduce/Walk.zig +10 -9
- package/compiler/reduce.zig +19 -20
- package/compiler/resinator/compile.zig +1 -1
- package/compiler_rt/arm.zig +1 -1
- package/init/build.zig +1 -1
- package/libc/include/generic-glibc/arpa/inet.h +3 -0
- package/libc/musl/src/fenv/loongarch64/fenv-sf.c +3 -0
- package/package.json +1 -1
- package/std/Build/Step/Compile.zig +20 -1
- package/std/Build/Step/TranslateC.zig +6 -0
- package/std/Build/WebServer.zig +1 -1
- package/std/Build.zig +4 -1
- package/std/Io/Reader/Limited.zig +44 -0
- package/std/Io/Reader.zig +128 -28
- package/std/Io/Writer.zig +31 -6
- package/std/Target.zig +8 -0
- package/std/Thread.zig +3 -4
- package/std/c.zig +87 -26
- package/std/crypto/aes_ocb.zig +32 -3
- package/std/crypto/tls/Client.zig +19 -8
- package/std/debug.zig +1 -1
- package/std/fs/Dir.zig +2 -1
- package/std/fs/File.zig +105 -104
- package/std/http/Client.zig +3 -2
- package/std/json/static.zig +3 -3
- package/std/math/big/int.zig +3 -4
- package/std/math/powi.zig +1 -0
- package/std/mem/Allocator.zig +3 -1
- package/std/mem.zig +3 -1
- package/std/net.zig +3 -2
- package/std/os/linux/bpf.zig +2 -2
- package/std/os/linux/powerpc.zig +74 -12
- package/std/os/linux/powerpc64.zig +74 -12
- package/std/os/linux.zig +7 -2
- package/std/os/uefi/protocol/service_binding.zig +1 -1
- package/std/os/uefi/tables.zig +1 -1
- package/std/pie.zig +1 -1
- package/std/posix.zig +6 -4
- package/std/process/Child.zig +5 -1
- package/std/process.zig +16 -2
- package/std/sort/pdq.zig +48 -1
- package/std/testing.zig +60 -0
- package/std/zig/llvm/BitcodeReader.zig +5 -1
- package/std/zig/system/linux.zig +1 -4
- package/std/zig/system.zig +3 -2
- package/std/zon/parse.zig +1 -0
- package/ubsan_rt.zig +3 -3
|
@@ -15,84 +15,125 @@ const sockaddr = linux.sockaddr;
|
|
|
15
15
|
const timespec = linux.timespec;
|
|
16
16
|
|
|
17
17
|
pub fn syscall0(number: SYS) usize {
|
|
18
|
+
// r0 is both an input register and a clobber. musl and glibc achieve this with
|
|
19
|
+
// a "+" constraint, which isn't supported in Zig, so instead we separately list
|
|
20
|
+
// r0 as both an input and an output. (Listing it as an input and a clobber would
|
|
21
|
+
// cause the C backend to emit invalid code; see #25209.)
|
|
22
|
+
var r0_out: usize = undefined;
|
|
18
23
|
return asm volatile (
|
|
19
24
|
\\ sc
|
|
20
25
|
\\ bns+ 1f
|
|
21
26
|
\\ neg 3, 3
|
|
22
27
|
\\ 1:
|
|
23
28
|
: [ret] "={r3}" (-> usize),
|
|
29
|
+
[r0_out] "={r0}" (r0_out),
|
|
24
30
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
25
|
-
: .{ .memory = true, .cr0 = true, .
|
|
31
|
+
: .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
pub fn syscall1(number: SYS, arg1: usize) usize {
|
|
35
|
+
// r0 is both an input and a clobber.
|
|
36
|
+
var r0_out: usize = undefined;
|
|
29
37
|
return asm volatile (
|
|
30
38
|
\\ sc
|
|
31
39
|
\\ bns+ 1f
|
|
32
40
|
\\ neg 3, 3
|
|
33
41
|
\\ 1:
|
|
34
42
|
: [ret] "={r3}" (-> usize),
|
|
43
|
+
[r0_out] "={r0}" (r0_out),
|
|
35
44
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
36
45
|
[arg1] "{r3}" (arg1),
|
|
37
|
-
: .{ .memory = true, .cr0 = true, .
|
|
46
|
+
: .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
|
|
50
|
+
// These registers are both inputs and clobbers.
|
|
51
|
+
var r0_out: usize = undefined;
|
|
52
|
+
var r4_out: usize = undefined;
|
|
41
53
|
return asm volatile (
|
|
42
54
|
\\ sc
|
|
43
55
|
\\ bns+ 1f
|
|
44
56
|
\\ neg 3, 3
|
|
45
57
|
\\ 1:
|
|
46
58
|
: [ret] "={r3}" (-> usize),
|
|
59
|
+
[r0_out] "={r0}" (r0_out),
|
|
60
|
+
[r4_out] "={r4}" (r4_out),
|
|
47
61
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
48
62
|
[arg1] "{r3}" (arg1),
|
|
49
63
|
[arg2] "{r4}" (arg2),
|
|
50
|
-
: .{ .memory = true, .cr0 = true, .
|
|
64
|
+
: .{ .memory = true, .cr0 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
|
|
68
|
+
// These registers are both inputs and clobbers.
|
|
69
|
+
var r0_out: usize = undefined;
|
|
70
|
+
var r4_out: usize = undefined;
|
|
71
|
+
var r5_out: usize = undefined;
|
|
54
72
|
return asm volatile (
|
|
55
73
|
\\ sc
|
|
56
74
|
\\ bns+ 1f
|
|
57
75
|
\\ neg 3, 3
|
|
58
76
|
\\ 1:
|
|
59
77
|
: [ret] "={r3}" (-> usize),
|
|
78
|
+
[r0_out] "={r0}" (r0_out),
|
|
79
|
+
[r4_out] "={r4}" (r4_out),
|
|
80
|
+
[r5_out] "={r5}" (r5_out),
|
|
60
81
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
61
82
|
[arg1] "{r3}" (arg1),
|
|
62
83
|
[arg2] "{r4}" (arg2),
|
|
63
84
|
[arg3] "{r5}" (arg3),
|
|
64
|
-
: .{ .memory = true, .cr0 = true, .
|
|
85
|
+
: .{ .memory = true, .cr0 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
65
86
|
}
|
|
66
87
|
|
|
67
88
|
pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
|
|
89
|
+
// These registers are both inputs and clobbers.
|
|
90
|
+
var r0_out: usize = undefined;
|
|
91
|
+
var r4_out: usize = undefined;
|
|
92
|
+
var r5_out: usize = undefined;
|
|
93
|
+
var r6_out: usize = undefined;
|
|
68
94
|
return asm volatile (
|
|
69
95
|
\\ sc
|
|
70
96
|
\\ bns+ 1f
|
|
71
97
|
\\ neg 3, 3
|
|
72
98
|
\\ 1:
|
|
73
99
|
: [ret] "={r3}" (-> usize),
|
|
100
|
+
[r0_out] "={r0}" (r0_out),
|
|
101
|
+
[r4_out] "={r4}" (r4_out),
|
|
102
|
+
[r5_out] "={r5}" (r5_out),
|
|
103
|
+
[r6_out] "={r6}" (r6_out),
|
|
74
104
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
75
105
|
[arg1] "{r3}" (arg1),
|
|
76
106
|
[arg2] "{r4}" (arg2),
|
|
77
107
|
[arg3] "{r5}" (arg3),
|
|
78
108
|
[arg4] "{r6}" (arg4),
|
|
79
|
-
: .{ .memory = true, .cr0 = true, .
|
|
109
|
+
: .{ .memory = true, .cr0 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
80
110
|
}
|
|
81
111
|
|
|
82
112
|
pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
|
|
113
|
+
// These registers are both inputs and clobbers.
|
|
114
|
+
var r0_out: usize = undefined;
|
|
115
|
+
var r4_out: usize = undefined;
|
|
116
|
+
var r5_out: usize = undefined;
|
|
117
|
+
var r6_out: usize = undefined;
|
|
118
|
+
var r7_out: usize = undefined;
|
|
83
119
|
return asm volatile (
|
|
84
120
|
\\ sc
|
|
85
121
|
\\ bns+ 1f
|
|
86
122
|
\\ neg 3, 3
|
|
87
123
|
\\ 1:
|
|
88
124
|
: [ret] "={r3}" (-> usize),
|
|
125
|
+
[r0_out] "={r0}" (r0_out),
|
|
126
|
+
[r4_out] "={r4}" (r4_out),
|
|
127
|
+
[r5_out] "={r5}" (r5_out),
|
|
128
|
+
[r6_out] "={r6}" (r6_out),
|
|
129
|
+
[r7_out] "={r7}" (r7_out),
|
|
89
130
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
90
131
|
[arg1] "{r3}" (arg1),
|
|
91
132
|
[arg2] "{r4}" (arg2),
|
|
92
133
|
[arg3] "{r5}" (arg3),
|
|
93
134
|
[arg4] "{r6}" (arg4),
|
|
94
135
|
[arg5] "{r7}" (arg5),
|
|
95
|
-
: .{ .memory = true, .cr0 = true, .
|
|
136
|
+
: .{ .memory = true, .cr0 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
96
137
|
}
|
|
97
138
|
|
|
98
139
|
pub fn syscall6(
|
|
@@ -104,12 +145,25 @@ pub fn syscall6(
|
|
|
104
145
|
arg5: usize,
|
|
105
146
|
arg6: usize,
|
|
106
147
|
) usize {
|
|
148
|
+
// These registers are both inputs and clobbers.
|
|
149
|
+
var r0_out: usize = undefined;
|
|
150
|
+
var r4_out: usize = undefined;
|
|
151
|
+
var r5_out: usize = undefined;
|
|
152
|
+
var r6_out: usize = undefined;
|
|
153
|
+
var r7_out: usize = undefined;
|
|
154
|
+
var r8_out: usize = undefined;
|
|
107
155
|
return asm volatile (
|
|
108
156
|
\\ sc
|
|
109
157
|
\\ bns+ 1f
|
|
110
158
|
\\ neg 3, 3
|
|
111
159
|
\\ 1:
|
|
112
160
|
: [ret] "={r3}" (-> usize),
|
|
161
|
+
[r0_out] "={r0}" (r0_out),
|
|
162
|
+
[r4_out] "={r4}" (r4_out),
|
|
163
|
+
[r5_out] "={r5}" (r5_out),
|
|
164
|
+
[r6_out] "={r6}" (r6_out),
|
|
165
|
+
[r7_out] "={r7}" (r7_out),
|
|
166
|
+
[r8_out] "={r8}" (r8_out),
|
|
113
167
|
: [number] "{r0}" (@intFromEnum(number)),
|
|
114
168
|
[arg1] "{r3}" (arg1),
|
|
115
169
|
[arg2] "{r4}" (arg2),
|
|
@@ -117,7 +171,7 @@ pub fn syscall6(
|
|
|
117
171
|
[arg4] "{r6}" (arg4),
|
|
118
172
|
[arg5] "{r7}" (arg5),
|
|
119
173
|
[arg6] "{r8}" (arg6),
|
|
120
|
-
: .{ .memory = true, .cr0 = true, .
|
|
174
|
+
: .{ .memory = true, .cr0 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .ctr = true, .xer = true });
|
|
121
175
|
}
|
|
122
176
|
|
|
123
177
|
pub fn clone() callconv(.naked) usize {
|
|
@@ -178,11 +232,19 @@ pub fn clone() callconv(.naked) usize {
|
|
|
178
232
|
pub const restore = restore_rt;
|
|
179
233
|
|
|
180
234
|
pub fn restore_rt() callconv(.naked) noreturn {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
235
|
+
switch (@import("builtin").zig_backend) {
|
|
236
|
+
.stage2_c => asm volatile (
|
|
237
|
+
\\ li 0, %[number]
|
|
238
|
+
\\ sc
|
|
239
|
+
:
|
|
240
|
+
: [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
|
|
241
|
+
: .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true }),
|
|
242
|
+
else => _ = asm volatile (
|
|
243
|
+
\\ sc
|
|
244
|
+
:
|
|
245
|
+
: [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
|
|
246
|
+
: .{ .memory = true, .cr0 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true }),
|
|
247
|
+
}
|
|
186
248
|
}
|
|
187
249
|
|
|
188
250
|
pub const F = struct {
|
package/std/os/linux.zig
CHANGED
|
@@ -1238,11 +1238,14 @@ pub fn access(path: [*:0]const u8, mode: u32) usize {
|
|
|
1238
1238
|
if (@hasField(SYS, "access")) {
|
|
1239
1239
|
return syscall2(.access, @intFromPtr(path), mode);
|
|
1240
1240
|
} else {
|
|
1241
|
-
return
|
|
1241
|
+
return faccessat(AT.FDCWD, path, mode, 0);
|
|
1242
1242
|
}
|
|
1243
1243
|
}
|
|
1244
1244
|
|
|
1245
1245
|
pub fn faccessat(dirfd: i32, path: [*:0]const u8, mode: u32, flags: u32) usize {
|
|
1246
|
+
if (flags == 0) {
|
|
1247
|
+
return syscall3(.faccessat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), mode);
|
|
1248
|
+
}
|
|
1246
1249
|
return syscall4(.faccessat2, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), mode, flags);
|
|
1247
1250
|
}
|
|
1248
1251
|
|
|
@@ -9799,7 +9802,9 @@ pub const wrapped = struct {
|
|
|
9799
9802
|
};
|
|
9800
9803
|
|
|
9801
9804
|
pub fn copy_file_range(fd_in: fd_t, off_in: ?*i64, fd_out: fd_t, off_out: ?*i64, len: usize, flags: u32) CopyFileRangeError!usize {
|
|
9802
|
-
const
|
|
9805
|
+
const use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
|
|
9806
|
+
const sys = if (use_c) std.c else std.os.linux;
|
|
9807
|
+
const rc = sys.copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
|
|
9803
9808
|
switch (errno(rc)) {
|
|
9804
9809
|
.SUCCESS => return @intCast(rc),
|
|
9805
9810
|
.BADF => return error.BadFileFlags,
|
package/std/os/uefi/tables.zig
CHANGED
|
@@ -90,7 +90,7 @@ pub const MemoryType = enum(u32) {
|
|
|
90
90
|
return @truncate(as_int - vendor_start);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
pub fn format(self: MemoryType, w: *std.io.Writer) std.io.
|
|
93
|
+
pub fn format(self: MemoryType, w: *std.io.Writer) std.io.Writer.Error!void {
|
|
94
94
|
if (self.toOem()) |oemval|
|
|
95
95
|
try w.print("OEM({X})", .{oemval})
|
|
96
96
|
else if (self.toVendor()) |vendorval|
|
package/std/pie.zig
CHANGED
|
@@ -177,7 +177,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
|
|
|
177
177
|
\\ jg 2f
|
|
178
178
|
\\ 1: .quad _DYNAMIC - .
|
|
179
179
|
\\ 2:
|
|
180
|
-
: [ret] "=
|
|
180
|
+
: [ret] "=a" (-> [*]const elf.Dyn),
|
|
181
181
|
),
|
|
182
182
|
// The compiler does not necessarily have any obligation to load the `l7` register (pointing
|
|
183
183
|
// to the GOT), so do it ourselves just in case.
|
package/std/posix.zig
CHANGED
|
@@ -6387,14 +6387,16 @@ pub const CopyFileRangeError = error{
|
|
|
6387
6387
|
///
|
|
6388
6388
|
/// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`.
|
|
6389
6389
|
pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
|
|
6390
|
-
if (builtin.os.tag == .freebsd or
|
|
6391
|
-
|
|
6392
|
-
|
|
6390
|
+
if (builtin.os.tag == .freebsd or builtin.os.tag == .linux) {
|
|
6391
|
+
const use_c = native_os != .linux or
|
|
6392
|
+
std.c.versionCheck(if (builtin.abi.isAndroid()) .{ .major = 34, .minor = 0, .patch = 0 } else .{ .major = 2, .minor = 27, .patch = 0 });
|
|
6393
|
+
const sys = if (use_c) std.c else linux;
|
|
6394
|
+
|
|
6393
6395
|
var off_in_copy: i64 = @bitCast(off_in);
|
|
6394
6396
|
var off_out_copy: i64 = @bitCast(off_out);
|
|
6395
6397
|
|
|
6396
6398
|
while (true) {
|
|
6397
|
-
const rc =
|
|
6399
|
+
const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
|
|
6398
6400
|
if (native_os == .freebsd) {
|
|
6399
6401
|
switch (errno(rc)) {
|
|
6400
6402
|
.SUCCESS => return @intCast(rc),
|
package/std/process/Child.zig
CHANGED
|
@@ -52,6 +52,8 @@ term: ?(SpawnError!Term),
|
|
|
52
52
|
argv: []const []const u8,
|
|
53
53
|
|
|
54
54
|
/// Leave as null to use the current env map using the supplied allocator.
|
|
55
|
+
/// Required if unable to access the current env map (e.g. building a library on
|
|
56
|
+
/// some platforms).
|
|
55
57
|
env_map: ?*const EnvMap,
|
|
56
58
|
|
|
57
59
|
stdin_behavior: StdIo,
|
|
@@ -414,6 +416,8 @@ pub fn run(args: struct {
|
|
|
414
416
|
argv: []const []const u8,
|
|
415
417
|
cwd: ?[]const u8 = null,
|
|
416
418
|
cwd_dir: ?fs.Dir = null,
|
|
419
|
+
/// Required if unable to access the current env map (e.g. building a
|
|
420
|
+
/// library on some platforms).
|
|
417
421
|
env_map: ?*const EnvMap = null,
|
|
418
422
|
max_output_bytes: usize = 50 * 1024,
|
|
419
423
|
expand_arg0: Arg0Expand = .no_expand,
|
|
@@ -614,7 +618,7 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
|
|
|
614
618
|
})).ptr;
|
|
615
619
|
} else {
|
|
616
620
|
// TODO come up with a solution for this.
|
|
617
|
-
@
|
|
621
|
+
@panic("missing std lib enhancement: ChildProcess implementation has no way to collect the environment variables to forward to the child process");
|
|
618
622
|
}
|
|
619
623
|
};
|
|
620
624
|
|
package/std/process.zig
CHANGED
|
@@ -1753,7 +1753,8 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
|
|
|
1753
1753
|
if (std.os.linux.E.init(result) != .SUCCESS) {
|
|
1754
1754
|
return error.UnknownTotalSystemMemory;
|
|
1755
1755
|
}
|
|
1756
|
-
|
|
1756
|
+
// Promote to u64 to avoid overflow on systems where info.totalram is a 32-bit usize
|
|
1757
|
+
return @as(u64, info.totalram) * info.mem_unit;
|
|
1757
1758
|
},
|
|
1758
1759
|
.freebsd => {
|
|
1759
1760
|
var physmem: c_ulong = undefined;
|
|
@@ -1762,7 +1763,20 @@ pub fn totalSystemMemory() TotalSystemMemoryError!u64 {
|
|
|
1762
1763
|
error.NameTooLong, error.UnknownName => unreachable,
|
|
1763
1764
|
else => return error.UnknownTotalSystemMemory,
|
|
1764
1765
|
};
|
|
1765
|
-
return @as(
|
|
1766
|
+
return @as(u64, @intCast(physmem));
|
|
1767
|
+
},
|
|
1768
|
+
// whole Darwin family
|
|
1769
|
+
.driverkit, .ios, .macos, .tvos, .visionos, .watchos => {
|
|
1770
|
+
// "hw.memsize" returns uint64_t
|
|
1771
|
+
var physmem: u64 = undefined;
|
|
1772
|
+
var len: usize = @sizeOf(u64);
|
|
1773
|
+
posix.sysctlbynameZ("hw.memsize", &physmem, &len, null, 0) catch |err| switch (err) {
|
|
1774
|
+
error.PermissionDenied => unreachable, // only when setting values,
|
|
1775
|
+
error.SystemResources => unreachable, // memory already on the stack
|
|
1776
|
+
error.UnknownName => unreachable, // constant, known good value
|
|
1777
|
+
else => return error.UnknownTotalSystemMemory,
|
|
1778
|
+
};
|
|
1779
|
+
return physmem;
|
|
1766
1780
|
},
|
|
1767
1781
|
.openbsd => {
|
|
1768
1782
|
const mib: [2]c_int = [_]c_int{
|
package/std/sort/pdq.zig
CHANGED
|
@@ -227,7 +227,7 @@ fn partialInsertionSort(a: usize, b: usize, context: anytype) bool {
|
|
|
227
227
|
// shift the smaller element to the left.
|
|
228
228
|
if (i - a >= 2) {
|
|
229
229
|
var j = i - 1;
|
|
230
|
-
while (j
|
|
230
|
+
while (j > a) : (j -= 1) {
|
|
231
231
|
if (!context.lessThan(j, j - 1)) break;
|
|
232
232
|
context.swap(j, j - 1);
|
|
233
233
|
}
|
|
@@ -328,3 +328,50 @@ fn reverseRange(a: usize, b: usize, context: anytype) void {
|
|
|
328
328
|
j -= 1;
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
+
|
|
332
|
+
test "pdqContext respects arbitrary range boundaries" {
|
|
333
|
+
// Regression test for issue #25250
|
|
334
|
+
// pdqsort should never access indices outside the specified [a, b) range
|
|
335
|
+
var data: [2000]i32 = @splat(0);
|
|
336
|
+
|
|
337
|
+
// Fill with data that triggers the partialInsertionSort path
|
|
338
|
+
for (0..data.len) |i| {
|
|
339
|
+
data[i] = @intCast(@mod(@as(i32, @intCast(i)) * 7, 100));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const TestContext = struct {
|
|
343
|
+
items: []i32,
|
|
344
|
+
range_start: usize,
|
|
345
|
+
range_end: usize,
|
|
346
|
+
|
|
347
|
+
pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
|
|
348
|
+
// Assert indices are within the expected range
|
|
349
|
+
testing.expect(a >= ctx.range_start and a < ctx.range_end) catch @panic("index a out of range");
|
|
350
|
+
testing.expect(b >= ctx.range_start and b < ctx.range_end) catch @panic("index b out of range");
|
|
351
|
+
return ctx.items[a] < ctx.items[b];
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
pub fn swap(ctx: @This(), a: usize, b: usize) void {
|
|
355
|
+
// Assert indices are within the expected range
|
|
356
|
+
testing.expect(a >= ctx.range_start and a < ctx.range_end) catch @panic("index a out of range");
|
|
357
|
+
testing.expect(b >= ctx.range_start and b < ctx.range_end) catch @panic("index b out of range");
|
|
358
|
+
mem.swap(i32, &ctx.items[a], &ctx.items[b]);
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// Test sorting a sub-range that doesn't start at 0
|
|
363
|
+
const start = 1118;
|
|
364
|
+
const end = 1764;
|
|
365
|
+
const ctx = TestContext{
|
|
366
|
+
.items = &data,
|
|
367
|
+
.range_start = start,
|
|
368
|
+
.range_end = end,
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
pdqContext(start, end, ctx);
|
|
372
|
+
|
|
373
|
+
// Verify the range is sorted
|
|
374
|
+
for ((start + 1)..end) |i| {
|
|
375
|
+
try testing.expect(data[i - 1] <= data[i]);
|
|
376
|
+
}
|
|
377
|
+
}
|
package/std/testing.zig
CHANGED
|
@@ -1249,3 +1249,63 @@ pub const Reader = struct {
|
|
|
1249
1249
|
return n;
|
|
1250
1250
|
}
|
|
1251
1251
|
};
|
|
1252
|
+
|
|
1253
|
+
/// A `std.Io.Reader` that gets its data from another `std.Io.Reader`, and always
|
|
1254
|
+
/// writes to its own buffer (and returns 0) during `stream` and `readVec`.
|
|
1255
|
+
pub const ReaderIndirect = struct {
|
|
1256
|
+
in: *std.Io.Reader,
|
|
1257
|
+
interface: std.Io.Reader,
|
|
1258
|
+
|
|
1259
|
+
pub fn init(in: *std.Io.Reader, buffer: []u8) ReaderIndirect {
|
|
1260
|
+
return .{
|
|
1261
|
+
.in = in,
|
|
1262
|
+
.interface = .{
|
|
1263
|
+
.vtable = &.{
|
|
1264
|
+
.stream = stream,
|
|
1265
|
+
.readVec = readVec,
|
|
1266
|
+
},
|
|
1267
|
+
.buffer = buffer,
|
|
1268
|
+
.seek = 0,
|
|
1269
|
+
.end = 0,
|
|
1270
|
+
},
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
fn readVec(r: *std.Io.Reader, _: [][]u8) std.Io.Reader.Error!usize {
|
|
1275
|
+
try streamInner(r);
|
|
1276
|
+
return 0;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
fn stream(r: *std.Io.Reader, _: *std.Io.Writer, _: std.Io.Limit) std.Io.Reader.StreamError!usize {
|
|
1280
|
+
try streamInner(r);
|
|
1281
|
+
return 0;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
fn streamInner(r: *std.Io.Reader) std.Io.Reader.Error!void {
|
|
1285
|
+
const r_indirect: *ReaderIndirect = @alignCast(@fieldParentPtr("interface", r));
|
|
1286
|
+
|
|
1287
|
+
// If there's no room remaining in the buffer at all, make room.
|
|
1288
|
+
if (r.buffer.len == r.end) {
|
|
1289
|
+
try r.rebase(r.buffer.len);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
var writer: std.Io.Writer = .{
|
|
1293
|
+
.buffer = r.buffer,
|
|
1294
|
+
.end = r.end,
|
|
1295
|
+
.vtable = &.{
|
|
1296
|
+
.drain = std.Io.Writer.unreachableDrain,
|
|
1297
|
+
.rebase = std.Io.Writer.unreachableRebase,
|
|
1298
|
+
},
|
|
1299
|
+
};
|
|
1300
|
+
defer r.end = writer.end;
|
|
1301
|
+
|
|
1302
|
+
r_indirect.in.streamExact(&writer, r.buffer.len - r.end) catch |err| switch (err) {
|
|
1303
|
+
// Only forward EndOfStream if no new bytes were written to the buffer
|
|
1304
|
+
error.EndOfStream => |e| if (r.end == writer.end) {
|
|
1305
|
+
return e;
|
|
1306
|
+
},
|
|
1307
|
+
error.WriteFailed => unreachable,
|
|
1308
|
+
else => |e| return e,
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
@@ -154,7 +154,11 @@ pub fn next(bc: *BitcodeReader) !?Item {
|
|
|
154
154
|
Abbrev.Builtin.enter_subblock.toRecordId() => {
|
|
155
155
|
const block_id: u32 = @intCast(record.operands[0]);
|
|
156
156
|
switch (block_id) {
|
|
157
|
-
Block.block_info =>
|
|
157
|
+
Block.block_info => {
|
|
158
|
+
try bc.startBlock(Block.block_info, @intCast(record.operands[1]));
|
|
159
|
+
try bc.parseBlockInfoBlock();
|
|
160
|
+
try bc.endBlock();
|
|
161
|
+
},
|
|
158
162
|
Block.first_reserved...Block.last_standard => return error.UnsupportedBlockId,
|
|
159
163
|
else => {
|
|
160
164
|
try bc.startBlock(block_id, @intCast(record.operands[1]));
|
package/std/zig/system/linux.zig
CHANGED
|
@@ -358,14 +358,11 @@ fn CpuinfoParser(comptime impl: anytype) type {
|
|
|
358
358
|
return struct {
|
|
359
359
|
fn parse(arch: Target.Cpu.Arch, reader: *std.Io.Reader) !?Target.Cpu {
|
|
360
360
|
var obj: impl = .{};
|
|
361
|
-
while (reader.
|
|
361
|
+
while (try reader.takeDelimiter('\n')) |line| {
|
|
362
362
|
const colon_pos = mem.indexOfScalar(u8, line, ':') orelse continue;
|
|
363
363
|
const key = mem.trimEnd(u8, line[0..colon_pos], " \t");
|
|
364
364
|
const value = mem.trimStart(u8, line[colon_pos + 1 ..], " \t");
|
|
365
365
|
if (!try obj.line_hook(key, value)) break;
|
|
366
|
-
} else |err| switch (err) {
|
|
367
|
-
error.EndOfStream => {},
|
|
368
|
-
else => |e| return e,
|
|
369
366
|
}
|
|
370
367
|
return obj.finalize(arch);
|
|
371
368
|
}
|
package/std/zig/system.zig
CHANGED
|
@@ -102,6 +102,7 @@ pub fn getExternalExecutor(
|
|
|
102
102
|
else => "qemu-mips64el",
|
|
103
103
|
},
|
|
104
104
|
},
|
|
105
|
+
.or1k => Executor{ .qemu = "qemu-or1k" },
|
|
105
106
|
.powerpc => Executor{ .qemu = "qemu-ppc" },
|
|
106
107
|
.powerpc64 => Executor{ .qemu = "qemu-ppc64" },
|
|
107
108
|
.powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
|
|
@@ -109,7 +110,7 @@ pub fn getExternalExecutor(
|
|
|
109
110
|
.riscv64 => Executor{ .qemu = "qemu-riscv64" },
|
|
110
111
|
.s390x => Executor{ .qemu = "qemu-s390x" },
|
|
111
112
|
.sparc => Executor{
|
|
112
|
-
.qemu = if (candidate.cpu.has(.sparc, .
|
|
113
|
+
.qemu = if (candidate.cpu.has(.sparc, .v8plus))
|
|
113
114
|
"qemu-sparc32plus"
|
|
114
115
|
else
|
|
115
116
|
"qemu-sparc",
|
|
@@ -121,7 +122,7 @@ pub fn getExternalExecutor(
|
|
|
121
122
|
else => Executor{ .qemu = "qemu-x86_64" },
|
|
122
123
|
},
|
|
123
124
|
.xtensa => Executor{ .qemu = "qemu-xtensa" },
|
|
124
|
-
else =>
|
|
125
|
+
else => bad_result,
|
|
125
126
|
};
|
|
126
127
|
}
|
|
127
128
|
|
package/std/zon/parse.zig
CHANGED
package/ubsan_rt.zig
CHANGED
|
@@ -627,7 +627,7 @@ fn exportHandler(
|
|
|
627
627
|
// Work around x86_64 backend limitation.
|
|
628
628
|
const linkage = if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) .internal else .weak;
|
|
629
629
|
const N = "__ubsan_handle_" ++ sym_name;
|
|
630
|
-
@export(handler, .{ .name = N, .linkage = linkage });
|
|
630
|
+
@export(handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
|
|
631
631
|
}
|
|
632
632
|
|
|
633
633
|
fn exportHandlerWithAbort(
|
|
@@ -639,11 +639,11 @@ fn exportHandlerWithAbort(
|
|
|
639
639
|
const linkage = if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) .internal else .weak;
|
|
640
640
|
{
|
|
641
641
|
const N = "__ubsan_handle_" ++ sym_name;
|
|
642
|
-
@export(handler, .{ .name = N, .linkage = linkage });
|
|
642
|
+
@export(handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
|
|
643
643
|
}
|
|
644
644
|
{
|
|
645
645
|
const N = "__ubsan_handle_" ++ sym_name ++ "_abort";
|
|
646
|
-
@export(abort_handler, .{ .name = N, .linkage = linkage });
|
|
646
|
+
@export(abort_handler, .{ .name = N, .linkage = linkage, .visibility = if (linkage == .internal) .default else .hidden });
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
649
|
|