@zigc/lib 0.16.0-dev.3066 → 0.16.0-dev.3091

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/c/math.zig CHANGED
@@ -59,6 +59,7 @@ comptime {
59
59
  symbol(&cosh, "cosh");
60
60
  symbol(&exp10, "exp10");
61
61
  symbol(&exp10f, "exp10f");
62
+ symbol(&fdim, "fdim");
62
63
  symbol(&hypot, "hypot");
63
64
  symbol(&modf, "modf");
64
65
  symbol(&pow, "pow");
@@ -147,6 +148,19 @@ fn exp10f(x: f32) callconv(.c) f32 {
147
148
  return math.pow(f32, 10.0, x);
148
149
  }
149
150
 
151
+ fn fdim(x: f64, y: f64) callconv(.c) f64 {
152
+ if (math.isNan(x)) {
153
+ return x;
154
+ }
155
+ if (math.isNan(y)) {
156
+ return y;
157
+ }
158
+ if (x > y) {
159
+ return x - y;
160
+ }
161
+ return 0;
162
+ }
163
+
150
164
  fn hypot(x: f64, y: f64) callconv(.c) f64 {
151
165
  return math.hypot(x, y);
152
166
  }
package/c/stropts.zig ADDED
@@ -0,0 +1,17 @@
1
+ const builtin = @import("builtin");
2
+
3
+ const std = @import("std");
4
+ const linux = std.os.linux;
5
+
6
+ const symbol = @import("../c.zig").symbol;
7
+ const errno = @import("../c.zig").errno;
8
+
9
+ comptime {
10
+ if (builtin.target.isMuslLibC()) {
11
+ symbol(&isastream, "isastream");
12
+ }
13
+ }
14
+
15
+ fn isastream(fd: c_int) callconv(.c) c_int {
16
+ return if (errno(linux.fcntl(fd, linux.F.GETFD, 0)) < 0) -1 else 0;
17
+ }
package/c.zig CHANGED
@@ -73,6 +73,7 @@ comptime {
73
73
  _ = @import("c/stdlib.zig");
74
74
  _ = @import("c/string.zig");
75
75
  _ = @import("c/strings.zig");
76
+ _ = @import("c/stropts.zig");
76
77
 
77
78
  _ = @import("c/sys/capability.zig");
78
79
  _ = @import("c/sys/file.zig");
@@ -0,0 +1,266 @@
1
+ const std = @import("std");
2
+ const testing = std.testing;
3
+ const assert = std.debug.assert;
4
+ const maxInt = std.math.maxInt;
5
+ const minInt = std.math.minInt;
6
+ const divCeil = std.math.divCeil;
7
+
8
+ const builtin = @import("builtin");
9
+ const compiler_rt = @import("../compiler_rt.zig");
10
+
11
+ const endian = builtin.cpu.arch.endian();
12
+
13
+ inline fn limbGet(limbs: []const u64, i: usize) u64 {
14
+ return switch (endian) {
15
+ .little => limbs[i],
16
+ .big => limbs[limbs.len - 1 - i],
17
+ };
18
+ }
19
+
20
+ inline fn limbSet(limbs: []u64, i: usize, value: u64) void {
21
+ switch (endian) {
22
+ .little => limbs[i] = value,
23
+ .big => limbs[limbs.len - 1 - i] = value,
24
+ }
25
+ }
26
+
27
+ fn limbCount(bits: u16) u16 {
28
+ return divCeil(u16, bits, 64) catch unreachable;
29
+ }
30
+
31
+ fn Limbs(T: type) type {
32
+ const int_info = @typeInfo(T).int;
33
+ const limb_cnt = comptime limbCount(int_info.bits);
34
+ return [limb_cnt]u64;
35
+ }
36
+
37
+ fn asLimbs(v: anytype) Limbs(@TypeOf(v)) {
38
+ const T = @TypeOf(v);
39
+ const int_info = @typeInfo(T).int;
40
+ const limb_cnt = comptime limbCount(int_info.bits);
41
+ const ET = @Int(int_info.signedness, limb_cnt * 64);
42
+ return @bitCast(@as(ET, v));
43
+ }
44
+
45
+ fn limbWrap(limb: u64, is_signed: bool, bits: u16) u64 {
46
+ assert(bits % 64 != 0);
47
+ const pad_bits: u6 = @intCast(64 - bits % 64);
48
+ if (!is_signed) {
49
+ const s = limb << pad_bits;
50
+ return s >> pad_bits;
51
+ } else {
52
+ const s = @as(i64, @bitCast(limb)) << pad_bits;
53
+ return @bitCast(s >> pad_bits);
54
+ }
55
+ }
56
+
57
+ comptime {
58
+ @export(&__addo_limb64, .{ .name = "__addo_limb64", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
59
+ }
60
+
61
+ fn __addo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, b_ptr: [*]const u64, is_signed: bool, bits: u16) callconv(.c) bool {
62
+ const limb_cnt = limbCount(bits);
63
+ const out = out_ptr[0..limb_cnt];
64
+ const a = a_ptr[0..limb_cnt];
65
+ const b = b_ptr[0..limb_cnt];
66
+
67
+ var carry: u1 = 0;
68
+ var i: usize = 0;
69
+ while (i < limb_cnt - 1) : (i += 1) {
70
+ const s1 = @addWithOverflow(limbGet(a, i), limbGet(b, i));
71
+ const s2 = @addWithOverflow(s1[0], carry);
72
+ carry = s1[1] | s2[1];
73
+ limbSet(out, i, s2[0]);
74
+ }
75
+
76
+ const limb: u64 = b: {
77
+ if (!is_signed) {
78
+ const s1 = @addWithOverflow(limbGet(a, i), limbGet(b, i));
79
+ const s2 = @addWithOverflow(s1[0], carry);
80
+ carry = s1[1] | s2[1];
81
+ break :b s2[0];
82
+ } else {
83
+ const as: i64 = @bitCast(limbGet(a, i));
84
+ const bs: i64 = @bitCast(limbGet(b, i));
85
+ const s1 = @addWithOverflow(as, bs);
86
+ const s2 = @addWithOverflow(s1[0], carry);
87
+ carry = s1[1] | s2[1];
88
+ break :b @bitCast(s2[0]);
89
+ }
90
+ };
91
+
92
+ if (bits % 64 == 0) {
93
+ limbSet(out, i, limb);
94
+ return carry != 0;
95
+ } else {
96
+ assert(carry == 0);
97
+ const wrapped_limb = limbWrap(limb, is_signed, bits);
98
+ limbSet(out, i, wrapped_limb);
99
+ return wrapped_limb != limb;
100
+ }
101
+ }
102
+
103
+ fn test__addo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool }) !void {
104
+ const int_info = @typeInfo(T).int;
105
+ const is_signed = int_info.signedness == .signed;
106
+
107
+ var a_limbs = asLimbs(a);
108
+ var b_limbs = asLimbs(b);
109
+ var out: Limbs(T) = undefined;
110
+ const overflow = __addo_limb64(&out, &a_limbs, &b_limbs, is_signed, int_info.bits);
111
+
112
+ const expected_limbs = asLimbs(expected[0]);
113
+ try testing.expectEqual(expected_limbs, out);
114
+ try testing.expectEqual(expected[1], overflow);
115
+ }
116
+
117
+ test __addo_limb64 {
118
+ try test__addo_limb64(u64, 1, 2, .{ 3, false });
119
+ try test__addo_limb64(u64, maxInt(u64), 2, .{ 1, true });
120
+ try test__addo_limb64(u65, maxInt(u65), 2, .{ 1, true });
121
+ try test__addo_limb64(u255, 1, 2, .{ 3, false });
122
+
123
+ try test__addo_limb64(i64, 1, 2, .{ 3, false });
124
+ try test__addo_limb64(i64, maxInt(i64), 1, .{ minInt(i64), true });
125
+ try test__addo_limb64(i65, maxInt(i65), 1, .{ minInt(i65), true });
126
+ try test__addo_limb64(i255, -3, 2, .{ -1, false });
127
+ }
128
+
129
+ comptime {
130
+ @export(&__subo_limb64, .{ .name = "__subo_limb64", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
131
+ }
132
+
133
+ fn __subo_limb64(out_ptr: [*]u64, a_ptr: [*]const u64, b_ptr: [*]const u64, is_signed: bool, bits: u16) callconv(.c) bool {
134
+ const limb_cnt = limbCount(bits);
135
+ const out = out_ptr[0..limb_cnt];
136
+ const a = a_ptr[0..limb_cnt];
137
+ const b = b_ptr[0..limb_cnt];
138
+
139
+ var borrow: u1 = 0;
140
+ var i: usize = 0;
141
+ while (i < limb_cnt - 1) : (i += 1) {
142
+ const s1 = @subWithOverflow(limbGet(a, i), limbGet(b, i));
143
+ const s2 = @subWithOverflow(s1[0], borrow);
144
+ borrow = s1[1] | s2[1];
145
+ limbSet(out, i, s2[0]);
146
+ }
147
+
148
+ const limb: u64 = b: {
149
+ if (!is_signed) {
150
+ const s1 = @subWithOverflow(limbGet(a, i), limbGet(b, i));
151
+ const s2 = @subWithOverflow(s1[0], borrow);
152
+ borrow = s1[1] | s2[1];
153
+ break :b s2[0];
154
+ } else {
155
+ const as: i64 = @bitCast(limbGet(a, i));
156
+ const bs: i64 = @bitCast(limbGet(b, i));
157
+ const s1 = @subWithOverflow(as, bs);
158
+ const s2 = @subWithOverflow(s1[0], borrow);
159
+ borrow = s1[1] | s2[1];
160
+ break :b @bitCast(s2[0]);
161
+ }
162
+ };
163
+
164
+ if (bits % 64 == 0) {
165
+ limbSet(out, i, limb);
166
+ return borrow != 0;
167
+ } else {
168
+ const wrapped_limb = limbWrap(limb, is_signed, bits);
169
+ limbSet(out, i, wrapped_limb);
170
+ return borrow != 0 or wrapped_limb != limb;
171
+ }
172
+ }
173
+
174
+ fn test__subo_limb64(comptime T: type, a: T, b: T, expected: struct { T, bool }) !void {
175
+ const int_info = @typeInfo(T).int;
176
+ const is_signed = int_info.signedness == .signed;
177
+
178
+ var a_limbs = asLimbs(a);
179
+ var b_limbs = asLimbs(b);
180
+ var out: Limbs(T) = undefined;
181
+ const overflow = __subo_limb64(&out, &a_limbs, &b_limbs, is_signed, int_info.bits);
182
+
183
+ const expected_limbs = asLimbs(expected[0]);
184
+ try testing.expectEqual(expected_limbs, out);
185
+ try testing.expectEqual(expected[1], overflow);
186
+ }
187
+
188
+ test __subo_limb64 {
189
+ try test__subo_limb64(u64, 3, 2, .{ 1, false });
190
+ try test__subo_limb64(u64, 0, 1, .{ maxInt(u64), true });
191
+ try test__subo_limb64(u65, 0, 1, .{ maxInt(u65), true });
192
+ try test__subo_limb64(u255, 3, 2, .{ 1, false });
193
+
194
+ try test__subo_limb64(i64, 1, 2, .{ -1, false });
195
+ try test__subo_limb64(i64, minInt(i64), 1, .{ maxInt(i64), true });
196
+ try test__subo_limb64(i65, minInt(i65), 1, .{ maxInt(i65), true });
197
+ try test__subo_limb64(i255, -1, 2, .{ -3, false });
198
+ }
199
+
200
+ comptime {
201
+ @export(&__cmp_limb64, .{ .name = "__cmp_limb64", .linkage = compiler_rt.linkage, .visibility = compiler_rt.visibility });
202
+ }
203
+
204
+ // a < b -> -1
205
+ // a == b -> 0
206
+ // a > b -> 1
207
+ fn __cmp_limb64(a_ptr: [*]const u64, b_ptr: [*]const u64, is_signed: bool, bits: u16) callconv(.c) i8 {
208
+ const limb_cnt = limbCount(bits);
209
+ const a = a_ptr[0..limb_cnt];
210
+ const b = b_ptr[0..limb_cnt];
211
+
212
+ var i: usize = 0;
213
+ if (is_signed) {
214
+ const sa: i64 = @bitCast(limbGet(a, limb_cnt - 1));
215
+ const sb: i64 = @bitCast(limbGet(b, limb_cnt - 1));
216
+ if (sa < sb) return -1;
217
+ if (sa > sb) return 1;
218
+ i += 1;
219
+ }
220
+
221
+ while (i < limb_cnt) : (i += 1) {
222
+ const ai = limbGet(a, limb_cnt - 1 - i);
223
+ const bi = limbGet(b, limb_cnt - 1 - i);
224
+ if (ai < bi) return -1;
225
+ if (ai > bi) return 1;
226
+ }
227
+
228
+ return 0;
229
+ }
230
+
231
+ fn test__cmp_limb64(comptime T: type, a: T, b: T, expected: i8) !void {
232
+ const int_info = @typeInfo(T).int;
233
+ const is_signed = int_info.signedness == .signed;
234
+
235
+ var a_limbs = asLimbs(a);
236
+ var b_limbs = asLimbs(b);
237
+ const actual = __cmp_limb64(&a_limbs, &b_limbs, is_signed, int_info.bits);
238
+
239
+ try testing.expectEqual(expected, actual);
240
+ }
241
+
242
+ test __cmp_limb64 {
243
+ try test__cmp_limb64(u64, 1, 2, -1);
244
+ try test__cmp_limb64(u64, 2, 2, 0);
245
+ try test__cmp_limb64(u64, 3, 2, 1);
246
+
247
+ try test__cmp_limb64(u65, 1, 2, -1);
248
+ try test__cmp_limb64(u65, maxInt(u65), maxInt(u65), 0);
249
+ try test__cmp_limb64(u65, maxInt(u65), maxInt(u65) - 1, 1);
250
+
251
+ try test__cmp_limb64(u255, 1, 2, -1);
252
+ try test__cmp_limb64(u255, 7, 7, 0);
253
+ try test__cmp_limb64(u255, maxInt(u255), maxInt(u255) - 1, 1);
254
+
255
+ try test__cmp_limb64(i64, -1, 0, -1);
256
+ try test__cmp_limb64(i64, 0, 0, 0);
257
+ try test__cmp_limb64(i64, 1, 0, 1);
258
+
259
+ try test__cmp_limb64(i65, minInt(i65), maxInt(i65), -1);
260
+ try test__cmp_limb64(i65, -1, -1, 0);
261
+ try test__cmp_limb64(i65, maxInt(i65), minInt(i65), 1);
262
+
263
+ try test__cmp_limb64(i255, -3, 2, -1);
264
+ try test__cmp_limb64(i255, -5, -5, 0);
265
+ try test__cmp_limb64(i255, 2, -3, 1);
266
+ }
package/compiler_rt.zig CHANGED
@@ -279,6 +279,8 @@ comptime {
279
279
  _ = @import("compiler_rt/divmodei4.zig");
280
280
  _ = @import("compiler_rt/udivmodei4.zig");
281
281
 
282
+ _ = @import("compiler_rt/limb64.zig");
283
+
282
284
  // extra
283
285
  _ = @import("compiler_rt/os_version_check.zig");
284
286
  _ = @import("compiler_rt/emutls.zig");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zigc/lib",
3
- "version": "0.16.0-dev.3066",
3
+ "version": "0.16.0-dev.3091",
4
4
  "description": "Zig standard library and libc headers (shared across all platforms)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -596,7 +596,7 @@ pub fn appendZigProcessFlags(
596
596
  "-target", try target.query.zigTriple(b.allocator),
597
597
  "-mcpu", try target.query.serializeCpuAlloc(b.allocator),
598
598
  });
599
- if (target.query.dynamic_linker) |dynamic_linker| {
599
+ if (target.query.dynamic_linker) |*dynamic_linker| {
600
600
  if (dynamic_linker.get()) |dynamic_linker_path| {
601
601
  try zig_args.append("--dynamic-linker");
602
602
  try zig_args.append(dynamic_linker_path);
@@ -6,7 +6,7 @@ root_prog_node: std.Progress.Node,
6
6
  watch: bool,
7
7
 
8
8
  tcp_server: ?net.Server,
9
- serve_thread: ?std.Thread,
9
+ serve_task: ?Io.Future(Io.Cancelable!void),
10
10
 
11
11
  /// Uses `Io.Clock.awake`.
12
12
  base_timestamp: Io.Timestamp,
@@ -103,7 +103,7 @@ pub fn init(opts: Options) WebServer {
103
103
  .watch = opts.watch,
104
104
 
105
105
  .tcp_server = null,
106
- .serve_thread = null,
106
+ .serve_task = null,
107
107
 
108
108
  .base_timestamp = opts.base_timestamp.raw,
109
109
  .step_names_trailing = step_names_trailing,
@@ -136,9 +136,9 @@ pub fn deinit(ws: *WebServer) void {
136
136
  gpa.free(ws.time_report_msgs);
137
137
  gpa.free(ws.time_report_update_times);
138
138
 
139
- if (ws.serve_thread) |t| {
139
+ if (ws.serve_task) |t| {
140
140
  if (ws.tcp_server) |*s| s.stream.close(io);
141
- t.join();
141
+ t.await();
142
142
  }
143
143
  if (ws.tcp_server) |*s| s.deinit();
144
144
 
@@ -146,15 +146,15 @@ pub fn deinit(ws: *WebServer) void {
146
146
  }
147
147
  pub fn start(ws: *WebServer) error{AlreadyReported}!void {
148
148
  assert(ws.tcp_server == null);
149
- assert(ws.serve_thread == null);
149
+ assert(ws.serve_task == null);
150
150
  const io = ws.graph.io;
151
151
 
152
152
  ws.tcp_server = ws.listen_address.listen(io, .{ .reuse_address = true }) catch |err| {
153
- log.err("failed to listen to port {d}: {s}", .{ ws.listen_address.getPort(), @errorName(err) });
153
+ log.err("failed to listen to port {d}: {t}", .{ ws.listen_address.getPort(), err });
154
154
  return error.AlreadyReported;
155
155
  };
156
- ws.serve_thread = std.Thread.spawn(.{}, serve, .{ws}) catch |err| {
157
- log.err("unable to spawn web server thread: {s}", .{@errorName(err)});
156
+ ws.serve_task = io.concurrent(serve, .{ws}) catch |err| {
157
+ log.err("unable to spawn web server thread: {t}", .{err});
158
158
  ws.tcp_server.?.deinit(io);
159
159
  ws.tcp_server = null;
160
160
  return error.AlreadyReported;
@@ -165,15 +165,20 @@ pub fn start(ws: *WebServer) error{AlreadyReported}!void {
165
165
  log.info("hint: pass '--webui={f}' to use the same port next time", .{ws.tcp_server.?.socket.address});
166
166
  }
167
167
  }
168
- fn serve(ws: *WebServer) void {
168
+ fn serve(ws: *WebServer) Io.Cancelable!void {
169
169
  const io = ws.graph.io;
170
+ var group: Io.Group = .init;
171
+ defer group.cancel(io);
170
172
  while (true) {
171
- var stream = ws.tcp_server.?.accept(io) catch |err| {
172
- log.err("failed to accept connection: {s}", .{@errorName(err)});
173
- return;
173
+ var stream = ws.tcp_server.?.accept(io) catch |err| switch (err) {
174
+ error.Canceled => |e| return e,
175
+ else => |e| {
176
+ log.err("failed to accept connection: {t}", .{e});
177
+ return;
178
+ },
174
179
  };
175
- _ = std.Thread.spawn(.{}, accept, .{ ws, stream }) catch |err| {
176
- log.err("unable to spawn connection thread: {s}", .{@errorName(err)});
180
+ group.concurrent(io, accept, .{ ws, stream }) catch |err| {
181
+ log.err("unable to spawn connection thread: {t}", .{err});
177
182
  stream.close(io);
178
183
  continue;
179
184
  };
@@ -303,8 +308,8 @@ fn serveWebSocket(ws: *WebServer, sock: *http.Server.WebSocket) !noreturn {
303
308
  copy.* = @atomicLoad(u8, shared, .monotonic);
304
309
  }
305
310
 
306
- const recv_thread = try std.Thread.spawn(.{}, recvWebSocketMessages, .{ ws, sock });
307
- defer recv_thread.join();
311
+ var recv_thread = try io.concurrent(recvWebSocketMessages, .{ ws, sock });
312
+ defer recv_thread.cancel(io);
308
313
 
309
314
  {
310
315
  const hello_header: abi.Hello = .{
package/std/Build/abi.zig CHANGED
@@ -235,7 +235,8 @@ pub const fuzz = struct {
235
235
  max: u64,
236
236
  weight: u64,
237
237
 
238
- fn intFromValue(x: anytype) u64 {
238
+ /// `inline` to propogate comptimeness
239
+ inline fn intFromValue(x: anytype) u64 {
239
240
  const T = @TypeOf(x);
240
241
  return switch (@typeInfo(T)) {
241
242
  .comptime_int => x,
@@ -269,11 +270,13 @@ pub const fuzz = struct {
269
270
  };
270
271
  }
271
272
 
272
- pub fn value(T: type, x: T, weight: u64) Weight {
273
+ /// `inline` to propogate comptimeness
274
+ pub inline fn value(T: type, x: T, weight: u64) Weight {
273
275
  return .{ .min = intFromValue(x), .max = intFromValue(x), .weight = weight };
274
276
  }
275
277
 
276
- pub fn rangeAtMost(T: type, at_least: T, at_most: T, weight: u64) Weight {
278
+ /// `inline` to propogate comptimeness
279
+ pub inline fn rangeAtMost(T: type, at_least: T, at_most: T, weight: u64) Weight {
277
280
  std.debug.assert(intFromValue(at_least) <= intFromValue(at_most));
278
281
  return .{
279
282
  .min = intFromValue(at_least),
@@ -282,7 +285,8 @@ pub const fuzz = struct {
282
285
  };
283
286
  }
284
287
 
285
- pub fn rangeLessThan(T: type, at_least: T, less_than: T, weight: u64) Weight {
288
+ /// `inline` to propogate comptimeness
289
+ pub inline fn rangeLessThan(T: type, at_least: T, less_than: T, weight: u64) Weight {
286
290
  std.debug.assert(intFromValue(at_least) < intFromValue(less_than));
287
291
  return .{
288
292
  .min = intFromValue(at_least),
@@ -2512,6 +2512,7 @@ fn dirCreateFile(
2512
2512
  .OPNOTSUPP => return error.FileLocksUnsupported,
2513
2513
  .AGAIN => return error.WouldBlock,
2514
2514
  .TXTBSY => return error.FileBusy,
2515
+ .ROFS => return error.ReadOnlyFileSystem,
2515
2516
  .NXIO => return error.NoDevice,
2516
2517
  .ILSEQ => return error.BadPathName,
2517
2518
  else => |err| return unexpectedErrno(err),
@@ -2647,6 +2648,7 @@ fn dirOpenFile(
2647
2648
  .AGAIN => return error.WouldBlock,
2648
2649
  .TXTBSY => return error.FileBusy,
2649
2650
  .NXIO => return error.NoDevice,
2651
+ .ROFS => return error.ReadOnlyFileSystem,
2650
2652
  .ILSEQ => return error.BadPathName,
2651
2653
  else => |err| return unexpectedErrno(err),
2652
2654
  }
package/std/Io/File.zig CHANGED
@@ -202,6 +202,7 @@ pub const OpenError = error{
202
202
  NotDir,
203
203
  /// The path already exists and the `CREAT` and `EXCL` flags were provided.
204
204
  PathAlreadyExists,
205
+ ReadOnlyFileSystem,
205
206
  DeviceBusy,
206
207
  FileLocksUnsupported,
207
208
  /// One of these three things:
@@ -4290,6 +4290,7 @@ fn dirCreateFilePosix(
4290
4290
  .AGAIN => return error.WouldBlock,
4291
4291
  .TXTBSY => return error.FileBusy,
4292
4292
  .NXIO => return error.NoDevice,
4293
+ .ROFS => return error.ReadOnlyFileSystem,
4293
4294
  .ILSEQ => return error.BadPathName,
4294
4295
  else => |err| return posix.unexpectedErrno(err),
4295
4296
  }
@@ -4871,6 +4872,7 @@ fn dirOpenFilePosix(
4871
4872
  .AGAIN => return error.WouldBlock,
4872
4873
  .TXTBSY => return error.FileBusy,
4873
4874
  .NXIO => return error.NoDevice,
4875
+ .ROFS => return error.ReadOnlyFileSystem,
4874
4876
  .ILSEQ => return error.BadPathName,
4875
4877
  else => |err| return posix.unexpectedErrno(err),
4876
4878
  }
package/std/Io/Uring.zig CHANGED
@@ -5673,6 +5673,7 @@ fn openat(
5673
5673
  .AGAIN => return error.WouldBlock,
5674
5674
  .TXTBSY => return error.FileBusy,
5675
5675
  .NXIO => return error.NoDevice,
5676
+ .ROFS => return error.ReadOnlyFileSystem,
5676
5677
  .ILSEQ => return error.BadPathName,
5677
5678
  else => |err| return unexpectedErrno(err),
5678
5679
  }
@@ -857,16 +857,8 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {
857
857
  len: usize,
858
858
  new_items: []const T,
859
859
  ) Allocator.Error!void {
860
- const after_range = start + len;
861
- const range = self.items[start..after_range];
862
- if (range.len < new_items.len) {
863
- const first = new_items[0..range.len];
864
- const rest = new_items[range.len..];
865
- @memcpy(range[0..first.len], first);
866
- try self.insertSlice(gpa, after_range, rest);
867
- } else {
868
- self.replaceRangeAssumeCapacity(start, len, new_items);
869
- }
860
+ try self.ensureTotalCapacity(gpa, try addOrOom(self.items.len - len, new_items.len));
861
+ self.replaceRangeAssumeCapacity(start, len, new_items);
870
862
  }
871
863
 
872
864
  /// Grows or shrinks the list as necessary.
@@ -874,26 +866,20 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {
874
866
  /// Never invalidates element pointers.
875
867
  ///
876
868
  /// Asserts the capacity is enough for additional items.
877
- pub fn replaceRangeAssumeCapacity(self: *Self, start: usize, len: usize, new_items: []const T) void {
878
- const after_range = start + len;
879
- const range = self.items[start..after_range];
880
-
881
- if (range.len == new_items.len)
882
- @memcpy(range[0..new_items.len], new_items)
883
- else if (range.len < new_items.len) {
884
- const first = new_items[0..range.len];
885
- const rest = new_items[range.len..];
886
- @memcpy(range[0..first.len], first);
887
- const dst = self.addManyAtAssumeCapacity(after_range, rest.len);
888
- @memcpy(dst, rest);
889
- } else {
890
- const extra = range.len - new_items.len;
891
- @memcpy(range[0..new_items.len], new_items);
892
- const src = self.items[after_range..];
893
- @memmove(self.items[after_range - extra ..][0..src.len], src);
894
- @memset(self.items[self.items.len - extra ..], undefined);
895
- self.items.len -= extra;
896
- }
869
+ pub fn replaceRangeAssumeCapacity(
870
+ self: *Self,
871
+ start: usize,
872
+ len: usize,
873
+ new_items: []const T,
874
+ ) void {
875
+ std.debug.assert(self.capacity - self.items.len >= new_items.len -| len);
876
+
877
+ const tail = self.items[start + len ..];
878
+ const vacated = self.items[self.items.len - (len -| new_items.len) ..];
879
+ self.items.len = self.items.len - len + new_items.len;
880
+ @memmove(self.items[start + new_items.len ..], tail);
881
+ @memcpy(self.items[start..][0..new_items.len], new_items);
882
+ @memset(vacated, undefined);
897
883
  }
898
884
 
899
885
  /// Grows or shrinks the list as necessary.
@@ -902,7 +888,12 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {
902
888
  ///
903
889
  /// If the unused capacity is insufficient for additional items,
904
890
  /// returns `error.OutOfMemory`.
905
- pub fn replaceRangeBounded(self: *Self, start: usize, len: usize, new_items: []const T) error{OutOfMemory}!void {
891
+ pub fn replaceRangeBounded(
892
+ self: *Self,
893
+ start: usize,
894
+ len: usize,
895
+ new_items: []const T,
896
+ ) error{OutOfMemory}!void {
906
897
  if (self.capacity - self.items.len < new_items.len -| len) return error.OutOfMemory;
907
898
  return replaceRangeAssumeCapacity(self, start, len, new_items);
908
899
  }
@@ -360,6 +360,7 @@ const Module = struct {
360
360
  error.SystemFdQuotaExceeded,
361
361
  error.FileLocksUnsupported,
362
362
  error.FileBusy,
363
+ error.ReadOnlyFileSystem,
363
364
  => return error.ReadFailed,
364
365
  };
365
366
  errdefer coff_file.close(io);
@@ -205,6 +205,24 @@ pub noinline fn valueRangeLessThan(s: *Smith, T: type, at_least: T, less_than: T
205
205
  return s.valueRangeLessThanWithHash(T, at_least, less_than, firstHash());
206
206
  }
207
207
 
208
+ /// It is asserted `len` is nonzero.
209
+ /// It is asserted `len` fits within 64 bits.
210
+ //
211
+ // `noinline` to capture a unique return address
212
+ pub noinline fn index(s: *Smith, len: usize) usize {
213
+ @disableInstrumentation();
214
+ return s.indexWithHash(len, firstHash());
215
+ }
216
+
217
+ /// It is asserted that the weight of `false` is non-zero.
218
+ /// It is asserted that the weight of `true` is non-zero.
219
+ //
220
+ // `noinline` to capture a unique return address
221
+ pub noinline fn boolWeighted(s: *Smith, false_weight: u64, true_weight: u64) bool {
222
+ @disableInstrumentation();
223
+ return s.boolWeightedWithHash(false_weight, true_weight, firstHash());
224
+ }
225
+
208
226
  /// This is similar to `value(bool)` however it is gauraunteed to eventually
209
227
  /// return `true` and provides the fuzzer with an extra hint about the data.
210
228
  //
@@ -228,6 +246,7 @@ pub noinline fn eosWeighted(s: *Smith, weights: []const Weight) bool {
228
246
  /// This is similar to `value(bool)` however it is gauraunteed to eventually
229
247
  /// return `true` and provides the fuzzer with an extra hint about the data.
230
248
  ///
249
+ /// It is asserted that the weight of `false` is non-zero.
231
250
  /// It is asserted that the weight of `true` is non-zero.
232
251
  //
233
252
  // `noinline` to capture a unique return address
@@ -463,6 +482,24 @@ pub fn valueRangeLessThanWithHash(s: *Smith, T: type, at_least: T, less_than: T,
463
482
  return s.valueWeightedWithHash(T, &.{.rangeLessThan(T, at_least, less_than, 1)}, hash);
464
483
  }
465
484
 
485
+ /// It is asserted `len` is nonzero.
486
+ /// It is asserted `len` fits within 64 bits.
487
+ pub fn indexWithHash(s: *Smith, len: usize, hash: u32) usize {
488
+ @disableInstrumentation();
489
+ assert(len != 0);
490
+ return @intCast(s.valueWeightedWithHash(u64, &.{.rangeLessThan(u64, 0, @intCast(len), 1)}, hash));
491
+ }
492
+
493
+ /// It is asserted that the weight of `false` is non-zero.
494
+ /// It is asserted that the weight of `true` is non-zero.
495
+ pub fn boolWeightedWithHash(s: *Smith, false_weight: u64, true_weight: u64, hash: u32) bool {
496
+ @disableInstrumentation();
497
+ return s.valueWeightedWithHash(bool, &.{
498
+ .value(bool, false, false_weight),
499
+ .value(bool, true, true_weight),
500
+ }, hash);
501
+ }
502
+
466
503
  /// This is similar to `value(bool)` however it is gauraunteed to eventually
467
504
  /// return `true` and provides the fuzzer with an extra hint about the data.
468
505
  pub fn eosWithHash(s: *Smith, hash: u32) bool {
@@ -504,8 +541,6 @@ pub fn eosWeightedWithHash(s: *Smith, weights: []const Weight, hash: u32) bool {
504
541
  ///
505
542
  /// It is asserted that the weight of `false` is non-zero.
506
543
  /// It is asserted that the weight of `true` is non-zero.
507
- //
508
- // `noinline` to capture a unique return address
509
544
  pub fn eosWeightedSimpleWithHash(s: *Smith, false_weight: u64, true_weight: u64, hash: u32) bool {
510
545
  @disableInstrumentation();
511
546
  return s.eosWeightedWithHash(&.{