authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-06 16:12:31-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-06 16:12:31-04:00
log367e2b2fe43a2de09767ad8d5657866088b44678
tree686b57ecfcfd472d70493c46c60a562b96d5ad31
parent41bf81dc3231eb763c93eb95b152e7ab8d3c5af8
parent14685e59b26c8dc002ce6c25c6916cbad54e79d0
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11800 from Vexu/stage2

`zig2 build test-std` progress

14 files changed, 339 insertions(+), 140 deletions(-)

lib/std/crypto/scrypt.zig+10-10
...@@ -73,11 +73,11 @@ fn salsaXor(tmp: *align(16) [16]u32, in: []align(16) const u32, out: []align(16)...@@ -73,11 +73,11 @@ fn salsaXor(tmp: *align(16) [16]u32, in: []align(16) const u32, out: []align(16)
73}73}
7474
75fn blockMix(tmp: *align(16) [16]u32, in: []align(16) const u32, out: []align(16) u32, r: u30) void {75fn blockMix(tmp: *align(16) [16]u32, in: []align(16) const u32, out: []align(16) u32, r: u30) void {
76 blockCopy(tmp, in[(2 * r - 1) * 16 ..], 1);76 blockCopy(tmp, @alignCast(16, in[(2 * r - 1) * 16 ..]), 1);
77 var i: usize = 0;77 var i: usize = 0;
78 while (i < 2 * r) : (i += 2) {78 while (i < 2 * r) : (i += 2) {
79 salsaXor(tmp, in[i * 16 ..], out[i * 8 ..]);79 salsaXor(tmp, @alignCast(16, in[i * 16 ..]), @alignCast(16, out[i * 8 ..]));
80 salsaXor(tmp, in[i * 16 + 16 ..], out[i * 8 + r * 16 ..]);80 salsaXor(tmp, @alignCast(16, in[i * 16 + 16 ..]), @alignCast(16, out[i * 8 + r * 16 ..]));
81 }81 }
82}82}
8383
...@@ -87,8 +87,8 @@ fn integerify(b: []align(16) const u32, r: u30) u64 {...@@ -87,8 +87,8 @@ fn integerify(b: []align(16) const u32, r: u30) u64 {
87}87}
8888
89fn smix(b: []align(16) u8, r: u30, n: usize, v: []align(16) u32, xy: []align(16) u32) void {89fn smix(b: []align(16) u8, r: u30, n: usize, v: []align(16) u32, xy: []align(16) u32) void {
90 var x = xy[0 .. 32 * r];90 var x = @alignCast(16, xy[0 .. 32 * r]);
91 var y = xy[32 * r ..];91 var y = @alignCast(16, xy[32 * r ..]);
9292
93 for (x) |*v1, j| {93 for (x) |*v1, j| {
94 v1.* = mem.readIntSliceLittle(u32, b[4 * j ..]);94 v1.* = mem.readIntSliceLittle(u32, b[4 * j ..]);
...@@ -97,21 +97,21 @@ fn smix(b: []align(16) u8, r: u30, n: usize, v: []align(16) u32, xy: []align(16)...@@ -97,21 +97,21 @@ fn smix(b: []align(16) u8, r: u30, n: usize, v: []align(16) u32, xy: []align(16)
97 var tmp: [16]u32 align(16) = undefined;97 var tmp: [16]u32 align(16) = undefined;
98 var i: usize = 0;98 var i: usize = 0;
99 while (i < n) : (i += 2) {99 while (i < n) : (i += 2) {
100 blockCopy(v[i * (32 * r) ..], x, 2 * r);100 blockCopy(@alignCast(16, v[i * (32 * r) ..]), x, 2 * r);
101 blockMix(&tmp, x, y, r);101 blockMix(&tmp, x, y, r);
102102
103 blockCopy(v[(i + 1) * (32 * r) ..], y, 2 * r);103 blockCopy(@alignCast(16, v[(i + 1) * (32 * r) ..]), y, 2 * r);
104 blockMix(&tmp, y, x, r);104 blockMix(&tmp, y, x, r);
105 }105 }
106106
107 i = 0;107 i = 0;
108 while (i < n) : (i += 2) {108 while (i < n) : (i += 2) {
109 var j = @intCast(usize, integerify(x, r) & (n - 1));109 var j = @intCast(usize, integerify(x, r) & (n - 1));
110 blockXor(x, v[j * (32 * r) ..], 2 * r);110 blockXor(x, @alignCast(16, v[j * (32 * r) ..]), 2 * r);
111 blockMix(&tmp, x, y, r);111 blockMix(&tmp, x, y, r);
112112
113 j = @intCast(usize, integerify(y, r) & (n - 1));113 j = @intCast(usize, integerify(y, r) & (n - 1));
114 blockXor(y, v[j * (32 * r) ..], 2 * r);114 blockXor(y, @alignCast(16, v[j * (32 * r) ..]), 2 * r);
115 blockMix(&tmp, y, x, r);115 blockMix(&tmp, y, x, r);
116 }116 }
117117
...@@ -201,7 +201,7 @@ pub fn kdf(...@@ -201,7 +201,7 @@ pub fn kdf(
201 try pwhash.pbkdf2(dk, password, salt, 1, HmacSha256);201 try pwhash.pbkdf2(dk, password, salt, 1, HmacSha256);
202 var i: u32 = 0;202 var i: u32 = 0;
203 while (i < params.p) : (i += 1) {203 while (i < params.p) : (i += 1) {
204 smix(dk[i * 128 * params.r ..], params.r, n, v, xy);204 smix(@alignCast(16, dk[i * 128 * params.r ..]), params.r, n, v, xy);
205 }205 }
206 try pwhash.pbkdf2(derived_key, password, dk, 1, HmacSha256);206 try pwhash.pbkdf2(derived_key, password, dk, 1, HmacSha256);
207}207}
lib/std/fs.zig+2-4
...@@ -887,10 +887,8 @@ pub const Dir = struct {...@@ -887,10 +887,8 @@ pub const Dir = struct {
887 }887 }
888888
889 pub fn deinit(self: *Walker) void {889 pub fn deinit(self: *Walker) void {
890 while (self.stack.popOrNull()) |*item| {890 for (self.stack.items) |*item| {
891 if (self.stack.items.len != 0) {891 item.iter.dir.close();
892 item.iter.dir.close();
893 }
894 }892 }
895 self.stack.deinit();893 self.stack.deinit();
896 self.name_buffer.deinit();894 self.name_buffer.deinit();
lib/std/os/linux/io_uring.zig+96-100
...@@ -7,10 +7,6 @@ const os = std.os;...@@ -7,10 +7,6 @@ const os = std.os;
7const linux = os.linux;7const linux = os.linux;
8const testing = std.testing;8const testing = std.testing;
99
10const io_uring_params = linux.io_uring_params;
11const io_uring_sqe = linux.io_uring_sqe;
12const io_uring_cqe = linux.io_uring_cqe;
13
14pub const IO_Uring = struct {10pub const IO_Uring = struct {
15 fd: os.fd_t = -1,11 fd: os.fd_t = -1,
16 sq: SubmissionQueue,12 sq: SubmissionQueue,
...@@ -18,24 +14,24 @@ pub const IO_Uring = struct {...@@ -18,24 +14,24 @@ pub const IO_Uring = struct {
18 flags: u32,14 flags: u32,
19 features: u32,15 features: u32,
2016
21 /// A friendly way to setup an io_uring, with default io_uring_params.17 /// A friendly way to setup an io_uring, with default linux.io_uring_params.
22 /// `entries` must be a power of two between 1 and 4096, although the kernel will make the final18 /// `entries` must be a power of two between 1 and 4096, although the kernel will make the final
23 /// call on how many entries the submission and completion queues will ultimately have,19 /// call on how many entries the submission and completion queues will ultimately have,
24 /// see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L8027-L8050.20 /// see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L8027-L8050.
25 /// Matches the interface of io_uring_queue_init() in liburing.21 /// Matches the interface of io_uring_queue_init() in liburing.
26 pub fn init(entries: u13, flags: u32) !IO_Uring {22 pub fn init(entries: u13, flags: u32) !IO_Uring {
27 var params = mem.zeroInit(io_uring_params, .{23 var params = mem.zeroInit(linux.io_uring_params, .{
28 .flags = flags,24 .flags = flags,
29 .sq_thread_idle = 1000,25 .sq_thread_idle = 1000,
30 });26 });
31 return try IO_Uring.init_params(entries, &params);27 return try IO_Uring.init_params(entries, &params);
32 }28 }
3329
34 /// A powerful way to setup an io_uring, if you want to tweak io_uring_params such as submission30 /// A powerful way to setup an io_uring, if you want to tweak linux.io_uring_params such as submission
35 /// queue thread cpu affinity or thread idle timeout (the kernel and our default is 1 second).31 /// queue thread cpu affinity or thread idle timeout (the kernel and our default is 1 second).
36 /// `params` is passed by reference because the kernel needs to modify the parameters.32 /// `params` is passed by reference because the kernel needs to modify the parameters.
37 /// Matches the interface of io_uring_queue_init_params() in liburing.33 /// Matches the interface of io_uring_queue_init_params() in liburing.
38 pub fn init_params(entries: u13, p: *io_uring_params) !IO_Uring {34 pub fn init_params(entries: u13, p: *linux.io_uring_params) !IO_Uring {
39 if (entries == 0) return error.EntriesZero;35 if (entries == 0) return error.EntriesZero;
40 if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;36 if (!std.math.isPowerOfTwo(entries)) return error.EntriesNotPowerOfTwo;
4137
...@@ -53,7 +49,7 @@ pub const IO_Uring = struct {...@@ -53,7 +49,7 @@ pub const IO_Uring = struct {
53 .FAULT => return error.ParamsOutsideAccessibleAddressSpace,49 .FAULT => return error.ParamsOutsideAccessibleAddressSpace,
54 // The resv array contains non-zero data, p.flags contains an unsupported flag,50 // The resv array contains non-zero data, p.flags contains an unsupported flag,
55 // entries out of bounds, IORING_SETUP_SQ_AFF was specified without IORING_SETUP_SQPOLL,51 // entries out of bounds, IORING_SETUP_SQ_AFF was specified without IORING_SETUP_SQPOLL,
56 // or IORING_SETUP_CQSIZE was specified but io_uring_params.cq_entries was invalid:52 // or IORING_SETUP_CQSIZE was specified but linux.io_uring_params.cq_entries was invalid:
57 .INVAL => return error.ArgumentsInvalid,53 .INVAL => return error.ArgumentsInvalid,
58 .MFILE => return error.ProcessFdQuotaExceeded,54 .MFILE => return error.ProcessFdQuotaExceeded,
59 .NFILE => return error.SystemFdQuotaExceeded,55 .NFILE => return error.SystemFdQuotaExceeded,
...@@ -135,7 +131,7 @@ pub const IO_Uring = struct {...@@ -135,7 +131,7 @@ pub const IO_Uring = struct {
135 /// and the null return in liburing is more a C idiom than anything else, for lack of a better131 /// and the null return in liburing is more a C idiom than anything else, for lack of a better
136 /// alternative. In Zig, we have first-class error handling... so let's use it.132 /// alternative. In Zig, we have first-class error handling... so let's use it.
137 /// Matches the implementation of io_uring_get_sqe() in liburing.133 /// Matches the implementation of io_uring_get_sqe() in liburing.
138 pub fn get_sqe(self: *IO_Uring) !*io_uring_sqe {134 pub fn get_sqe(self: *IO_Uring) !*linux.io_uring_sqe {
139 const head = @atomicLoad(u32, self.sq.head, .Acquire);135 const head = @atomicLoad(u32, self.sq.head, .Acquire);
140 // Remember that these head and tail offsets wrap around every four billion operations.136 // Remember that these head and tail offsets wrap around every four billion operations.
141 // We must therefore use wrapping addition and subtraction to avoid a runtime crash.137 // We must therefore use wrapping addition and subtraction to avoid a runtime crash.
...@@ -268,7 +264,7 @@ pub const IO_Uring = struct {...@@ -268,7 +264,7 @@ pub const IO_Uring = struct {
268 /// Faster, because we can now amortize the atomic store release to `cq.head` across the batch.264 /// Faster, because we can now amortize the atomic store release to `cq.head` across the batch.
269 /// See https://github.com/axboe/liburing/issues/103#issuecomment-686665007.265 /// See https://github.com/axboe/liburing/issues/103#issuecomment-686665007.
270 /// Matches the implementation of io_uring_peek_batch_cqe() in liburing, but supports waiting.266 /// Matches the implementation of io_uring_peek_batch_cqe() in liburing, but supports waiting.
271 pub fn copy_cqes(self: *IO_Uring, cqes: []io_uring_cqe, wait_nr: u32) !u32 {267 pub fn copy_cqes(self: *IO_Uring, cqes: []linux.io_uring_cqe, wait_nr: u32) !u32 {
272 const count = self.copy_cqes_ready(cqes, wait_nr);268 const count = self.copy_cqes_ready(cqes, wait_nr);
273 if (count > 0) return count;269 if (count > 0) return count;
274 if (self.cq_ring_needs_flush() or wait_nr > 0) {270 if (self.cq_ring_needs_flush() or wait_nr > 0) {
...@@ -278,7 +274,7 @@ pub const IO_Uring = struct {...@@ -278,7 +274,7 @@ pub const IO_Uring = struct {
278 return 0;274 return 0;
279 }275 }
280276
281 fn copy_cqes_ready(self: *IO_Uring, cqes: []io_uring_cqe, wait_nr: u32) u32 {277 fn copy_cqes_ready(self: *IO_Uring, cqes: []linux.io_uring_cqe, wait_nr: u32) u32 {
282 _ = wait_nr;278 _ = wait_nr;
283 const ready = self.cq_ready();279 const ready = self.cq_ready();
284 const count = std.math.min(cqes.len, ready);280 const count = std.math.min(cqes.len, ready);
...@@ -298,8 +294,8 @@ pub const IO_Uring = struct {...@@ -298,8 +294,8 @@ pub const IO_Uring = struct {
298294
299 /// Returns a copy of an I/O completion, waiting for it if necessary, and advancing the CQ ring.295 /// Returns a copy of an I/O completion, waiting for it if necessary, and advancing the CQ ring.
300 /// A convenience method for `copy_cqes()` for when you don't need to batch or peek.296 /// A convenience method for `copy_cqes()` for when you don't need to batch or peek.
301 pub fn copy_cqe(ring: *IO_Uring) !io_uring_cqe {297 pub fn copy_cqe(ring: *IO_Uring) !linux.io_uring_cqe {
302 var cqes: [1]io_uring_cqe = undefined;298 var cqes: [1]linux.io_uring_cqe = undefined;
303 while (true) {299 while (true) {
304 const count = try ring.copy_cqes(&cqes, 1);300 const count = try ring.copy_cqes(&cqes, 1);
305 if (count > 0) return cqes[0];301 if (count > 0) return cqes[0];
...@@ -316,7 +312,7 @@ pub const IO_Uring = struct {...@@ -316,7 +312,7 @@ pub const IO_Uring = struct {
316 /// Must be called exactly once after a zero-copy CQE has been processed by your application.312 /// Must be called exactly once after a zero-copy CQE has been processed by your application.
317 /// Not idempotent, calling more than once will result in other CQEs being lost.313 /// Not idempotent, calling more than once will result in other CQEs being lost.
318 /// Matches the implementation of cqe_seen() in liburing.314 /// Matches the implementation of cqe_seen() in liburing.
319 pub fn cqe_seen(self: *IO_Uring, cqe: *io_uring_cqe) void {315 pub fn cqe_seen(self: *IO_Uring, cqe: *linux.io_uring_cqe) void {
320 _ = cqe;316 _ = cqe;
321 self.cq_advance(1);317 self.cq_advance(1);
322 }318 }
...@@ -339,7 +335,7 @@ pub const IO_Uring = struct {...@@ -339,7 +335,7 @@ pub const IO_Uring = struct {
339 /// apply to the write, since the fsync may complete before the write is issued to the disk.335 /// apply to the write, since the fsync may complete before the write is issued to the disk.
340 /// You should preferably use `link_with_next_sqe()` on a write's SQE to link it with an fsync,336 /// You should preferably use `link_with_next_sqe()` on a write's SQE to link it with an fsync,
341 /// or else insert a full write barrier using `drain_previous_sqes()` when queueing an fsync.337 /// or else insert a full write barrier using `drain_previous_sqes()` when queueing an fsync.
342 pub fn fsync(self: *IO_Uring, user_data: u64, fd: os.fd_t, flags: u32) !*io_uring_sqe {338 pub fn fsync(self: *IO_Uring, user_data: u64, fd: os.fd_t, flags: u32) !*linux.io_uring_sqe {
343 const sqe = try self.get_sqe();339 const sqe = try self.get_sqe();
344 io_uring_prep_fsync(sqe, fd, flags);340 io_uring_prep_fsync(sqe, fd, flags);
345 sqe.user_data = user_data;341 sqe.user_data = user_data;
...@@ -351,7 +347,7 @@ pub const IO_Uring = struct {...@@ -351,7 +347,7 @@ pub const IO_Uring = struct {
351 /// A no-op is more useful than may appear at first glance.347 /// A no-op is more useful than may appear at first glance.
352 /// For example, you could call `drain_previous_sqes()` on the returned SQE, to use the no-op to348 /// For example, you could call `drain_previous_sqes()` on the returned SQE, to use the no-op to
353 /// know when the ring is idle before acting on a kill signal.349 /// know when the ring is idle before acting on a kill signal.
354 pub fn nop(self: *IO_Uring, user_data: u64) !*io_uring_sqe {350 pub fn nop(self: *IO_Uring, user_data: u64) !*linux.io_uring_sqe {
355 const sqe = try self.get_sqe();351 const sqe = try self.get_sqe();
356 io_uring_prep_nop(sqe);352 io_uring_prep_nop(sqe);
357 sqe.user_data = user_data;353 sqe.user_data = user_data;
...@@ -387,7 +383,7 @@ pub const IO_Uring = struct {...@@ -387,7 +383,7 @@ pub const IO_Uring = struct {
387 fd: os.fd_t,383 fd: os.fd_t,
388 buffer: ReadBuffer,384 buffer: ReadBuffer,
389 offset: u64,385 offset: u64,
390 ) !*io_uring_sqe {386 ) !*linux.io_uring_sqe {
391 const sqe = try self.get_sqe();387 const sqe = try self.get_sqe();
392 switch (buffer) {388 switch (buffer) {
393 .buffer => |slice| io_uring_prep_read(sqe, fd, slice, offset),389 .buffer => |slice| io_uring_prep_read(sqe, fd, slice, offset),
...@@ -410,7 +406,7 @@ pub const IO_Uring = struct {...@@ -410,7 +406,7 @@ pub const IO_Uring = struct {
410 fd: os.fd_t,406 fd: os.fd_t,
411 buffer: []const u8,407 buffer: []const u8,
412 offset: u64,408 offset: u64,
413 ) !*io_uring_sqe {409 ) !*linux.io_uring_sqe {
414 const sqe = try self.get_sqe();410 const sqe = try self.get_sqe();
415 io_uring_prep_write(sqe, fd, buffer, offset);411 io_uring_prep_write(sqe, fd, buffer, offset);
416 sqe.user_data = user_data;412 sqe.user_data = user_data;
...@@ -429,7 +425,7 @@ pub const IO_Uring = struct {...@@ -429,7 +425,7 @@ pub const IO_Uring = struct {
429 buffer: *os.iovec,425 buffer: *os.iovec,
430 offset: u64,426 offset: u64,
431 buffer_index: u16,427 buffer_index: u16,
432 ) !*io_uring_sqe {428 ) !*linux.io_uring_sqe {
433 const sqe = try self.get_sqe();429 const sqe = try self.get_sqe();
434 io_uring_prep_read_fixed(sqe, fd, buffer, offset, buffer_index);430 io_uring_prep_read_fixed(sqe, fd, buffer, offset, buffer_index);
435 sqe.user_data = user_data;431 sqe.user_data = user_data;
...@@ -446,7 +442,7 @@ pub const IO_Uring = struct {...@@ -446,7 +442,7 @@ pub const IO_Uring = struct {
446 fd: os.fd_t,442 fd: os.fd_t,
447 iovecs: []const os.iovec_const,443 iovecs: []const os.iovec_const,
448 offset: u64,444 offset: u64,
449 ) !*io_uring_sqe {445 ) !*linux.io_uring_sqe {
450 const sqe = try self.get_sqe();446 const sqe = try self.get_sqe();
451 io_uring_prep_writev(sqe, fd, iovecs, offset);447 io_uring_prep_writev(sqe, fd, iovecs, offset);
452 sqe.user_data = user_data;448 sqe.user_data = user_data;
...@@ -465,7 +461,7 @@ pub const IO_Uring = struct {...@@ -465,7 +461,7 @@ pub const IO_Uring = struct {
465 buffer: *os.iovec,461 buffer: *os.iovec,
466 offset: u64,462 offset: u64,
467 buffer_index: u16,463 buffer_index: u16,
468 ) !*io_uring_sqe {464 ) !*linux.io_uring_sqe {
469 const sqe = try self.get_sqe();465 const sqe = try self.get_sqe();
470 io_uring_prep_write_fixed(sqe, fd, buffer, offset, buffer_index);466 io_uring_prep_write_fixed(sqe, fd, buffer, offset, buffer_index);
471 sqe.user_data = user_data;467 sqe.user_data = user_data;
...@@ -481,7 +477,7 @@ pub const IO_Uring = struct {...@@ -481,7 +477,7 @@ pub const IO_Uring = struct {
481 addr: *os.sockaddr,477 addr: *os.sockaddr,
482 addrlen: *os.socklen_t,478 addrlen: *os.socklen_t,
483 flags: u32,479 flags: u32,
484 ) !*io_uring_sqe {480 ) !*linux.io_uring_sqe {
485 const sqe = try self.get_sqe();481 const sqe = try self.get_sqe();
486 io_uring_prep_accept(sqe, fd, addr, addrlen, flags);482 io_uring_prep_accept(sqe, fd, addr, addrlen, flags);
487 sqe.user_data = user_data;483 sqe.user_data = user_data;
...@@ -496,7 +492,7 @@ pub const IO_Uring = struct {...@@ -496,7 +492,7 @@ pub const IO_Uring = struct {
496 fd: os.fd_t,492 fd: os.fd_t,
497 addr: *const os.sockaddr,493 addr: *const os.sockaddr,
498 addrlen: os.socklen_t,494 addrlen: os.socklen_t,
499 ) !*io_uring_sqe {495 ) !*linux.io_uring_sqe {
500 const sqe = try self.get_sqe();496 const sqe = try self.get_sqe();
501 io_uring_prep_connect(sqe, fd, addr, addrlen);497 io_uring_prep_connect(sqe, fd, addr, addrlen);
502 sqe.user_data = user_data;498 sqe.user_data = user_data;
...@@ -512,7 +508,7 @@ pub const IO_Uring = struct {...@@ -512,7 +508,7 @@ pub const IO_Uring = struct {
512 fd: os.fd_t,508 fd: os.fd_t,
513 op: u32,509 op: u32,
514 ev: ?*linux.epoll_event,510 ev: ?*linux.epoll_event,
515 ) !*io_uring_sqe {511 ) !*linux.io_uring_sqe {
516 const sqe = try self.get_sqe();512 const sqe = try self.get_sqe();
517 io_uring_prep_epoll_ctl(sqe, epfd, fd, op, ev);513 io_uring_prep_epoll_ctl(sqe, epfd, fd, op, ev);
518 sqe.user_data = user_data;514 sqe.user_data = user_data;
...@@ -541,7 +537,7 @@ pub const IO_Uring = struct {...@@ -541,7 +537,7 @@ pub const IO_Uring = struct {
541 fd: os.fd_t,537 fd: os.fd_t,
542 buffer: RecvBuffer,538 buffer: RecvBuffer,
543 flags: u32,539 flags: u32,
544 ) !*io_uring_sqe {540 ) !*linux.io_uring_sqe {
545 const sqe = try self.get_sqe();541 const sqe = try self.get_sqe();
546 switch (buffer) {542 switch (buffer) {
547 .buffer => |slice| io_uring_prep_recv(sqe, fd, slice, flags),543 .buffer => |slice| io_uring_prep_recv(sqe, fd, slice, flags),
...@@ -564,7 +560,7 @@ pub const IO_Uring = struct {...@@ -564,7 +560,7 @@ pub const IO_Uring = struct {
564 fd: os.fd_t,560 fd: os.fd_t,
565 buffer: []const u8,561 buffer: []const u8,
566 flags: u32,562 flags: u32,
567 ) !*io_uring_sqe {563 ) !*linux.io_uring_sqe {
568 const sqe = try self.get_sqe();564 const sqe = try self.get_sqe();
569 io_uring_prep_send(sqe, fd, buffer, flags);565 io_uring_prep_send(sqe, fd, buffer, flags);
570 sqe.user_data = user_data;566 sqe.user_data = user_data;
...@@ -579,7 +575,7 @@ pub const IO_Uring = struct {...@@ -579,7 +575,7 @@ pub const IO_Uring = struct {
579 fd: os.fd_t,575 fd: os.fd_t,
580 msg: *os.msghdr,576 msg: *os.msghdr,
581 flags: u32,577 flags: u32,
582 ) !*io_uring_sqe {578 ) !*linux.io_uring_sqe {
583 const sqe = try self.get_sqe();579 const sqe = try self.get_sqe();
584 io_uring_prep_recvmsg(sqe, fd, msg, flags);580 io_uring_prep_recvmsg(sqe, fd, msg, flags);
585 sqe.user_data = user_data;581 sqe.user_data = user_data;
...@@ -594,7 +590,7 @@ pub const IO_Uring = struct {...@@ -594,7 +590,7 @@ pub const IO_Uring = struct {
594 fd: os.fd_t,590 fd: os.fd_t,
595 msg: *const os.msghdr_const,591 msg: *const os.msghdr_const,
596 flags: u32,592 flags: u32,
597 ) !*io_uring_sqe {593 ) !*linux.io_uring_sqe {
598 const sqe = try self.get_sqe();594 const sqe = try self.get_sqe();
599 io_uring_prep_sendmsg(sqe, fd, msg, flags);595 io_uring_prep_sendmsg(sqe, fd, msg, flags);
600 sqe.user_data = user_data;596 sqe.user_data = user_data;
...@@ -610,7 +606,7 @@ pub const IO_Uring = struct {...@@ -610,7 +606,7 @@ pub const IO_Uring = struct {
610 path: [*:0]const u8,606 path: [*:0]const u8,
611 flags: u32,607 flags: u32,
612 mode: os.mode_t,608 mode: os.mode_t,
613 ) !*io_uring_sqe {609 ) !*linux.io_uring_sqe {
614 const sqe = try self.get_sqe();610 const sqe = try self.get_sqe();
615 io_uring_prep_openat(sqe, fd, path, flags, mode);611 io_uring_prep_openat(sqe, fd, path, flags, mode);
616 sqe.user_data = user_data;612 sqe.user_data = user_data;
...@@ -619,7 +615,7 @@ pub const IO_Uring = struct {...@@ -619,7 +615,7 @@ pub const IO_Uring = struct {
619615
620 /// Queues (but does not submit) an SQE to perform a `close(2)`.616 /// Queues (but does not submit) an SQE to perform a `close(2)`.
621 /// Returns a pointer to the SQE.617 /// Returns a pointer to the SQE.
622 pub fn close(self: *IO_Uring, user_data: u64, fd: os.fd_t) !*io_uring_sqe {618 pub fn close(self: *IO_Uring, user_data: u64, fd: os.fd_t) !*linux.io_uring_sqe {
623 const sqe = try self.get_sqe();619 const sqe = try self.get_sqe();
624 io_uring_prep_close(sqe, fd);620 io_uring_prep_close(sqe, fd);
625 sqe.user_data = user_data;621 sqe.user_data = user_data;
...@@ -645,7 +641,7 @@ pub const IO_Uring = struct {...@@ -645,7 +641,7 @@ pub const IO_Uring = struct {
645 ts: *const os.linux.kernel_timespec,641 ts: *const os.linux.kernel_timespec,
646 count: u32,642 count: u32,
647 flags: u32,643 flags: u32,
648 ) !*io_uring_sqe {644 ) !*linux.io_uring_sqe {
649 const sqe = try self.get_sqe();645 const sqe = try self.get_sqe();
650 io_uring_prep_timeout(sqe, ts, count, flags);646 io_uring_prep_timeout(sqe, ts, count, flags);
651 sqe.user_data = user_data;647 sqe.user_data = user_data;
...@@ -665,7 +661,7 @@ pub const IO_Uring = struct {...@@ -665,7 +661,7 @@ pub const IO_Uring = struct {
665 user_data: u64,661 user_data: u64,
666 timeout_user_data: u64,662 timeout_user_data: u64,
667 flags: u32,663 flags: u32,
668 ) !*io_uring_sqe {664 ) !*linux.io_uring_sqe {
669 const sqe = try self.get_sqe();665 const sqe = try self.get_sqe();
670 io_uring_prep_timeout_remove(sqe, timeout_user_data, flags);666 io_uring_prep_timeout_remove(sqe, timeout_user_data, flags);
671 sqe.user_data = user_data;667 sqe.user_data = user_data;
...@@ -693,7 +689,7 @@ pub const IO_Uring = struct {...@@ -693,7 +689,7 @@ pub const IO_Uring = struct {
693 user_data: u64,689 user_data: u64,
694 ts: *const os.linux.kernel_timespec,690 ts: *const os.linux.kernel_timespec,
695 flags: u32,691 flags: u32,
696 ) !*io_uring_sqe {692 ) !*linux.io_uring_sqe {
697 const sqe = try self.get_sqe();693 const sqe = try self.get_sqe();
698 io_uring_prep_link_timeout(sqe, ts, flags);694 io_uring_prep_link_timeout(sqe, ts, flags);
699 sqe.user_data = user_data;695 sqe.user_data = user_data;
...@@ -707,7 +703,7 @@ pub const IO_Uring = struct {...@@ -707,7 +703,7 @@ pub const IO_Uring = struct {
707 user_data: u64,703 user_data: u64,
708 fd: os.fd_t,704 fd: os.fd_t,
709 poll_mask: u32,705 poll_mask: u32,
710 ) !*io_uring_sqe {706 ) !*linux.io_uring_sqe {
711 const sqe = try self.get_sqe();707 const sqe = try self.get_sqe();
712 io_uring_prep_poll_add(sqe, fd, poll_mask);708 io_uring_prep_poll_add(sqe, fd, poll_mask);
713 sqe.user_data = user_data;709 sqe.user_data = user_data;
...@@ -720,7 +716,7 @@ pub const IO_Uring = struct {...@@ -720,7 +716,7 @@ pub const IO_Uring = struct {
720 self: *IO_Uring,716 self: *IO_Uring,
721 user_data: u64,717 user_data: u64,
722 target_user_data: u64,718 target_user_data: u64,
723 ) !*io_uring_sqe {719 ) !*linux.io_uring_sqe {
724 const sqe = try self.get_sqe();720 const sqe = try self.get_sqe();
725 io_uring_prep_poll_remove(sqe, target_user_data);721 io_uring_prep_poll_remove(sqe, target_user_data);
726 sqe.user_data = user_data;722 sqe.user_data = user_data;
...@@ -736,7 +732,7 @@ pub const IO_Uring = struct {...@@ -736,7 +732,7 @@ pub const IO_Uring = struct {
736 new_user_data: u64,732 new_user_data: u64,
737 poll_mask: u32,733 poll_mask: u32,
738 flags: u32,734 flags: u32,
739 ) !*io_uring_sqe {735 ) !*linux.io_uring_sqe {
740 const sqe = try self.get_sqe();736 const sqe = try self.get_sqe();
741 io_uring_prep_poll_update(sqe, old_user_data, new_user_data, poll_mask, flags);737 io_uring_prep_poll_update(sqe, old_user_data, new_user_data, poll_mask, flags);
742 sqe.user_data = user_data;738 sqe.user_data = user_data;
...@@ -752,7 +748,7 @@ pub const IO_Uring = struct {...@@ -752,7 +748,7 @@ pub const IO_Uring = struct {
752 mode: i32,748 mode: i32,
753 offset: u64,749 offset: u64,
754 len: u64,750 len: u64,
755 ) !*io_uring_sqe {751 ) !*linux.io_uring_sqe {
756 const sqe = try self.get_sqe();752 const sqe = try self.get_sqe();
757 io_uring_prep_fallocate(sqe, fd, mode, offset, len);753 io_uring_prep_fallocate(sqe, fd, mode, offset, len);
758 sqe.user_data = user_data;754 sqe.user_data = user_data;
...@@ -769,7 +765,7 @@ pub const IO_Uring = struct {...@@ -769,7 +765,7 @@ pub const IO_Uring = struct {
769 flags: u32,765 flags: u32,
770 mask: u32,766 mask: u32,
771 buf: *linux.Statx,767 buf: *linux.Statx,
772 ) !*io_uring_sqe {768 ) !*linux.io_uring_sqe {
773 const sqe = try self.get_sqe();769 const sqe = try self.get_sqe();
774 io_uring_prep_statx(sqe, fd, path, flags, mask, buf);770 io_uring_prep_statx(sqe, fd, path, flags, mask, buf);
775 sqe.user_data = user_data;771 sqe.user_data = user_data;
...@@ -789,7 +785,7 @@ pub const IO_Uring = struct {...@@ -789,7 +785,7 @@ pub const IO_Uring = struct {
789 user_data: u64,785 user_data: u64,
790 cancel_user_data: u64,786 cancel_user_data: u64,
791 flags: u32,787 flags: u32,
792 ) !*io_uring_sqe {788 ) !*linux.io_uring_sqe {
793 const sqe = try self.get_sqe();789 const sqe = try self.get_sqe();
794 io_uring_prep_cancel(sqe, cancel_user_data, flags);790 io_uring_prep_cancel(sqe, cancel_user_data, flags);
795 sqe.user_data = user_data;791 sqe.user_data = user_data;
...@@ -805,7 +801,7 @@ pub const IO_Uring = struct {...@@ -805,7 +801,7 @@ pub const IO_Uring = struct {
805 user_data: u64,801 user_data: u64,
806 sockfd: os.socket_t,802 sockfd: os.socket_t,
807 how: u32,803 how: u32,
808 ) !*io_uring_sqe {804 ) !*linux.io_uring_sqe {
809 const sqe = try self.get_sqe();805 const sqe = try self.get_sqe();
810 io_uring_prep_shutdown(sqe, sockfd, how);806 io_uring_prep_shutdown(sqe, sockfd, how);
811 sqe.user_data = user_data;807 sqe.user_data = user_data;
...@@ -822,7 +818,7 @@ pub const IO_Uring = struct {...@@ -822,7 +818,7 @@ pub const IO_Uring = struct {
822 new_dir_fd: os.fd_t,818 new_dir_fd: os.fd_t,
823 new_path: [*:0]const u8,819 new_path: [*:0]const u8,
824 flags: u32,820 flags: u32,
825 ) !*io_uring_sqe {821 ) !*linux.io_uring_sqe {
826 const sqe = try self.get_sqe();822 const sqe = try self.get_sqe();
827 io_uring_prep_renameat(sqe, old_dir_fd, old_path, new_dir_fd, new_path, flags);823 io_uring_prep_renameat(sqe, old_dir_fd, old_path, new_dir_fd, new_path, flags);
828 sqe.user_data = user_data;824 sqe.user_data = user_data;
...@@ -837,7 +833,7 @@ pub const IO_Uring = struct {...@@ -837,7 +833,7 @@ pub const IO_Uring = struct {
837 dir_fd: os.fd_t,833 dir_fd: os.fd_t,
838 path: [*:0]const u8,834 path: [*:0]const u8,
839 flags: u32,835 flags: u32,
840 ) !*io_uring_sqe {836 ) !*linux.io_uring_sqe {
841 const sqe = try self.get_sqe();837 const sqe = try self.get_sqe();
842 io_uring_prep_unlinkat(sqe, dir_fd, path, flags);838 io_uring_prep_unlinkat(sqe, dir_fd, path, flags);
843 sqe.user_data = user_data;839 sqe.user_data = user_data;
...@@ -852,7 +848,7 @@ pub const IO_Uring = struct {...@@ -852,7 +848,7 @@ pub const IO_Uring = struct {
852 dir_fd: os.fd_t,848 dir_fd: os.fd_t,
853 path: [*:0]const u8,849 path: [*:0]const u8,
854 mode: os.mode_t,850 mode: os.mode_t,
855 ) !*io_uring_sqe {851 ) !*linux.io_uring_sqe {
856 const sqe = try self.get_sqe();852 const sqe = try self.get_sqe();
857 io_uring_prep_mkdirat(sqe, dir_fd, path, mode);853 io_uring_prep_mkdirat(sqe, dir_fd, path, mode);
858 sqe.user_data = user_data;854 sqe.user_data = user_data;
...@@ -867,7 +863,7 @@ pub const IO_Uring = struct {...@@ -867,7 +863,7 @@ pub const IO_Uring = struct {
867 target: [*:0]const u8,863 target: [*:0]const u8,
868 new_dir_fd: os.fd_t,864 new_dir_fd: os.fd_t,
869 link_path: [*:0]const u8,865 link_path: [*:0]const u8,
870 ) !*io_uring_sqe {866 ) !*linux.io_uring_sqe {
871 const sqe = try self.get_sqe();867 const sqe = try self.get_sqe();
872 io_uring_prep_symlinkat(sqe, target, new_dir_fd, link_path);868 io_uring_prep_symlinkat(sqe, target, new_dir_fd, link_path);
873 sqe.user_data = user_data;869 sqe.user_data = user_data;
...@@ -884,7 +880,7 @@ pub const IO_Uring = struct {...@@ -884,7 +880,7 @@ pub const IO_Uring = struct {
884 new_dir_fd: os.fd_t,880 new_dir_fd: os.fd_t,
885 new_path: [*:0]const u8,881 new_path: [*:0]const u8,
886 flags: u32,882 flags: u32,
887 ) !*io_uring_sqe {883 ) !*linux.io_uring_sqe {
888 const sqe = try self.get_sqe();884 const sqe = try self.get_sqe();
889 io_uring_prep_linkat(sqe, old_dir_fd, old_path, new_dir_fd, new_path, flags);885 io_uring_prep_linkat(sqe, old_dir_fd, old_path, new_dir_fd, new_path, flags);
890 sqe.user_data = user_data;886 sqe.user_data = user_data;
...@@ -905,7 +901,7 @@ pub const IO_Uring = struct {...@@ -905,7 +901,7 @@ pub const IO_Uring = struct {
905 buffer_size: usize,901 buffer_size: usize,
906 group_id: usize,902 group_id: usize,
907 buffer_id: usize,903 buffer_id: usize,
908 ) !*io_uring_sqe {904 ) !*linux.io_uring_sqe {
909 const sqe = try self.get_sqe();905 const sqe = try self.get_sqe();
910 io_uring_prep_provide_buffers(sqe, buffers, buffers_count, buffer_size, group_id, buffer_id);906 io_uring_prep_provide_buffers(sqe, buffers, buffers_count, buffer_size, group_id, buffer_id);
911 sqe.user_data = user_data;907 sqe.user_data = user_data;
...@@ -919,7 +915,7 @@ pub const IO_Uring = struct {...@@ -919,7 +915,7 @@ pub const IO_Uring = struct {
919 user_data: u64,915 user_data: u64,
920 buffers_count: usize,916 buffers_count: usize,
921 group_id: usize,917 group_id: usize,
922 ) !*io_uring_sqe {918 ) !*linux.io_uring_sqe {
923 const sqe = try self.get_sqe();919 const sqe = try self.get_sqe();
924 io_uring_prep_remove_buffers(sqe, buffers_count, group_id);920 io_uring_prep_remove_buffers(sqe, buffers_count, group_id);
925 sqe.user_data = user_data;921 sqe.user_data = user_data;
...@@ -1083,7 +1079,7 @@ pub const SubmissionQueue = struct {...@@ -1083,7 +1079,7 @@ pub const SubmissionQueue = struct {
1083 flags: *u32,1079 flags: *u32,
1084 dropped: *u32,1080 dropped: *u32,
1085 array: []u32,1081 array: []u32,
1086 sqes: []io_uring_sqe,1082 sqes: []linux.io_uring_sqe,
1087 mmap: []align(mem.page_size) u8,1083 mmap: []align(mem.page_size) u8,
1088 mmap_sqes: []align(mem.page_size) u8,1084 mmap_sqes: []align(mem.page_size) u8,
10891085
...@@ -1094,12 +1090,12 @@ pub const SubmissionQueue = struct {...@@ -1094,12 +1090,12 @@ pub const SubmissionQueue = struct {
1094 sqe_head: u32 = 0,1090 sqe_head: u32 = 0,
1095 sqe_tail: u32 = 0,1091 sqe_tail: u32 = 0,
10961092
1097 pub fn init(fd: os.fd_t, p: io_uring_params) !SubmissionQueue {1093 pub fn init(fd: os.fd_t, p: linux.io_uring_params) !SubmissionQueue {
1098 assert(fd >= 0);1094 assert(fd >= 0);
1099 assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);1095 assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);
1100 const size = std.math.max(1096 const size = std.math.max(
1101 p.sq_off.array + p.sq_entries * @sizeOf(u32),1097 p.sq_off.array + p.sq_entries * @sizeOf(u32),
1102 p.cq_off.cqes + p.cq_entries * @sizeOf(io_uring_cqe),1098 p.cq_off.cqes + p.cq_entries * @sizeOf(linux.io_uring_cqe),
1103 );1099 );
1104 const mmap = try os.mmap(1100 const mmap = try os.mmap(
1105 null,1101 null,
...@@ -1113,8 +1109,8 @@ pub const SubmissionQueue = struct {...@@ -1113,8 +1109,8 @@ pub const SubmissionQueue = struct {
1113 assert(mmap.len == size);1109 assert(mmap.len == size);
11141110
1115 // The motivation for the `sqes` and `array` indirection is to make it possible for the1111 // The motivation for the `sqes` and `array` indirection is to make it possible for the
1116 // application to preallocate static io_uring_sqe entries and then replay them when needed.1112 // application to preallocate static linux.io_uring_sqe entries and then replay them when needed.
1117 const size_sqes = p.sq_entries * @sizeOf(io_uring_sqe);1113 const size_sqes = p.sq_entries * @sizeOf(linux.io_uring_sqe);
1118 const mmap_sqes = try os.mmap(1114 const mmap_sqes = try os.mmap(
1119 null,1115 null,
1120 size_sqes,1116 size_sqes,
...@@ -1127,7 +1123,7 @@ pub const SubmissionQueue = struct {...@@ -1127,7 +1123,7 @@ pub const SubmissionQueue = struct {
1127 assert(mmap_sqes.len == size_sqes);1123 assert(mmap_sqes.len == size_sqes);
11281124
1129 const array = @ptrCast([*]u32, @alignCast(@alignOf(u32), &mmap[p.sq_off.array]));1125 const array = @ptrCast([*]u32, @alignCast(@alignOf(u32), &mmap[p.sq_off.array]));
1130 const sqes = @ptrCast([*]io_uring_sqe, @alignCast(@alignOf(io_uring_sqe), &mmap_sqes[0]));1126 const sqes = @ptrCast([*]linux.io_uring_sqe, @alignCast(@alignOf(linux.io_uring_sqe), &mmap_sqes[0]));
1131 // We expect the kernel copies p.sq_entries to the u32 pointed to by p.sq_off.ring_entries,1127 // We expect the kernel copies p.sq_entries to the u32 pointed to by p.sq_off.ring_entries,
1132 // see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L7843-L7844.1128 // see https://github.com/torvalds/linux/blob/v5.8/fs/io_uring.c#L7843-L7844.
1133 assert(1129 assert(
...@@ -1158,15 +1154,15 @@ pub const CompletionQueue = struct {...@@ -1158,15 +1154,15 @@ pub const CompletionQueue = struct {
1158 tail: *u32,1154 tail: *u32,
1159 mask: u32,1155 mask: u32,
1160 overflow: *u32,1156 overflow: *u32,
1161 cqes: []io_uring_cqe,1157 cqes: []linux.io_uring_cqe,
11621158
1163 pub fn init(fd: os.fd_t, p: io_uring_params, sq: SubmissionQueue) !CompletionQueue {1159 pub fn init(fd: os.fd_t, p: linux.io_uring_params, sq: SubmissionQueue) !CompletionQueue {
1164 assert(fd >= 0);1160 assert(fd >= 0);
1165 assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);1161 assert((p.features & linux.IORING_FEAT_SINGLE_MMAP) != 0);
1166 const mmap = sq.mmap;1162 const mmap = sq.mmap;
1167 const cqes = @ptrCast(1163 const cqes = @ptrCast(
1168 [*]io_uring_cqe,1164 [*]linux.io_uring_cqe,
1169 @alignCast(@alignOf(io_uring_cqe), &mmap[p.cq_off.cqes]),1165 @alignCast(@alignOf(linux.io_uring_cqe), &mmap[p.cq_off.cqes]),
1170 );1166 );
1171 assert(p.cq_entries ==1167 assert(p.cq_entries ==
1172 @ptrCast(*u32, @alignCast(@alignOf(u32), &mmap[p.cq_off.ring_entries])).*);1168 @ptrCast(*u32, @alignCast(@alignOf(u32), &mmap[p.cq_off.ring_entries])).*);
...@@ -1186,7 +1182,7 @@ pub const CompletionQueue = struct {...@@ -1186,7 +1182,7 @@ pub const CompletionQueue = struct {
1186 }1182 }
1187};1183};
11881184
1189pub fn io_uring_prep_nop(sqe: *io_uring_sqe) void {1185pub fn io_uring_prep_nop(sqe: *linux.io_uring_sqe) void {
1190 sqe.* = .{1186 sqe.* = .{
1191 .opcode = .NOP,1187 .opcode = .NOP,
1192 .flags = 0,1188 .flags = 0,
...@@ -1204,7 +1200,7 @@ pub fn io_uring_prep_nop(sqe: *io_uring_sqe) void {...@@ -1204,7 +1200,7 @@ pub fn io_uring_prep_nop(sqe: *io_uring_sqe) void {
1204 };1200 };
1205}1201}
12061202
1207pub fn io_uring_prep_fsync(sqe: *io_uring_sqe, fd: os.fd_t, flags: u32) void {1203pub fn io_uring_prep_fsync(sqe: *linux.io_uring_sqe, fd: os.fd_t, flags: u32) void {
1208 sqe.* = .{1204 sqe.* = .{
1209 .opcode = .FSYNC,1205 .opcode = .FSYNC,
1210 .flags = 0,1206 .flags = 0,
...@@ -1224,7 +1220,7 @@ pub fn io_uring_prep_fsync(sqe: *io_uring_sqe, fd: os.fd_t, flags: u32) void {...@@ -1224,7 +1220,7 @@ pub fn io_uring_prep_fsync(sqe: *io_uring_sqe, fd: os.fd_t, flags: u32) void {
12241220
1225pub fn io_uring_prep_rw(1221pub fn io_uring_prep_rw(
1226 op: linux.IORING_OP,1222 op: linux.IORING_OP,
1227 sqe: *io_uring_sqe,1223 sqe: *linux.io_uring_sqe,
1228 fd: os.fd_t,1224 fd: os.fd_t,
1229 addr: u64,1225 addr: u64,
1230 len: usize,1226 len: usize,
...@@ -1247,16 +1243,16 @@ pub fn io_uring_prep_rw(...@@ -1247,16 +1243,16 @@ pub fn io_uring_prep_rw(
1247 };1243 };
1248}1244}
12491245
1250pub fn io_uring_prep_read(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []u8, offset: u64) void {1246pub fn io_uring_prep_read(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []u8, offset: u64) void {
1251 io_uring_prep_rw(.READ, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);1247 io_uring_prep_rw(.READ, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);
1252}1248}
12531249
1254pub fn io_uring_prep_write(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []const u8, offset: u64) void {1250pub fn io_uring_prep_write(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, offset: u64) void {
1255 io_uring_prep_rw(.WRITE, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);1251 io_uring_prep_rw(.WRITE, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, offset);
1256}1252}
12571253
1258pub fn io_uring_prep_readv(1254pub fn io_uring_prep_readv(
1259 sqe: *io_uring_sqe,1255 sqe: *linux.io_uring_sqe,
1260 fd: os.fd_t,1256 fd: os.fd_t,
1261 iovecs: []const os.iovec,1257 iovecs: []const os.iovec,
1262 offset: u64,1258 offset: u64,
...@@ -1265,7 +1261,7 @@ pub fn io_uring_prep_readv(...@@ -1265,7 +1261,7 @@ pub fn io_uring_prep_readv(
1265}1261}
12661262
1267pub fn io_uring_prep_writev(1263pub fn io_uring_prep_writev(
1268 sqe: *io_uring_sqe,1264 sqe: *linux.io_uring_sqe,
1269 fd: os.fd_t,1265 fd: os.fd_t,
1270 iovecs: []const os.iovec_const,1266 iovecs: []const os.iovec_const,
1271 offset: u64,1267 offset: u64,
...@@ -1273,12 +1269,12 @@ pub fn io_uring_prep_writev(...@@ -1273,12 +1269,12 @@ pub fn io_uring_prep_writev(
1273 io_uring_prep_rw(.WRITEV, sqe, fd, @ptrToInt(iovecs.ptr), iovecs.len, offset);1269 io_uring_prep_rw(.WRITEV, sqe, fd, @ptrToInt(iovecs.ptr), iovecs.len, offset);
1274}1270}
12751271
1276pub fn io_uring_prep_read_fixed(sqe: *io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {1272pub fn io_uring_prep_read_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
1277 io_uring_prep_rw(.READ_FIXED, sqe, fd, @ptrToInt(buffer.iov_base), buffer.iov_len, offset);1273 io_uring_prep_rw(.READ_FIXED, sqe, fd, @ptrToInt(buffer.iov_base), buffer.iov_len, offset);
1278 sqe.buf_index = buffer_index;1274 sqe.buf_index = buffer_index;
1279}1275}
12801276
1281pub fn io_uring_prep_write_fixed(sqe: *io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {1277pub fn io_uring_prep_write_fixed(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: *os.iovec, offset: u64, buffer_index: u16) void {
1282 io_uring_prep_rw(.WRITE_FIXED, sqe, fd, @ptrToInt(buffer.iov_base), buffer.iov_len, offset);1278 io_uring_prep_rw(.WRITE_FIXED, sqe, fd, @ptrToInt(buffer.iov_base), buffer.iov_len, offset);
1283 sqe.buf_index = buffer_index;1279 sqe.buf_index = buffer_index;
1284}1280}
...@@ -1294,7 +1290,7 @@ pub inline fn __io_uring_prep_poll_mask(poll_mask: u32) u32 {...@@ -1294,7 +1290,7 @@ pub inline fn __io_uring_prep_poll_mask(poll_mask: u32) u32 {
1294}1290}
12951291
1296pub fn io_uring_prep_accept(1292pub fn io_uring_prep_accept(
1297 sqe: *io_uring_sqe,1293 sqe: *linux.io_uring_sqe,
1298 fd: os.fd_t,1294 fd: os.fd_t,
1299 addr: *os.sockaddr,1295 addr: *os.sockaddr,
1300 addrlen: *os.socklen_t,1296 addrlen: *os.socklen_t,
...@@ -1307,7 +1303,7 @@ pub fn io_uring_prep_accept(...@@ -1307,7 +1303,7 @@ pub fn io_uring_prep_accept(
1307}1303}
13081304
1309pub fn io_uring_prep_connect(1305pub fn io_uring_prep_connect(
1310 sqe: *io_uring_sqe,1306 sqe: *linux.io_uring_sqe,
1311 fd: os.fd_t,1307 fd: os.fd_t,
1312 addr: *const os.sockaddr,1308 addr: *const os.sockaddr,
1313 addrlen: os.socklen_t,1309 addrlen: os.socklen_t,
...@@ -1317,7 +1313,7 @@ pub fn io_uring_prep_connect(...@@ -1317,7 +1313,7 @@ pub fn io_uring_prep_connect(
1317}1313}
13181314
1319pub fn io_uring_prep_epoll_ctl(1315pub fn io_uring_prep_epoll_ctl(
1320 sqe: *io_uring_sqe,1316 sqe: *linux.io_uring_sqe,
1321 epfd: os.fd_t,1317 epfd: os.fd_t,
1322 fd: os.fd_t,1318 fd: os.fd_t,
1323 op: u32,1319 op: u32,
...@@ -1326,18 +1322,18 @@ pub fn io_uring_prep_epoll_ctl(...@@ -1326,18 +1322,18 @@ pub fn io_uring_prep_epoll_ctl(
1326 io_uring_prep_rw(.EPOLL_CTL, sqe, epfd, @ptrToInt(ev), op, @intCast(u64, fd));1322 io_uring_prep_rw(.EPOLL_CTL, sqe, epfd, @ptrToInt(ev), op, @intCast(u64, fd));
1327}1323}
13281324
1329pub fn io_uring_prep_recv(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []u8, flags: u32) void {1325pub fn io_uring_prep_recv(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []u8, flags: u32) void {
1330 io_uring_prep_rw(.RECV, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);1326 io_uring_prep_rw(.RECV, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);
1331 sqe.rw_flags = flags;1327 sqe.rw_flags = flags;
1332}1328}
13331329
1334pub fn io_uring_prep_send(sqe: *io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32) void {1330pub fn io_uring_prep_send(sqe: *linux.io_uring_sqe, fd: os.fd_t, buffer: []const u8, flags: u32) void {
1335 io_uring_prep_rw(.SEND, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);1331 io_uring_prep_rw(.SEND, sqe, fd, @ptrToInt(buffer.ptr), buffer.len, 0);
1336 sqe.rw_flags = flags;1332 sqe.rw_flags = flags;
1337}1333}
13381334
1339pub fn io_uring_prep_recvmsg(1335pub fn io_uring_prep_recvmsg(
1340 sqe: *io_uring_sqe,1336 sqe: *linux.io_uring_sqe,
1341 fd: os.fd_t,1337 fd: os.fd_t,
1342 msg: *os.msghdr,1338 msg: *os.msghdr,
1343 flags: u32,1339 flags: u32,
...@@ -1347,7 +1343,7 @@ pub fn io_uring_prep_recvmsg(...@@ -1347,7 +1343,7 @@ pub fn io_uring_prep_recvmsg(
1347}1343}
13481344
1349pub fn io_uring_prep_sendmsg(1345pub fn io_uring_prep_sendmsg(
1350 sqe: *io_uring_sqe,1346 sqe: *linux.io_uring_sqe,
1351 fd: os.fd_t,1347 fd: os.fd_t,
1352 msg: *const os.msghdr_const,1348 msg: *const os.msghdr_const,
1353 flags: u32,1349 flags: u32,
...@@ -1357,7 +1353,7 @@ pub fn io_uring_prep_sendmsg(...@@ -1357,7 +1353,7 @@ pub fn io_uring_prep_sendmsg(
1357}1353}
13581354
1359pub fn io_uring_prep_openat(1355pub fn io_uring_prep_openat(
1360 sqe: *io_uring_sqe,1356 sqe: *linux.io_uring_sqe,
1361 fd: os.fd_t,1357 fd: os.fd_t,
1362 path: [*:0]const u8,1358 path: [*:0]const u8,
1363 flags: u32,1359 flags: u32,
...@@ -1367,7 +1363,7 @@ pub fn io_uring_prep_openat(...@@ -1367,7 +1363,7 @@ pub fn io_uring_prep_openat(
1367 sqe.rw_flags = flags;1363 sqe.rw_flags = flags;
1368}1364}
13691365
1370pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {1366pub fn io_uring_prep_close(sqe: *linux.io_uring_sqe, fd: os.fd_t) void {
1371 sqe.* = .{1367 sqe.* = .{
1372 .opcode = .CLOSE,1368 .opcode = .CLOSE,
1373 .flags = 0,1369 .flags = 0,
...@@ -1386,7 +1382,7 @@ pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {...@@ -1386,7 +1382,7 @@ pub fn io_uring_prep_close(sqe: *io_uring_sqe, fd: os.fd_t) void {
1386}1382}
13871383
1388pub fn io_uring_prep_timeout(1384pub fn io_uring_prep_timeout(
1389 sqe: *io_uring_sqe,1385 sqe: *linux.io_uring_sqe,
1390 ts: *const os.linux.kernel_timespec,1386 ts: *const os.linux.kernel_timespec,
1391 count: u32,1387 count: u32,
1392 flags: u32,1388 flags: u32,
...@@ -1395,7 +1391,7 @@ pub fn io_uring_prep_timeout(...@@ -1395,7 +1391,7 @@ pub fn io_uring_prep_timeout(
1395 sqe.rw_flags = flags;1391 sqe.rw_flags = flags;
1396}1392}
13971393
1398pub fn io_uring_prep_timeout_remove(sqe: *io_uring_sqe, timeout_user_data: u64, flags: u32) void {1394pub fn io_uring_prep_timeout_remove(sqe: *linux.io_uring_sqe, timeout_user_data: u64, flags: u32) void {
1399 sqe.* = .{1395 sqe.* = .{
1400 .opcode = .TIMEOUT_REMOVE,1396 .opcode = .TIMEOUT_REMOVE,
1401 .flags = 0,1397 .flags = 0,
...@@ -1414,7 +1410,7 @@ pub fn io_uring_prep_timeout_remove(sqe: *io_uring_sqe, timeout_user_data: u64,...@@ -1414,7 +1410,7 @@ pub fn io_uring_prep_timeout_remove(sqe: *io_uring_sqe, timeout_user_data: u64,
1414}1410}
14151411
1416pub fn io_uring_prep_link_timeout(1412pub fn io_uring_prep_link_timeout(
1417 sqe: *io_uring_sqe,1413 sqe: *linux.io_uring_sqe,
1418 ts: *const os.linux.kernel_timespec,1414 ts: *const os.linux.kernel_timespec,
1419 flags: u32,1415 flags: u32,
1420) void {1416) void {
...@@ -1423,7 +1419,7 @@ pub fn io_uring_prep_link_timeout(...@@ -1423,7 +1419,7 @@ pub fn io_uring_prep_link_timeout(
1423}1419}
14241420
1425pub fn io_uring_prep_poll_add(1421pub fn io_uring_prep_poll_add(
1426 sqe: *io_uring_sqe,1422 sqe: *linux.io_uring_sqe,
1427 fd: os.fd_t,1423 fd: os.fd_t,
1428 poll_mask: u32,1424 poll_mask: u32,
1429) void {1425) void {
...@@ -1432,14 +1428,14 @@ pub fn io_uring_prep_poll_add(...@@ -1432,14 +1428,14 @@ pub fn io_uring_prep_poll_add(
1432}1428}
14331429
1434pub fn io_uring_prep_poll_remove(1430pub fn io_uring_prep_poll_remove(
1435 sqe: *io_uring_sqe,1431 sqe: *linux.io_uring_sqe,
1436 target_user_data: u64,1432 target_user_data: u64,
1437) void {1433) void {
1438 io_uring_prep_rw(.POLL_REMOVE, sqe, -1, target_user_data, 0, 0);1434 io_uring_prep_rw(.POLL_REMOVE, sqe, -1, target_user_data, 0, 0);
1439}1435}
14401436
1441pub fn io_uring_prep_poll_update(1437pub fn io_uring_prep_poll_update(
1442 sqe: *io_uring_sqe,1438 sqe: *linux.io_uring_sqe,
1443 old_user_data: u64,1439 old_user_data: u64,
1444 new_user_data: u64,1440 new_user_data: u64,
1445 poll_mask: u32,1441 poll_mask: u32,
...@@ -1450,7 +1446,7 @@ pub fn io_uring_prep_poll_update(...@@ -1450,7 +1446,7 @@ pub fn io_uring_prep_poll_update(
1450}1446}
14511447
1452pub fn io_uring_prep_fallocate(1448pub fn io_uring_prep_fallocate(
1453 sqe: *io_uring_sqe,1449 sqe: *linux.io_uring_sqe,
1454 fd: os.fd_t,1450 fd: os.fd_t,
1455 mode: i32,1451 mode: i32,
1456 offset: u64,1452 offset: u64,
...@@ -1474,7 +1470,7 @@ pub fn io_uring_prep_fallocate(...@@ -1474,7 +1470,7 @@ pub fn io_uring_prep_fallocate(
1474}1470}
14751471
1476pub fn io_uring_prep_statx(1472pub fn io_uring_prep_statx(
1477 sqe: *io_uring_sqe,1473 sqe: *linux.io_uring_sqe,
1478 fd: os.fd_t,1474 fd: os.fd_t,
1479 path: [*:0]const u8,1475 path: [*:0]const u8,
1480 flags: u32,1476 flags: u32,
...@@ -1486,7 +1482,7 @@ pub fn io_uring_prep_statx(...@@ -1486,7 +1482,7 @@ pub fn io_uring_prep_statx(
1486}1482}
14871483
1488pub fn io_uring_prep_cancel(1484pub fn io_uring_prep_cancel(
1489 sqe: *io_uring_sqe,1485 sqe: *linux.io_uring_sqe,
1490 cancel_user_data: u64,1486 cancel_user_data: u64,
1491 flags: u32,1487 flags: u32,
1492) void {1488) void {
...@@ -1495,7 +1491,7 @@ pub fn io_uring_prep_cancel(...@@ -1495,7 +1491,7 @@ pub fn io_uring_prep_cancel(
1495}1491}
14961492
1497pub fn io_uring_prep_shutdown(1493pub fn io_uring_prep_shutdown(
1498 sqe: *io_uring_sqe,1494 sqe: *linux.io_uring_sqe,
1499 sockfd: os.socket_t,1495 sockfd: os.socket_t,
1500 how: u32,1496 how: u32,
1501) void {1497) void {
...@@ -1503,7 +1499,7 @@ pub fn io_uring_prep_shutdown(...@@ -1503,7 +1499,7 @@ pub fn io_uring_prep_shutdown(
1503}1499}
15041500
1505pub fn io_uring_prep_renameat(1501pub fn io_uring_prep_renameat(
1506 sqe: *io_uring_sqe,1502 sqe: *linux.io_uring_sqe,
1507 old_dir_fd: os.fd_t,1503 old_dir_fd: os.fd_t,
1508 old_path: [*:0]const u8,1504 old_path: [*:0]const u8,
1509 new_dir_fd: os.fd_t,1505 new_dir_fd: os.fd_t,
...@@ -1523,7 +1519,7 @@ pub fn io_uring_prep_renameat(...@@ -1523,7 +1519,7 @@ pub fn io_uring_prep_renameat(
1523}1519}
15241520
1525pub fn io_uring_prep_unlinkat(1521pub fn io_uring_prep_unlinkat(
1526 sqe: *io_uring_sqe,1522 sqe: *linux.io_uring_sqe,
1527 dir_fd: os.fd_t,1523 dir_fd: os.fd_t,
1528 path: [*:0]const u8,1524 path: [*:0]const u8,
1529 flags: u32,1525 flags: u32,
...@@ -1533,7 +1529,7 @@ pub fn io_uring_prep_unlinkat(...@@ -1533,7 +1529,7 @@ pub fn io_uring_prep_unlinkat(
1533}1529}
15341530
1535pub fn io_uring_prep_mkdirat(1531pub fn io_uring_prep_mkdirat(
1536 sqe: *io_uring_sqe,1532 sqe: *linux.io_uring_sqe,
1537 dir_fd: os.fd_t,1533 dir_fd: os.fd_t,
1538 path: [*:0]const u8,1534 path: [*:0]const u8,
1539 mode: os.mode_t,1535 mode: os.mode_t,
...@@ -1542,7 +1538,7 @@ pub fn io_uring_prep_mkdirat(...@@ -1542,7 +1538,7 @@ pub fn io_uring_prep_mkdirat(
1542}1538}
15431539
1544pub fn io_uring_prep_symlinkat(1540pub fn io_uring_prep_symlinkat(
1545 sqe: *io_uring_sqe,1541 sqe: *linux.io_uring_sqe,
1546 target: [*:0]const u8,1542 target: [*:0]const u8,
1547 new_dir_fd: os.fd_t,1543 new_dir_fd: os.fd_t,
1548 link_path: [*:0]const u8,1544 link_path: [*:0]const u8,
...@@ -1558,7 +1554,7 @@ pub fn io_uring_prep_symlinkat(...@@ -1558,7 +1554,7 @@ pub fn io_uring_prep_symlinkat(
1558}1554}
15591555
1560pub fn io_uring_prep_linkat(1556pub fn io_uring_prep_linkat(
1561 sqe: *io_uring_sqe,1557 sqe: *linux.io_uring_sqe,
1562 old_dir_fd: os.fd_t,1558 old_dir_fd: os.fd_t,
1563 old_path: [*:0]const u8,1559 old_path: [*:0]const u8,
1564 new_dir_fd: os.fd_t,1560 new_dir_fd: os.fd_t,
...@@ -1578,7 +1574,7 @@ pub fn io_uring_prep_linkat(...@@ -1578,7 +1574,7 @@ pub fn io_uring_prep_linkat(
1578}1574}
15791575
1580pub fn io_uring_prep_provide_buffers(1576pub fn io_uring_prep_provide_buffers(
1581 sqe: *io_uring_sqe,1577 sqe: *linux.io_uring_sqe,
1582 buffers: [*]u8,1578 buffers: [*]u8,
1583 num: usize,1579 num: usize,
1584 buffer_len: usize,1580 buffer_len: usize,
...@@ -1591,7 +1587,7 @@ pub fn io_uring_prep_provide_buffers(...@@ -1591,7 +1587,7 @@ pub fn io_uring_prep_provide_buffers(
1591}1587}
15921588
1593pub fn io_uring_prep_remove_buffers(1589pub fn io_uring_prep_remove_buffers(
1594 sqe: *io_uring_sqe,1590 sqe: *linux.io_uring_sqe,
1595 num: usize,1591 num: usize,
1596 group_id: usize,1592 group_id: usize,
1597) void {1593) void {
...@@ -1602,9 +1598,9 @@ pub fn io_uring_prep_remove_buffers(...@@ -1602,9 +1598,9 @@ pub fn io_uring_prep_remove_buffers(
1602test "structs/offsets/entries" {1598test "structs/offsets/entries" {
1603 if (builtin.os.tag != .linux) return error.SkipZigTest;1599 if (builtin.os.tag != .linux) return error.SkipZigTest;
16041600
1605 try testing.expectEqual(@as(usize, 120), @sizeOf(io_uring_params));1601 try testing.expectEqual(@as(usize, 120), @sizeOf(linux.io_uring_params));
1606 try testing.expectEqual(@as(usize, 64), @sizeOf(io_uring_sqe));1602 try testing.expectEqual(@as(usize, 64), @sizeOf(linux.io_uring_sqe));
1607 try testing.expectEqual(@as(usize, 16), @sizeOf(io_uring_cqe));1603 try testing.expectEqual(@as(usize, 16), @sizeOf(linux.io_uring_cqe));
16081604
1609 try testing.expectEqual(0, linux.IORING_OFF_SQ_RING);1605 try testing.expectEqual(0, linux.IORING_OFF_SQ_RING);
1610 try testing.expectEqual(0x8000000, linux.IORING_OFF_CQ_RING);1606 try testing.expectEqual(0x8000000, linux.IORING_OFF_CQ_RING);
...@@ -1628,7 +1624,7 @@ test "nop" {...@@ -1628,7 +1624,7 @@ test "nop" {
1628 }1624 }
16291625
1630 const sqe = try ring.nop(0xaaaaaaaa);1626 const sqe = try ring.nop(0xaaaaaaaa);
1631 try testing.expectEqual(io_uring_sqe{1627 try testing.expectEqual(linux.io_uring_sqe{
1632 .opcode = .NOP,1628 .opcode = .NOP,
1633 .flags = 0,1629 .flags = 0,
1634 .ioprio = 0,1630 .ioprio = 0,
...@@ -1658,7 +1654,7 @@ test "nop" {...@@ -1658,7 +1654,7 @@ test "nop" {
1658 try testing.expectEqual(@as(u32, 0), ring.cq.head.*);1654 try testing.expectEqual(@as(u32, 0), ring.cq.head.*);
1659 try testing.expectEqual(@as(u32, 0), ring.sq_ready());1655 try testing.expectEqual(@as(u32, 0), ring.sq_ready());
16601656
1661 try testing.expectEqual(io_uring_cqe{1657 try testing.expectEqual(linux.io_uring_cqe{
1662 .user_data = 0xaaaaaaaa,1658 .user_data = 0xaaaaaaaa,
1663 .res = 0,1659 .res = 0,
1664 .flags = 0,1660 .flags = 0,
...@@ -1669,7 +1665,7 @@ test "nop" {...@@ -1669,7 +1665,7 @@ test "nop" {
1669 const sqe_barrier = try ring.nop(0xbbbbbbbb);1665 const sqe_barrier = try ring.nop(0xbbbbbbbb);
1670 sqe_barrier.flags |= linux.IOSQE_IO_DRAIN;1666 sqe_barrier.flags |= linux.IOSQE_IO_DRAIN;
1671 try testing.expectEqual(@as(u32, 1), try ring.submit());1667 try testing.expectEqual(@as(u32, 1), try ring.submit());
1672 try testing.expectEqual(io_uring_cqe{1668 try testing.expectEqual(linux.io_uring_cqe{
1673 .user_data = 0xbbbbbbbb,1669 .user_data = 0xbbbbbbbb,
1674 .res = 0,1670 .res = 0,
1675 .flags = 0,1671 .flags = 0,
...@@ -1909,7 +1905,7 @@ test "openat" {...@@ -1909,7 +1905,7 @@ test "openat" {
1909 const flags: u32 = os.O.CLOEXEC | os.O.RDWR | os.O.CREAT;1905 const flags: u32 = os.O.CLOEXEC | os.O.RDWR | os.O.CREAT;
1910 const mode: os.mode_t = 0o666;1906 const mode: os.mode_t = 0o666;
1911 const sqe_openat = try ring.openat(0x33333333, linux.AT.FDCWD, path, flags, mode);1907 const sqe_openat = try ring.openat(0x33333333, linux.AT.FDCWD, path, flags, mode);
1912 try testing.expectEqual(io_uring_sqe{1908 try testing.expectEqual(linux.io_uring_sqe{
1913 .opcode = .OPENAT,1909 .opcode = .OPENAT,
1914 .flags = 0,1910 .flags = 0,
1915 .ioprio = 0,1911 .ioprio = 0,
lib/std/os/test.zig+4-2
...@@ -766,8 +766,10 @@ test "sigaction" {...@@ -766,8 +766,10 @@ test "sigaction" {
766 }766 }
767 };767 };
768768
769 const actual_handler = if (builtin.zig_backend == .stage1) S.handler else &S.handler;
770
769 var sa = os.Sigaction{771 var sa = os.Sigaction{
770 .handler = .{ .sigaction = S.handler },772 .handler = .{ .sigaction = actual_handler },
771 .mask = os.empty_sigset,773 .mask = os.empty_sigset,
772 .flags = os.SA.SIGINFO | os.SA.RESETHAND,774 .flags = os.SA.SIGINFO | os.SA.RESETHAND,
773 };775 };
...@@ -776,7 +778,7 @@ test "sigaction" {...@@ -776,7 +778,7 @@ test "sigaction" {
776 try os.sigaction(os.SIG.USR1, &sa, null);778 try os.sigaction(os.SIG.USR1, &sa, null);
777 // Check that we can read it back correctly.779 // Check that we can read it back correctly.
778 try os.sigaction(os.SIG.USR1, null, &old_sa);780 try os.sigaction(os.SIG.USR1, null, &old_sa);
779 try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);781 try testing.expectEqual(actual_handler, old_sa.handler.sigaction.?);
780 try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);782 try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);
781 // Invoke the handler.783 // Invoke the handler.
782 try os.raise(os.SIG.USR1);784 try os.raise(os.SIG.USR1);
src/AstGen.zig+9-2
...@@ -291,8 +291,8 @@ pub const ResultLoc = union(enum) {...@@ -291,8 +291,8 @@ pub const ResultLoc = union(enum) {
291 }291 }
292};292};
293293
294pub const align_rl: ResultLoc = .{ .ty = .u16_type };294pub const align_rl: ResultLoc = .{ .ty = .u29_type };
295pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u16_type };295pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u29_type };
296pub const bool_rl: ResultLoc = .{ .ty = .bool_type };296pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
297pub const type_rl: ResultLoc = .{ .ty = .type_type };297pub const type_rl: ResultLoc = .{ .ty = .type_type };
298pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };298pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type };
...@@ -8077,6 +8077,7 @@ const primitives = std.ComptimeStringMap(Zir.Inst.Ref, .{...@@ -8077,6 +8077,7 @@ const primitives = std.ComptimeStringMap(Zir.Inst.Ref, .{
8077 .{ "true", .bool_true },8077 .{ "true", .bool_true },
8078 .{ "type", .type_type },8078 .{ "type", .type_type },
8079 .{ "u16", .u16_type },8079 .{ "u16", .u16_type },
8080 .{ "u29", .u29_type },
8080 .{ "u32", .u32_type },8081 .{ "u32", .u32_type },
8081 .{ "u64", .u64_type },8082 .{ "u64", .u64_type },
8082 .{ "u128", .u128_type },8083 .{ "u128", .u128_type },
...@@ -8749,6 +8750,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In...@@ -8749,6 +8750,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In
8749 .isize_type,8750 .isize_type,
8750 .type_type,8751 .type_type,
8751 .u16_type,8752 .u16_type,
8753 .u29_type,
8752 .u32_type,8754 .u32_type,
8753 .u64_type,8755 .u64_type,
8754 .u128_type,8756 .u128_type,
...@@ -8988,6 +8990,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {...@@ -8988,6 +8990,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
8988 .i8_type,8990 .i8_type,
8989 .isize_type,8991 .isize_type,
8990 .u16_type,8992 .u16_type,
8993 .u29_type,
8991 .u32_type,8994 .u32_type,
8992 .u64_type,8995 .u64_type,
8993 .u128_type,8996 .u128_type,
...@@ -9063,6 +9066,7 @@ fn rvalue(...@@ -9063,6 +9066,7 @@ fn rvalue(
9063 as_ty | @enumToInt(Zir.Inst.Ref.u8_type),9066 as_ty | @enumToInt(Zir.Inst.Ref.u8_type),
9064 as_ty | @enumToInt(Zir.Inst.Ref.i8_type),9067 as_ty | @enumToInt(Zir.Inst.Ref.i8_type),
9065 as_ty | @enumToInt(Zir.Inst.Ref.u16_type),9068 as_ty | @enumToInt(Zir.Inst.Ref.u16_type),
9069 as_ty | @enumToInt(Zir.Inst.Ref.u29_type),
9066 as_ty | @enumToInt(Zir.Inst.Ref.i16_type),9070 as_ty | @enumToInt(Zir.Inst.Ref.i16_type),
9067 as_ty | @enumToInt(Zir.Inst.Ref.u32_type),9071 as_ty | @enumToInt(Zir.Inst.Ref.u32_type),
9068 as_ty | @enumToInt(Zir.Inst.Ref.i32_type),9072 as_ty | @enumToInt(Zir.Inst.Ref.i32_type),
...@@ -9875,6 +9879,9 @@ const GenZir = struct {...@@ -9875,6 +9879,9 @@ const GenZir = struct {
9875 errdefer as_scope.unstack();9879 errdefer as_scope.unstack();
9876 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);9880 as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr);
98779881
9882 // `rl_ty_inst` needs to be set in case the stores to `rl_ptr` are eliminated.
9883 as_scope.rl_ty_inst = dest_type;
9884
9878 return as_scope;9885 return as_scope;
9879 }9886 }
98809887
src/Module.zig+1-1
...@@ -4016,7 +4016,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4016,7 +4016,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4016 try wip_captures.finalize();4016 try wip_captures.finalize();
4017 const src: LazySrcLoc = .{ .node_offset = 0 };4017 const src: LazySrcLoc = .{ .node_offset = 0 };
4018 const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);4018 const decl_tv = try sema.resolveInstValue(&block_scope, src, result_ref);
4019 const decl_align: u16 = blk: {4019 const decl_align: u32 = blk: {
4020 const align_ref = decl.zirAlignRef();4020 const align_ref = decl.zirAlignRef();
4021 if (align_ref == .none) break :blk 0;4021 if (align_ref == .none) break :blk 0;
4022 break :blk try sema.resolveAlign(&block_scope, src, align_ref);4022 break :blk try sema.resolveAlign(&block_scope, src, align_ref);
src/Sema.zig+56-17
...@@ -1739,9 +1739,9 @@ pub fn resolveAlign(...@@ -1739,9 +1739,9 @@ pub fn resolveAlign(
1739 block: *Block,1739 block: *Block,
1740 src: LazySrcLoc,1740 src: LazySrcLoc,
1741 zir_ref: Zir.Inst.Ref,1741 zir_ref: Zir.Inst.Ref,
1742) !u16 {1742) !u32 {
1743 const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u16));1743 const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u29));
1744 const alignment = @intCast(u16, alignment_big); // We coerce to u16 in the prev line.1744 const alignment = @intCast(u32, alignment_big); // We coerce to u16 in the prev line.
1745 if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});1745 if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{});
1746 if (!std.math.isPowerOfTwo(alignment)) {1746 if (!std.math.isPowerOfTwo(alignment)) {
1747 return sema.fail(block, src, "alignment value {d} is not a power of two", .{1747 return sema.fail(block, src, "alignment value {d} is not a power of two", .{
...@@ -1875,7 +1875,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1875,7 +1875,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
18751875
1876 const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));1876 const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));
1877 const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value);1877 const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value);
1878 try sema.storePtr(&trash_block, src, dummy_ptr, dummy_operand);1878 try sema.storePtr2(&trash_block, src, dummy_ptr, src, dummy_operand, src, .bitcast);
18791879
1880 {1880 {
1881 const air_tags = sema.air_instructions.items(.tag);1881 const air_tags = sema.air_instructions.items(.tag);
...@@ -2526,7 +2526,7 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -2526,7 +2526,7 @@ fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2526 const src: LazySrcLoc = .{ .node_offset = inst_data };2526 const src: LazySrcLoc = .{ .node_offset = inst_data };
2527 try sema.requireFunctionBlock(block, src);2527 try sema.requireFunctionBlock(block, src);
25282528
2529 if (block.is_comptime) {2529 if (block.is_comptime or try sema.typeRequiresComptime(block, src, sema.fn_ret_ty)) {
2530 const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty);2530 const fn_ret_ty = try sema.resolveTypeFields(block, src, sema.fn_ret_ty);
2531 return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0, src);2531 return sema.analyzeComptimeAlloc(block, fn_ret_ty, 0, src);
2532 }2532 }
...@@ -2663,7 +2663,7 @@ fn zirAllocExtended(...@@ -2663,7 +2663,7 @@ fn zirAllocExtended(
2663 break :blk try sema.resolveType(block, ty_src, type_ref);2663 break :blk try sema.resolveType(block, ty_src, type_ref);
2664 } else undefined;2664 } else undefined;
26652665
2666 const alignment: u16 = if (small.has_align) blk: {2666 const alignment: u32 = if (small.has_align) blk: {
2667 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);2667 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
2668 extra_index += 1;2668 extra_index += 1;
2669 const alignment = try sema.resolveAlign(block, align_src, align_ref);2669 const alignment = try sema.resolveAlign(block, align_src, align_ref);
...@@ -3616,7 +3616,7 @@ fn zirValidateArrayInit(...@@ -3616,7 +3616,7 @@ fn zirValidateArrayInit(
3616 const air_tags = sema.air_instructions.items(.tag);3616 const air_tags = sema.air_instructions.items(.tag);
3617 const air_datas = sema.air_instructions.items(.data);3617 const air_datas = sema.air_instructions.items(.data);
36183618
3619 for (instrs) |elem_ptr, i| {3619 outer: for (instrs) |elem_ptr, i| {
3620 const elem_ptr_data = sema.code.instructions.items(.data)[elem_ptr].pl_node;3620 const elem_ptr_data = sema.code.instructions.items(.data)[elem_ptr].pl_node;
3621 const elem_src: LazySrcLoc = .{ .node_offset = elem_ptr_data.src_node };3621 const elem_src: LazySrcLoc = .{ .node_offset = elem_ptr_data.src_node };
36223622
...@@ -3630,6 +3630,10 @@ fn zirValidateArrayInit(...@@ -3630,6 +3630,10 @@ fn zirValidateArrayInit(
3630 // of the for loop.3630 // of the for loop.
3631 var block_index = block.instructions.items.len - 1;3631 var block_index = block.instructions.items.len - 1;
3632 while (block.instructions.items[block_index] != elem_ptr_air_inst) {3632 while (block.instructions.items[block_index] != elem_ptr_air_inst) {
3633 if (block_index == 0) {
3634 array_is_comptime = true;
3635 continue :outer;
3636 }
3633 block_index -= 1;3637 block_index -= 1;
3634 }3638 }
3635 first_block_index = @minimum(first_block_index, block_index);3639 first_block_index = @minimum(first_block_index, block_index);
...@@ -3672,6 +3676,13 @@ fn zirValidateArrayInit(...@@ -3672,6 +3676,13 @@ fn zirValidateArrayInit(
3672 }3676 }
36733677
3674 if (array_is_comptime) {3678 if (array_is_comptime) {
3679 if (try sema.resolveDefinedValue(block, init_src, array_ptr)) |ptr_val| {
3680 if (ptr_val.tag() == .comptime_field_ptr) {
3681 // This store was validated by the individual elem ptrs.
3682 return;
3683 }
3684 }
3685
3675 // Our task is to delete all the `elem_ptr` and `store` instructions, and insert3686 // Our task is to delete all the `elem_ptr` and `store` instructions, and insert
3676 // instead a single `store` to the array_ptr with a comptime struct value.3687 // instead a single `store` to the array_ptr with a comptime struct value.
3677 // Also to populate the sentinel value, if any.3688 // Also to populate the sentinel value, if any.
...@@ -14199,7 +14210,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -14199,7 +14210,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
14199 .size = ptr_size,14210 .size = ptr_size,
14200 .mutable = !is_const_val.toBool(),14211 .mutable = !is_const_val.toBool(),
14201 .@"volatile" = is_volatile_val.toBool(),14212 .@"volatile" = is_volatile_val.toBool(),
14202 .@"align" = @intCast(u16, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.14213 .@"align" = @intCast(u29, alignment_val.toUnsignedInt(target)), // TODO: Validate this value.
14203 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),14214 .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
14204 .pointee_type = try child_ty.copy(sema.arena),14215 .pointee_type = try child_ty.copy(sema.arena),
14205 .@"allowzero" = is_allowzero_val.toBool(),14216 .@"allowzero" = is_allowzero_val.toBool(),
...@@ -16973,7 +16984,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -16973,7 +16984,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
16973 const body = sema.code.extra[extra_index..][0..body_len];16984 const body = sema.code.extra[extra_index..][0..body_len];
16974 extra_index += body.len;16985 extra_index += body.len;
1697516986
16976 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u16);16987 const val = try sema.resolveGenericBody(block, align_src, body, inst, Type.u29);
16977 if (val.tag() == .generic_poison) {16988 if (val.tag() == .generic_poison) {
16978 break :blk null;16989 break :blk null;
16979 }16990 }
...@@ -18462,14 +18473,11 @@ fn structFieldPtrByIndex(...@@ -18462,14 +18473,11 @@ fn structFieldPtrByIndex(
18462 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);18473 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
1846318474
18464 if (field.is_comptime) {18475 if (field.is_comptime) {
18465 var anon_decl = try block.startAnonDecl(field_src);18476 const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{
18466 defer anon_decl.deinit();18477 .field_ty = try field.ty.copy(sema.arena),
18467 const decl = try anon_decl.finish(18478 .field_val = try field.default_val.copy(sema.arena),
18468 try field.ty.copy(anon_decl.arena()),18479 });
18469 try field.default_val.copy(anon_decl.arena()),18480 return sema.addConstant(ptr_field_ty, val);
18470 ptr_ty_data.@"align",
18471 );
18472 return sema.analyzeDeclRef(decl);
18473 }18481 }
1847418482
18475 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {18483 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
...@@ -20187,6 +20195,13 @@ fn storePtr2(...@@ -20187,6 +20195,13 @@ fn storePtr2(
2018720195
20188 // TODO handle if the element type requires comptime20196 // TODO handle if the element type requires comptime
2018920197
20198 if (air_tag == .bitcast) {
20199 // `air_tag == .bitcast` is used as a special case for `zirCoerceResultPtr`
20200 // to avoid calling `requireRuntimeBlock` for the dummy block.
20201 _ = try block.addBinOp(.store, ptr, operand);
20202 return;
20203 }
20204
20190 try sema.requireRuntimeBlock(block, runtime_src);20205 try sema.requireRuntimeBlock(block, runtime_src);
20191 try sema.queueFullTypeResolution(elem_ty);20206 try sema.queueFullTypeResolution(elem_ty);
20192 _ = try block.addBinOp(air_tag, ptr, operand);20207 _ = try block.addBinOp(air_tag, ptr, operand);
...@@ -20240,6 +20255,14 @@ fn storePtrVal(...@@ -20240,6 +20255,14 @@ fn storePtrVal(
2024020255
20241 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);20256 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
2024220257
20258 if (mut_kit.decl_ref_mut.runtime_index == std.math.maxInt(u32)) {
20259 // Special case for comptime field ptr.
20260 if (!mut_kit.val.eql(bitcasted_val, mut_kit.ty, sema.mod)) {
20261 return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{});
20262 }
20263 return;
20264 }
20265
20243 const arena = mut_kit.beginArena(sema.mod);20266 const arena = mut_kit.beginArena(sema.mod);
20244 defer mut_kit.finishArena(sema.mod);20267 defer mut_kit.finishArena(sema.mod);
2024520268
...@@ -20289,6 +20312,19 @@ fn beginComptimePtrMutation(...@@ -20289,6 +20312,19 @@ fn beginComptimePtrMutation(
20289 .ty = decl.ty,20312 .ty = decl.ty,
20290 };20313 };
20291 },20314 },
20315 .comptime_field_ptr => {
20316 const payload = ptr_val.castTag(.comptime_field_ptr).?.data;
20317 const duped = try sema.arena.create(Value);
20318 duped.* = payload.field_val;
20319 return ComptimePtrMutationKit{
20320 .decl_ref_mut = .{
20321 .decl_index = @intToEnum(Module.Decl.Index, 0),
20322 .runtime_index = std.math.maxInt(u32),
20323 },
20324 .val = duped,
20325 .ty = payload.field_ty,
20326 };
20327 },
20292 .elem_ptr => {20328 .elem_ptr => {
20293 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;20329 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
20294 var parent = try beginComptimePtrMutation(sema, block, src, elem_ptr.array_ptr);20330 var parent = try beginComptimePtrMutation(sema, block, src, elem_ptr.array_ptr);
...@@ -23850,6 +23886,7 @@ pub fn typeHasOnePossibleValue(...@@ -23850,6 +23886,7 @@ pub fn typeHasOnePossibleValue(
23850 .i8,23886 .i8,
23851 .u16,23887 .u16,
23852 .i16,23888 .i16,
23889 .u29,
23853 .u32,23890 .u32,
23854 .i32,23891 .i32,
23855 .u64,23892 .u64,
...@@ -24143,6 +24180,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {...@@ -24143,6 +24180,7 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
24143 .u8 => return .u8_type,24180 .u8 => return .u8_type,
24144 .i8 => return .i8_type,24181 .i8 => return .i8_type,
24145 .u16 => return .u16_type,24182 .u16 => return .u16_type,
24183 .u29 => return .u29_type,
24146 .i16 => return .i16_type,24184 .i16 => return .i16_type,
24147 .u32 => return .u32_type,24185 .u32 => return .u32_type,
24148 .i32 => return .i32_type,24186 .i32 => return .i32_type,
...@@ -24513,6 +24551,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ...@@ -24513,6 +24551,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
24513 .i8,24551 .i8,
24514 .u16,24552 .u16,
24515 .i16,24553 .i16,
24554 .u29,
24516 .u32,24555 .u32,
24517 .i32,24556 .i32,
24518 .u64,24557 .u64,
src/TypedValue.zig+11
...@@ -79,6 +79,7 @@ pub fn print(...@@ -79,6 +79,7 @@ pub fn print(
79 .i8_type => return writer.writeAll("i8"),79 .i8_type => return writer.writeAll("i8"),
80 .u16_type => return writer.writeAll("u16"),80 .u16_type => return writer.writeAll("u16"),
81 .i16_type => return writer.writeAll("i16"),81 .i16_type => return writer.writeAll("i16"),
82 .u29_type => return writer.writeAll("u29"),
82 .u32_type => return writer.writeAll("u32"),83 .u32_type => return writer.writeAll("u32"),
83 .i32_type => return writer.writeAll("i32"),84 .i32_type => return writer.writeAll("i32"),
84 .u64_type => return writer.writeAll("u64"),85 .u64_type => return writer.writeAll("u64"),
...@@ -264,6 +265,16 @@ pub fn print(...@@ -264,6 +265,16 @@ pub fn print(
264 .val = decl.val,265 .val = decl.val,
265 }, writer, level - 1, mod);266 }, writer, level - 1, mod);
266 },267 },
268 .comptime_field_ptr => {
269 const payload = val.castTag(.comptime_field_ptr).?.data;
270 if (level == 0) {
271 return writer.writeAll("(comptime field ptr)");
272 }
273 return print(.{
274 .ty = payload.field_ty,
275 .val = payload.field_val,
276 }, writer, level - 1, mod);
277 },
267 .elem_ptr => {278 .elem_ptr => {
268 const elem_ptr = val.castTag(.elem_ptr).?.data;279 const elem_ptr = val.castTag(.elem_ptr).?.data;
269 try writer.writeAll("&");280 try writer.writeAll("&");
src/Zir.zig+5
...@@ -1961,6 +1961,7 @@ pub const Inst = struct {...@@ -1961,6 +1961,7 @@ pub const Inst = struct {
1961 i8_type,1961 i8_type,
1962 u16_type,1962 u16_type,
1963 i16_type,1963 i16_type,
1964 u29_type,
1964 u32_type,1965 u32_type,
1965 i32_type,1966 i32_type,
1966 u64_type,1967 u64_type,
...@@ -2072,6 +2073,10 @@ pub const Inst = struct {...@@ -2072,6 +2073,10 @@ pub const Inst = struct {
2072 .ty = Type.initTag(.type),2073 .ty = Type.initTag(.type),
2073 .val = Value.initTag(.i16_type),2074 .val = Value.initTag(.i16_type),
2074 },2075 },
2076 .u29_type = .{
2077 .ty = Type.initTag(.type),
2078 .val = Value.initTag(.u29_type),
2079 },
2075 .u32_type = .{2080 .u32_type = .{
2076 .ty = Type.initTag(.type),2081 .ty = Type.initTag(.type),
2077 .val = Value.initTag(.u32_type),2082 .val = Value.initTag(.u32_type),
src/type.zig+20
...@@ -36,6 +36,7 @@ pub const Type = extern union {...@@ -36,6 +36,7 @@ pub const Type = extern union {
36 .i8,36 .i8,
37 .u16,37 .u16,
38 .i16,38 .i16,
39 .u29,
39 .u32,40 .u32,
40 .i32,41 .i32,
41 .u64,42 .u64,
...@@ -568,6 +569,7 @@ pub const Type = extern union {...@@ -568,6 +569,7 @@ pub const Type = extern union {
568 .i8,569 .i8,
569 .u16,570 .u16,
570 .i16,571 .i16,
572 .u29,
571 .u32,573 .u32,
572 .i32,574 .i32,
573 .u64,575 .u64,
...@@ -979,6 +981,7 @@ pub const Type = extern union {...@@ -979,6 +981,7 @@ pub const Type = extern union {
979 .i8,981 .i8,
980 .u16,982 .u16,
981 .i16,983 .i16,
984 .u29,
982 .u32,985 .u32,
983 .i32,986 .i32,
984 .u64,987 .u64,
...@@ -1261,6 +1264,7 @@ pub const Type = extern union {...@@ -1261,6 +1264,7 @@ pub const Type = extern union {
1261 .i8,1264 .i8,
1262 .u16,1265 .u16,
1263 .i16,1266 .i16,
1267 .u29,
1264 .u32,1268 .u32,
1265 .i32,1269 .i32,
1266 .u64,1270 .u64,
...@@ -1551,6 +1555,7 @@ pub const Type = extern union {...@@ -1551,6 +1555,7 @@ pub const Type = extern union {
1551 .i8,1555 .i8,
1552 .u16,1556 .u16,
1553 .i16,1557 .i16,
1558 .u29,
1554 .u32,1559 .u32,
1555 .i32,1560 .i32,
1556 .u64,1561 .u64,
...@@ -1935,6 +1940,7 @@ pub const Type = extern union {...@@ -1935,6 +1940,7 @@ pub const Type = extern union {
1935 .i8,1940 .i8,
1936 .u16,1941 .u16,
1937 .i16,1942 .i16,
1943 .u29,
1938 .u32,1944 .u32,
1939 .i32,1945 .i32,
1940 .u64,1946 .u64,
...@@ -2235,6 +2241,7 @@ pub const Type = extern union {...@@ -2235,6 +2241,7 @@ pub const Type = extern union {
2235 .u8 => return Value.initTag(.u8_type),2241 .u8 => return Value.initTag(.u8_type),
2236 .i8 => return Value.initTag(.i8_type),2242 .i8 => return Value.initTag(.i8_type),
2237 .u16 => return Value.initTag(.u16_type),2243 .u16 => return Value.initTag(.u16_type),
2244 .u29 => return Value.initTag(.u29_type),
2238 .i16 => return Value.initTag(.i16_type),2245 .i16 => return Value.initTag(.i16_type),
2239 .u32 => return Value.initTag(.u32_type),2246 .u32 => return Value.initTag(.u32_type),
2240 .i32 => return Value.initTag(.i32_type),2247 .i32 => return Value.initTag(.i32_type),
...@@ -2312,6 +2319,7 @@ pub const Type = extern union {...@@ -2312,6 +2319,7 @@ pub const Type = extern union {
2312 .i8,2319 .i8,
2313 .u16,2320 .u16,
2314 .i16,2321 .i16,
2322 .u29,
2315 .u32,2323 .u32,
2316 .i32,2324 .i32,
2317 .u64,2325 .u64,
...@@ -2560,6 +2568,7 @@ pub const Type = extern union {...@@ -2560,6 +2568,7 @@ pub const Type = extern union {
2560 .i8,2568 .i8,
2561 .u16,2569 .u16,
2562 .i16,2570 .i16,
2571 .u29,
2563 .u32,2572 .u32,
2564 .i32,2573 .i32,
2565 .u64,2574 .u64,
...@@ -2953,6 +2962,7 @@ pub const Type = extern union {...@@ -2953,6 +2962,7 @@ pub const Type = extern union {
2953 .vector => return AbiAlignmentAdvanced{ .scalar = 16 },2962 .vector => return AbiAlignmentAdvanced{ .scalar = 16 },
29542963
2955 .i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },2964 .i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },
2965 .u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
2956 .i32, .u32 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(32, target) },2966 .i32, .u32 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(32, target) },
2957 .i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },2967 .i64, .u64 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(64, target) },
2958 .u128, .i128 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(128, target) },2968 .u128, .i128 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(128, target) },
...@@ -3416,6 +3426,7 @@ pub const Type = extern union {...@@ -3416,6 +3426,7 @@ pub const Type = extern union {
3416 },3426 },
34173427
3418 .i16, .u16 => return AbiSizeAdvanced{ .scalar = intAbiSize(16, target) },3428 .i16, .u16 => return AbiSizeAdvanced{ .scalar = intAbiSize(16, target) },
3429 .u29 => return AbiSizeAdvanced{ .scalar = intAbiSize(29, target) },
3419 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },3430 .i32, .u32 => return AbiSizeAdvanced{ .scalar = intAbiSize(32, target) },
3420 .i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },3431 .i64, .u64 => return AbiSizeAdvanced{ .scalar = intAbiSize(64, target) },
3421 .u128, .i128 => return AbiSizeAdvanced{ .scalar = intAbiSize(128, target) },3432 .u128, .i128 => return AbiSizeAdvanced{ .scalar = intAbiSize(128, target) },
...@@ -3569,6 +3580,7 @@ pub const Type = extern union {...@@ -3569,6 +3580,7 @@ pub const Type = extern union {
3569 .bool, .u1 => 1,3580 .bool, .u1 => 1,
3570 .u8, .i8 => 8,3581 .u8, .i8 => 8,
3571 .i16, .u16, .f16 => 16,3582 .i16, .u16, .f16 => 16,
3583 .u29 => 29,
3572 .i32, .u32, .f32 => 32,3584 .i32, .u32, .f32 => 32,
3573 .i64, .u64, .f64 => 64,3585 .i64, .u64, .f64 => 64,
3574 .f80 => 80,3586 .f80 => 80,
...@@ -4524,6 +4536,7 @@ pub const Type = extern union {...@@ -4524,6 +4536,7 @@ pub const Type = extern union {
4524 .u1,4536 .u1,
4525 .u8,4537 .u8,
4526 .u16,4538 .u16,
4539 .u29,
4527 .u32,4540 .u32,
4528 .u64,4541 .u64,
4529 .u128,4542 .u128,
...@@ -4550,6 +4563,7 @@ pub const Type = extern union {...@@ -4550,6 +4563,7 @@ pub const Type = extern union {
4550 .i8 => return .{ .signedness = .signed, .bits = 8 },4563 .i8 => return .{ .signedness = .signed, .bits = 8 },
4551 .u16 => return .{ .signedness = .unsigned, .bits = 16 },4564 .u16 => return .{ .signedness = .unsigned, .bits = 16 },
4552 .i16 => return .{ .signedness = .signed, .bits = 16 },4565 .i16 => return .{ .signedness = .signed, .bits = 16 },
4566 .u29 => return .{ .signedness = .unsigned, .bits = 29 },
4553 .u32 => return .{ .signedness = .unsigned, .bits = 32 },4567 .u32 => return .{ .signedness = .unsigned, .bits = 32 },
4554 .i32 => return .{ .signedness = .signed, .bits = 32 },4568 .i32 => return .{ .signedness = .signed, .bits = 32 },
4555 .u64 => return .{ .signedness = .unsigned, .bits = 64 },4569 .u64 => return .{ .signedness = .unsigned, .bits = 64 },
...@@ -4814,6 +4828,7 @@ pub const Type = extern union {...@@ -4814,6 +4828,7 @@ pub const Type = extern union {
4814 .i8,4828 .i8,
4815 .u16,4829 .u16,
4816 .i16,4830 .i16,
4831 .u29,
4817 .u32,4832 .u32,
4818 .i32,4833 .i32,
4819 .u64,4834 .u64,
...@@ -4856,6 +4871,7 @@ pub const Type = extern union {...@@ -4856,6 +4871,7 @@ pub const Type = extern union {
4856 .i8,4871 .i8,
4857 .u16,4872 .u16,
4858 .i16,4873 .i16,
4874 .u29,
4859 .u32,4875 .u32,
4860 .i32,4876 .i32,
4861 .u64,4877 .u64,
...@@ -5072,6 +5088,7 @@ pub const Type = extern union {...@@ -5072,6 +5088,7 @@ pub const Type = extern union {
5072 .i8,5088 .i8,
5073 .u16,5089 .u16,
5074 .i16,5090 .i16,
5091 .u29,
5075 .u32,5092 .u32,
5076 .i32,5093 .i32,
5077 .u64,5094 .u64,
...@@ -5816,6 +5833,7 @@ pub const Type = extern union {...@@ -5816,6 +5833,7 @@ pub const Type = extern union {
5816 i8,5833 i8,
5817 u16,5834 u16,
5818 i16,5835 i16,
5836 u29,
5819 u32,5837 u32,
5820 i32,5838 i32,
5821 u64,5839 u64,
...@@ -5939,6 +5957,7 @@ pub const Type = extern union {...@@ -5939,6 +5957,7 @@ pub const Type = extern union {
5939 .i8,5957 .i8,
5940 .u16,5958 .u16,
5941 .i16,5959 .i16,
5960 .u29,
5942 .u32,5961 .u32,
5943 .i32,5962 .i32,
5944 .u64,5963 .u64,
...@@ -6302,6 +6321,7 @@ pub const Type = extern union {...@@ -6302,6 +6321,7 @@ pub const Type = extern union {
6302 pub const @"u1" = initTag(.u1);6321 pub const @"u1" = initTag(.u1);
6303 pub const @"u8" = initTag(.u8);6322 pub const @"u8" = initTag(.u8);
6304 pub const @"u16" = initTag(.u16);6323 pub const @"u16" = initTag(.u16);
6324 pub const @"u29" = initTag(.u29);
6305 pub const @"u32" = initTag(.u32);6325 pub const @"u32" = initTag(.u32);
6306 pub const @"u64" = initTag(.u64);6326 pub const @"u64" = initTag(.u64);
63076327
src/value.zig+50-4
...@@ -30,6 +30,7 @@ pub const Value = extern union {...@@ -30,6 +30,7 @@ pub const Value = extern union {
30 i8_type,30 i8_type,
31 u16_type,31 u16_type,
32 i16_type,32 i16_type,
33 u29_type,
33 u32_type,34 u32_type,
34 i32_type,35 i32_type,
35 u64_type,36 u64_type,
...@@ -120,6 +121,8 @@ pub const Value = extern union {...@@ -120,6 +121,8 @@ pub const Value = extern union {
120 /// This Tag will never be seen by machine codegen backends. It is changed into a121 /// This Tag will never be seen by machine codegen backends. It is changed into a
121 /// `decl_ref` when a comptime variable goes out of scope.122 /// `decl_ref` when a comptime variable goes out of scope.
122 decl_ref_mut,123 decl_ref_mut,
124 /// Behaves like `decl_ref_mut` but validates that the stored value matches the field value.
125 comptime_field_ptr,
123 /// Pointer to a specific element of an array, vector or slice.126 /// Pointer to a specific element of an array, vector or slice.
124 elem_ptr,127 elem_ptr,
125 /// Pointer to a specific field of a struct or union.128 /// Pointer to a specific field of a struct or union.
...@@ -194,6 +197,7 @@ pub const Value = extern union {...@@ -194,6 +197,7 @@ pub const Value = extern union {
194 .i8_type,197 .i8_type,
195 .u16_type,198 .u16_type,
196 .i16_type,199 .i16_type,
200 .u29_type,
197 .u32_type,201 .u32_type,
198 .i32_type,202 .i32_type,
199 .u64_type,203 .u64_type,
...@@ -316,6 +320,7 @@ pub const Value = extern union {...@@ -316,6 +320,7 @@ pub const Value = extern union {
316 .aggregate => Payload.Aggregate,320 .aggregate => Payload.Aggregate,
317 .@"union" => Payload.Union,321 .@"union" => Payload.Union,
318 .bound_fn => Payload.BoundFn,322 .bound_fn => Payload.BoundFn,
323 .comptime_field_ptr => Payload.ComptimeFieldPtr,
319 };324 };
320 }325 }
321326
...@@ -394,6 +399,7 @@ pub const Value = extern union {...@@ -394,6 +399,7 @@ pub const Value = extern union {
394 .i8_type,399 .i8_type,
395 .u16_type,400 .u16_type,
396 .i16_type,401 .i16_type,
402 .u29_type,
397 .u32_type,403 .u32_type,
398 .i32_type,404 .i32_type,
399 .u64_type,405 .u64_type,
...@@ -506,6 +512,18 @@ pub const Value = extern union {...@@ -506,6 +512,18 @@ pub const Value = extern union {
506 };512 };
507 return Value{ .ptr_otherwise = &new_payload.base };513 return Value{ .ptr_otherwise = &new_payload.base };
508 },514 },
515 .comptime_field_ptr => {
516 const payload = self.cast(Payload.ComptimeFieldPtr).?;
517 const new_payload = try arena.create(Payload.ComptimeFieldPtr);
518 new_payload.* = .{
519 .base = payload.base,
520 .data = .{
521 .field_val = try payload.data.field_val.copy(arena),
522 .field_ty = try payload.data.field_ty.copy(arena),
523 },
524 };
525 return Value{ .ptr_otherwise = &new_payload.base };
526 },
509 .elem_ptr => {527 .elem_ptr => {
510 const payload = self.castTag(.elem_ptr).?;528 const payload = self.castTag(.elem_ptr).?;
511 const new_payload = try arena.create(Payload.ElemPtr);529 const new_payload = try arena.create(Payload.ElemPtr);
...@@ -645,6 +663,7 @@ pub const Value = extern union {...@@ -645,6 +663,7 @@ pub const Value = extern union {
645 .u8_type => return out_stream.writeAll("u8"),663 .u8_type => return out_stream.writeAll("u8"),
646 .i8_type => return out_stream.writeAll("i8"),664 .i8_type => return out_stream.writeAll("i8"),
647 .u16_type => return out_stream.writeAll("u16"),665 .u16_type => return out_stream.writeAll("u16"),
666 .u29_type => return out_stream.writeAll("u29"),
648 .i16_type => return out_stream.writeAll("i16"),667 .i16_type => return out_stream.writeAll("i16"),
649 .u32_type => return out_stream.writeAll("u32"),668 .u32_type => return out_stream.writeAll("u32"),
650 .i32_type => return out_stream.writeAll("i32"),669 .i32_type => return out_stream.writeAll("i32"),
...@@ -754,6 +773,9 @@ pub const Value = extern union {...@@ -754,6 +773,9 @@ pub const Value = extern union {
754 const decl_index = val.castTag(.decl_ref).?.data;773 const decl_index = val.castTag(.decl_ref).?.data;
755 return out_stream.print("(decl_ref {d})", .{decl_index});774 return out_stream.print("(decl_ref {d})", .{decl_index});
756 },775 },
776 .comptime_field_ptr => {
777 return out_stream.writeAll("(comptime_field_ptr)");
778 },
757 .elem_ptr => {779 .elem_ptr => {
758 const elem_ptr = val.castTag(.elem_ptr).?.data;780 const elem_ptr = val.castTag(.elem_ptr).?.data;
759 try out_stream.print("&[{}] ", .{elem_ptr.index});781 try out_stream.print("&[{}] ", .{elem_ptr.index});
...@@ -882,6 +904,7 @@ pub const Value = extern union {...@@ -882,6 +904,7 @@ pub const Value = extern union {
882 .i8_type => Type.initTag(.i8),904 .i8_type => Type.initTag(.i8),
883 .u16_type => Type.initTag(.u16),905 .u16_type => Type.initTag(.u16),
884 .i16_type => Type.initTag(.i16),906 .i16_type => Type.initTag(.i16),
907 .u29_type => Type.initTag(.u29),
885 .u32_type => Type.initTag(.u32),908 .u32_type => Type.initTag(.u32),
886 .i32_type => Type.initTag(.i32),909 .i32_type => Type.initTag(.i32),
887 .u64_type => Type.initTag(.u64),910 .u64_type => Type.initTag(.u64),
...@@ -1706,6 +1729,7 @@ pub const Value = extern union {...@@ -1706,6 +1729,7 @@ pub const Value = extern union {
1706 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),1729 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
17071730
1708 .decl_ref_mut,1731 .decl_ref_mut,
1732 .comptime_field_ptr,
1709 .extern_fn,1733 .extern_fn,
1710 .decl_ref,1734 .decl_ref,
1711 .function,1735 .function,
...@@ -1770,6 +1794,7 @@ pub const Value = extern union {...@@ -1770,6 +1794,7 @@ pub const Value = extern union {
1770 .bool_true,1794 .bool_true,
1771 .decl_ref,1795 .decl_ref,
1772 .decl_ref_mut,1796 .decl_ref_mut,
1797 .comptime_field_ptr,
1773 .extern_fn,1798 .extern_fn,
1774 .function,1799 .function,
1775 .variable,1800 .variable,
...@@ -2362,7 +2387,7 @@ pub const Value = extern union {...@@ -2362,7 +2387,7 @@ pub const Value = extern union {
23622387
2363 pub fn isComptimeMutablePtr(val: Value) bool {2388 pub fn isComptimeMutablePtr(val: Value) bool {
2364 return switch (val.tag()) {2389 return switch (val.tag()) {
2365 .decl_ref_mut => true,2390 .decl_ref_mut, .comptime_field_ptr => true,
2366 .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),2391 .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
2367 .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),2392 .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
2368 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),2393 .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
...@@ -2426,6 +2451,9 @@ pub const Value = extern union {...@@ -2426,6 +2451,9 @@ pub const Value = extern union {
2426 const decl: Module.Decl.Index = ptr_val.pointerDecl().?;2451 const decl: Module.Decl.Index = ptr_val.pointerDecl().?;
2427 std.hash.autoHash(hasher, decl);2452 std.hash.autoHash(hasher, decl);
2428 },2453 },
2454 .comptime_field_ptr => {
2455 std.hash.autoHash(hasher, Value.Tag.comptime_field_ptr);
2456 },
24292457
2430 .elem_ptr => {2458 .elem_ptr => {
2431 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;2459 const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
...@@ -2471,7 +2499,7 @@ pub const Value = extern union {...@@ -2471,7 +2499,7 @@ pub const Value = extern union {
2471 return switch (val.tag()) {2499 return switch (val.tag()) {
2472 .slice => val.castTag(.slice).?.data.ptr,2500 .slice => val.castTag(.slice).?.data.ptr,
2473 // TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc.2501 // TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc.
2474 .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr => val,2502 .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr, .comptime_field_ptr => val,
2475 else => unreachable,2503 else => unreachable,
2476 };2504 };
2477 }2505 }
...@@ -2497,6 +2525,14 @@ pub const Value = extern union {...@@ -2497,6 +2525,14 @@ pub const Value = extern union {
2497 return 1;2525 return 1;
2498 }2526 }
2499 },2527 },
2528 .comptime_field_ptr => {
2529 const payload = val.castTag(.comptime_field_ptr).?.data;
2530 if (payload.field_ty.zigTypeTag() == .Array) {
2531 return payload.field_ty.arrayLen();
2532 } else {
2533 return 1;
2534 }
2535 },
2500 else => unreachable,2536 else => unreachable,
2501 };2537 };
2502 }2538 }
...@@ -2587,6 +2623,7 @@ pub const Value = extern union {...@@ -2587,6 +2623,7 @@ pub const Value = extern union {
25872623
2588 .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer),2624 .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer),
2589 .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer),2625 .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer),
2626 .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValueAdvanced(mod, index, arena, buffer),
2590 .elem_ptr => {2627 .elem_ptr => {
2591 const data = val.castTag(.elem_ptr).?.data;2628 const data = val.castTag(.elem_ptr).?.data;
2592 return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer);2629 return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer);
...@@ -2623,6 +2660,7 @@ pub const Value = extern union {...@@ -2623,6 +2660,7 @@ pub const Value = extern union {
26232660
2624 .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end),2661 .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end),
2625 .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end),2662 .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end),
2663 .comptime_field_ptr => sliceArray(val.castTag(.comptime_field_ptr).?.data.field_val, mod, arena, start, end),
2626 .elem_ptr => blk: {2664 .elem_ptr => blk: {
2627 const elem_ptr = val.castTag(.elem_ptr).?.data;2665 const elem_ptr = val.castTag(.elem_ptr).?.data;
2628 break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index);2666 break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index);
...@@ -4742,6 +4780,14 @@ pub const Value = extern union {...@@ -4742,6 +4780,14 @@ pub const Value = extern union {
4742 },4780 },
4743 };4781 };
47444782
4783 pub const ComptimeFieldPtr = struct {
4784 base: Payload,
4785 data: struct {
4786 field_val: Value,
4787 field_ty: Type,
4788 },
4789 };
4790
4745 pub const ElemPtr = struct {4791 pub const ElemPtr = struct {
4746 pub const base_tag = Tag.elem_ptr;4792 pub const base_tag = Tag.elem_ptr;
47474793
...@@ -4864,7 +4910,7 @@ pub const Value = extern union {...@@ -4864,7 +4910,7 @@ pub const Value = extern union {
4864 /// `Module.resolvePeerTypes`.4910 /// `Module.resolvePeerTypes`.
4865 stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},4911 stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},
4866 /// 0 means ABI-aligned.4912 /// 0 means ABI-aligned.
4867 alignment: u16,4913 alignment: u32,
4868 },4914 },
4869 };4915 };
48704916
...@@ -4875,7 +4921,7 @@ pub const Value = extern union {...@@ -4875,7 +4921,7 @@ pub const Value = extern union {
4875 data: struct {4921 data: struct {
4876 decl_index: Module.Decl.Index,4922 decl_index: Module.Decl.Index,
4877 /// 0 means ABI-aligned.4923 /// 0 means ABI-aligned.
4878 alignment: u16,4924 alignment: u32,
4879 },4925 },
4880 };4926 };
48814927
test/behavior/basic.zig+33
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const assert = std.debug.assert;
3const mem = std.mem;4const mem = std.mem;
4const expect = std.testing.expect;5const expect = std.testing.expect;
5const expectEqualStrings = std.testing.expectEqualStrings;6const expectEqualStrings = std.testing.expectEqualStrings;
...@@ -1053,3 +1054,35 @@ test "const alloc with comptime known initializer is made comptime known" {...@@ -1053,3 +1054,35 @@ test "const alloc with comptime known initializer is made comptime known" {
1053 if (u.a == 0) @compileError("bad");1054 if (u.a == 0) @compileError("bad");
1054 }1055 }
1055}1056}
1057
1058comptime {
1059 // coerce result ptr outside a function
1060 const S = struct { a: comptime_int };
1061 var s: S = undefined;
1062 s = S{ .a = 1 };
1063 assert(s.a == 1);
1064}
1065
1066test "switch inside @as gets correct type" {
1067 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1068 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1069
1070 var a: u32 = 0;
1071 var b: [2]u32 = undefined;
1072 b[0] = @as(u32, switch (a) {
1073 1 => 1,
1074 else => 0,
1075 });
1076}
1077
1078test "inline call of function with a switch inside the return statement" {
1079 const S = struct {
1080 inline fn foo(x: anytype) @TypeOf(x) {
1081 return switch (x) {
1082 1 => 1,
1083 else => unreachable,
1084 };
1085 }
1086 };
1087 try expect(S.foo(1) == 1);
1088}
test/behavior/struct.zig+22
...@@ -1336,3 +1336,25 @@ test "packed struct field access via pointer" {...@@ -1336,3 +1336,25 @@ test "packed struct field access via pointer" {
1336 try S.doTheTest();1336 try S.doTheTest();
1337 comptime try S.doTheTest();1337 comptime try S.doTheTest();
1338}1338}
1339
1340test "store to comptime field" {
1341 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
1342
1343 {
1344 const S = struct {
1345 comptime a: [2]u32 = [2]u32{ 1, 2 },
1346 };
1347 var s: S = .{};
1348 s.a = [2]u32{ 1, 2 };
1349 s.a[0] = 1;
1350 }
1351 {
1352 const T = struct { a: u32, b: u32 };
1353 const S = struct {
1354 comptime a: T = T{ .a = 1, .b = 2 },
1355 };
1356 var s: S = .{};
1357 s.a = T{ .a = 1, .b = 2 };
1358 s.a.a = 1;
1359 }
1360}
test/cases/compile_errors/invalid_store_to_comptime_field.zig created+20
...@@ -0,0 +1,20 @@
1pub export fn entry() void {
2 const S = struct {
3 comptime a: [2]u32 = [2]u32{ 1, 2 },
4 };
5 var s: S = .{};
6 s.a = [2]u32{ 2, 2 };
7}
8pub export fn entry1() void {
9 const T = struct { a: u32, b: u32 };
10 const S = struct {
11 comptime a: T = T{ .a = 1, .b = 2 },
12 };
13 var s: S = .{};
14 s.a = T{ .a = 2, .b = 2 };
15}
16// error
17// backend=stage2,llvm
18//
19// :6:19: error: value stored in comptime field does not match the default value of the field
20// :14:19: error: value stored in comptime field does not match the default value of the field