| author | |
| committer | |
| log | 10c97c26d964ea70230341468e05fdea533a77a3 |
| tree | 56d96f2d1298bc437aca6769e2127792d994de83 |
| parent | 6d2c8349c53707f9eeee7554bd7717667718ce4d |
| signature |
16 files changed, 276 insertions(+), 218 deletions(-)
lib/std/Build/Configuration.zig+4-2| ... | @@ -3215,7 +3215,8 @@ pub const Storage = enum { | ... | @@ -3215,7 +3215,8 @@ pub const Storage = enum { |
| 3215 | .@"extern" => { | 3215 | .@"extern" => { |
| 3216 | const n = @divExact(@sizeOf(Field), @sizeOf(u32)); | 3216 | const n = @divExact(@sizeOf(Field), @sizeOf(u32)); |
| 3217 | defer i.* += n; | 3217 | defer i.* += n; |
| 3218 | return @bitCast(buffer[i.*..][0..n].*); | 3218 | const ptr: *align(@alignOf(u32)) const Field = @ptrCast(buffer[i.*..][0..n]); |
| 3219 | return ptr.*; | ||
| 3219 | }, | 3220 | }, |
| 3220 | }, | 3221 | }, |
| 3221 | else => comptime unreachable, | 3222 | else => comptime unreachable, |
| ... | @@ -3381,7 +3382,8 @@ pub const Storage = enum { | ... | @@ -3381,7 +3382,8 @@ pub const Storage = enum { |
| 3381 | }, | 3382 | }, |
| 3382 | .@"extern" => { | 3383 | .@"extern" => { |
| 3383 | const n = @divExact(@sizeOf(Field), @sizeOf(u32)); | 3384 | const n = @divExact(@sizeOf(Field), @sizeOf(u32)); |
| 3384 | buffer[i..][0..n].* = @bitCast(value); | 3385 | const ptr: *align(@alignOf(Field)) const [n]u32 = @ptrCast(&value); |
| 3386 | buffer[i..][0..n].* = ptr.*; | ||
| 3385 | return n; | 3387 | return n; |
| 3386 | }, | 3388 | }, |
| 3387 | }, | 3389 | }, |
lib/std/Io/Threaded.zig+6-2| ... | @@ -14188,9 +14188,11 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so | ... | @@ -14188,9 +14188,11 @@ fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.so |
| 14188 | } | 14188 | } |
| 14189 | 14189 | ||
| 14190 | fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address { | 14190 | fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address { |
| 14191 | // The network byte order address in `in.addr` is already the byte order we want. | ||
| 14192 | const addr_bytes: *const [4]u8 = @ptrCast(&in.addr); | ||
| 14191 | return .{ | 14193 | return .{ |
| 14192 | .port = std.mem.bigToNative(u16, in.port), | 14194 | .port = std.mem.bigToNative(u16, in.port), |
| 14193 | .bytes = @bitCast(in.addr), | 14195 | .bytes = addr_bytes.*, |
| 14194 | }; | 14196 | }; |
| 14195 | } | 14197 | } |
| 14196 | 14198 | ||
| ... | @@ -14204,9 +14206,11 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address { | ... | @@ -14204,9 +14206,11 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address { |
| 14204 | } | 14206 | } |
| 14205 | 14207 | ||
| 14206 | fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in { | 14208 | fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in { |
| 14209 | // The byte order of `a.bytes` is already equivalent to a network byte order address. | ||
| 14210 | const addr_raw: *align(1) const u32 = @ptrCast(&a.bytes); | ||
| 14207 | return .{ | 14211 | return .{ |
| 14208 | .port = std.mem.nativeToBig(u16, a.port), | 14212 | .port = std.mem.nativeToBig(u16, a.port), |
| 14209 | .addr = @bitCast(a.bytes), | 14213 | .addr = addr_raw.*, |
| 14210 | }; | 14214 | }; |
| 14211 | } | 14215 | } |
| 14212 | 14216 |
lib/std/Io/net.zig+1-5| ... | @@ -592,11 +592,7 @@ pub const Ip6Address = struct { | ... | @@ -592,11 +592,7 @@ pub const Ip6Address = struct { |
| 592 | if (remaining != 0) return .incomplete; | 592 | if (remaining != 0) return .incomplete; |
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | // Workaround that can be removed when this proposal is | 595 | for (&parts) |*part| part.* = @byteSwap(part.*); |
| 596 | // implemented https://github.com/ziglang/zig/issues/19755 | ||
| 597 | if ((comptime @import("builtin").cpu.arch.endian()) != .big) { | ||
| 598 | for (&parts) |*part| part.* = @byteSwap(part.*); | ||
| 599 | } | ||
| 600 | 596 | ||
| 601 | return .{ .success = .{ | 597 | return .{ .success = .{ |
| 602 | .bytes = @bitCast(parts), | 598 | .bytes = @bitCast(parts), |
lib/std/Random/RomuTrio.zig+2-2| ... | @@ -33,7 +33,7 @@ fn next(self: *RomuTrio) u64 { | ... | @@ -33,7 +33,7 @@ fn next(self: *RomuTrio) u64 { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | pub fn seedWithBuf(self: *RomuTrio, buf: [24]u8) void { | 35 | pub fn seedWithBuf(self: *RomuTrio, buf: [24]u8) void { |
| 36 | const seed_buf = @as([3]u64, @bitCast(buf)); | 36 | const seed_buf: [3]u64 = @bitCast(buf); |
| 37 | self.x_state = seed_buf[0]; | 37 | self.x_state = seed_buf[0]; |
| 38 | self.y_state = seed_buf[1]; | 38 | self.y_state = seed_buf[1]; |
| 39 | self.z_state = seed_buf[2]; | 39 | self.z_state = seed_buf[2]; |
| ... | @@ -121,7 +121,7 @@ test fill { | ... | @@ -121,7 +121,7 @@ test fill { |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | test "buf seeding test" { | 123 | test "buf seeding test" { |
| 124 | const buf0 = @as([24]u8, @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 })); | 124 | const buf0: [24]u8 = @bitCast([3]u64{ 16294208416658607535, 13964609475759908645, 4703697494102998476 }); |
| 125 | const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 }; | 125 | const resulting_state = .{ .x = 16294208416658607535, .y = 13964609475759908645, .z = 4703697494102998476 }; |
| 126 | var r = RomuTrio.init(0); | 126 | var r = RomuTrio.init(0); |
| 127 | r.seedWithBuf(buf0); | 127 | r.seedWithBuf(buf0); |
lib/std/Random/Xoshiro256.zig+2-2| ... | @@ -46,12 +46,12 @@ pub fn jump(self: *Xoshiro256) void { | ... | @@ -46,12 +46,12 @@ pub fn jump(self: *Xoshiro256) void { |
| 46 | 46 | ||
| 47 | while (table != 0) : (table >>= 1) { | 47 | while (table != 0) : (table >>= 1) { |
| 48 | if (@as(u1, @truncate(table)) != 0) { | 48 | if (@as(u1, @truncate(table)) != 0) { |
| 49 | s ^= @as(u256, @bitCast(self.s)); | 49 | s ^= @bitCast(self.s); |
| 50 | } | 50 | } |
| 51 | _ = self.next(); | 51 | _ = self.next(); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | self.s = @as([4]u64, @bitCast(s)); | 54 | self.s = @bitCast(s); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | pub fn seed(self: *Xoshiro256, init_s: u64) void { | 57 | pub fn seed(self: *Xoshiro256, init_s: u64) void { |
lib/std/crypto/tls/Client.zig+5-5| ... | @@ -376,7 +376,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -376,7 +376,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 376 | const nonce = nonce: { | 376 | const nonce = nonce: { |
| 377 | const V = @Vector(P.AEAD.nonce_length, u8); | 377 | const V = @Vector(P.AEAD.nonce_length, u8); |
| 378 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); | 378 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); |
| 379 | const operand: V = pad ++ @as([8]u8, @bitCast(big(read_seq))); | 379 | const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(read_seq))); |
| 380 | break :nonce @as(V, pv.server_handshake_iv) ^ operand; | 380 | break :nonce @as(V, pv.server_handshake_iv) ^ operand; |
| 381 | }; | 381 | }; |
| 382 | P.AEAD.decrypt(cleartext, ciphertext, auth_tag, record_header, nonce, pv.server_handshake_key) catch | 382 | P.AEAD.decrypt(cleartext, ciphertext, auth_tag, record_header, nonce, pv.server_handshake_key) catch |
| ... | @@ -416,7 +416,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -416,7 +416,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 416 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { | 416 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { |
| 417 | const V = @Vector(P.AEAD.nonce_length, u8); | 417 | const V = @Vector(P.AEAD.nonce_length, u8); |
| 418 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); | 418 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); |
| 419 | const operand: V = pad ++ @as([8]u8, @bitCast(big(masked_read_seq))); | 419 | const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(masked_read_seq))); |
| 420 | break :nonce @as(V, pv.app_cipher.server_write_IV ++ record_iv) ^ operand; | 420 | break :nonce @as(V, pv.app_cipher.server_write_IV ++ record_iv) ^ operand; |
| 421 | }; | 421 | }; |
| 422 | const ciphertext = record_decoder.slice(message_len); | 422 | const ciphertext = record_decoder.slice(message_len); |
| ... | @@ -792,7 +792,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client | ... | @@ -792,7 +792,7 @@ pub fn init(input: *Reader, output: *Writer, options: Options) InitError!Client |
| 792 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { | 792 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { |
| 793 | const V = @Vector(P.AEAD.nonce_length, u8); | 793 | const V = @Vector(P.AEAD.nonce_length, u8); |
| 794 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); | 794 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); |
| 795 | const operand: V = pad ++ @as([8]u8, @bitCast(big(write_seq))); | 795 | const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(write_seq))); |
| 796 | break :nonce @as(V, pv.app_cipher.client_write_IV ++ pv.app_cipher.client_salt) ^ operand; | 796 | break :nonce @as(V, pv.app_cipher.client_write_IV ++ pv.app_cipher.client_salt) ^ operand; |
| 797 | }; | 797 | }; |
| 798 | var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++ | 798 | var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++ |
| ... | @@ -1105,7 +1105,7 @@ fn prepareCiphertextRecord( | ... | @@ -1105,7 +1105,7 @@ fn prepareCiphertextRecord( |
| 1105 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { | 1105 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { |
| 1106 | const V = @Vector(P.AEAD.nonce_length, u8); | 1106 | const V = @Vector(P.AEAD.nonce_length, u8); |
| 1107 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); | 1107 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); |
| 1108 | const operand: V = pad ++ @as([8]u8, @bitCast(big(c.write_seq))); | 1108 | const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(c.write_seq))); |
| 1109 | break :nonce @as(V, pv.client_write_IV ++ pv.client_salt) ^ operand; | 1109 | break :nonce @as(V, pv.client_write_IV ++ pv.client_salt) ^ operand; |
| 1110 | }; | 1110 | }; |
| 1111 | record_iv.* = nonce[P.fixed_iv_length..].*; | 1111 | record_iv.* = nonce[P.fixed_iv_length..].*; |
| ... | @@ -1214,7 +1214,7 @@ fn readIndirect(c: *Client) Reader.Error!usize { | ... | @@ -1214,7 +1214,7 @@ fn readIndirect(c: *Client) Reader.Error!usize { |
| 1214 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { | 1214 | const nonce: [P.AEAD.nonce_length]u8 = nonce: { |
| 1215 | const V = @Vector(P.AEAD.nonce_length, u8); | 1215 | const V = @Vector(P.AEAD.nonce_length, u8); |
| 1216 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); | 1216 | const pad: [P.AEAD.nonce_length - 8]u8 = @splat(0); |
| 1217 | const operand: V = pad ++ @as([8]u8, @bitCast(big(masked_read_seq))); | 1217 | const operand: V = pad ++ @as([8]u8, @bitCast(@byteSwap(masked_read_seq))); |
| 1218 | break :nonce @as(V, pv.server_write_IV ++ record_iv) ^ operand; | 1218 | break :nonce @as(V, pv.server_write_IV ++ record_iv) ^ operand; |
| 1219 | }; | 1219 | }; |
| 1220 | const ciphertext = input.take(message_len) catch unreachable; // already peeked | 1220 | const ciphertext = input.take(message_len) catch unreachable; // already peeked |
lib/std/hash/xxhash.zig+65-56| ... | @@ -421,7 +421,18 @@ pub const XxHash32 = struct { | ... | @@ -421,7 +421,18 @@ pub const XxHash32 = struct { |
| 421 | }; | 421 | }; |
| 422 | 422 | ||
| 423 | pub const XxHash3 = struct { | 423 | pub const XxHash3 = struct { |
| 424 | const block_bytes = 64; | ||
| 424 | const Block = @Vector(8, u64); | 425 | const Block = @Vector(8, u64); |
| 426 | const InputBlock = extern struct { | ||
| 427 | raw: [block_bytes]u8, | ||
| 428 | inline fn load(ptr: *const InputBlock) Block { | ||
| 429 | return @bitCast(ptr.raw); | ||
| 430 | } | ||
| 431 | inline fn store(ptr: *InputBlock, val: Block) void { | ||
| 432 | ptr.raw = @bitCast(val); | ||
| 433 | } | ||
| 434 | }; | ||
| 435 | |||
| 425 | const default_secret: [192]u8 = .{ | 436 | const default_secret: [192]u8 = .{ |
| 426 | 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, | 437 | 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, |
| 427 | 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, | 438 | 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, |
| ... | @@ -464,10 +475,6 @@ pub const XxHash3 = struct { | ... | @@ -464,10 +475,6 @@ pub const XxHash3 = struct { |
| 464 | return wide[0] ^ wide[1]; | 475 | return wide[0] ^ wide[1]; |
| 465 | } | 476 | } |
| 466 | 477 | ||
| 467 | inline fn swap(x: anytype) @TypeOf(x) { | ||
| 468 | return if (native_endian == .big) @byteSwap(x) else x; | ||
| 469 | } | ||
| 470 | |||
| 471 | inline fn disableAutoVectorization(x: anytype) void { | 478 | inline fn disableAutoVectorization(x: anytype) void { |
| 472 | if (!@inComptime()) asm volatile ("" | 479 | if (!@inComptime()) asm volatile ("" |
| 473 | : | 480 | : |
| ... | @@ -476,20 +483,20 @@ pub const XxHash3 = struct { | ... | @@ -476,20 +483,20 @@ pub const XxHash3 = struct { |
| 476 | } | 483 | } |
| 477 | 484 | ||
| 478 | inline fn mix16(seed: u64, input: []const u8, secret: []const u8) u64 { | 485 | inline fn mix16(seed: u64, input: []const u8, secret: []const u8) u64 { |
| 479 | const blk: [4]u64 = @bitCast([_][16]u8{ input[0..16].*, secret[0..16].* }); | 486 | const blk: [4]u64 = @bitCast([2][16]u8{ input[0..16].*, secret[0..16].* }); |
| 480 | disableAutoVectorization(seed); | 487 | disableAutoVectorization(seed); |
| 481 | 488 | ||
| 482 | return fold( | 489 | return fold( |
| 483 | swap(blk[0]) ^ (swap(blk[2]) +% seed), | 490 | blk[0] ^ (blk[2] +% seed), |
| 484 | swap(blk[1]) ^ (swap(blk[3]) -% seed), | 491 | blk[1] ^ (blk[3] -% seed), |
| 485 | ); | 492 | ); |
| 486 | } | 493 | } |
| 487 | 494 | ||
| 488 | const Accumulator = extern struct { | 495 | const Accumulator = struct { |
| 489 | consumed: usize = 0, | 496 | consumed: usize = 0, |
| 490 | seed: u64, | 497 | seed: u64, |
| 491 | secret: [192]u8 = undefined, | 498 | secret: [192]u8, |
| 492 | state: Block = Block{ | 499 | state: Block = .{ |
| 493 | XxHash32.prime_3, | 500 | XxHash32.prime_3, |
| 494 | XxHash64.prime_1, | 501 | XxHash64.prime_1, |
| 495 | XxHash64.prime_2, | 502 | XxHash64.prime_2, |
| ... | @@ -501,33 +508,35 @@ pub const XxHash3 = struct { | ... | @@ -501,33 +508,35 @@ pub const XxHash3 = struct { |
| 501 | }, | 508 | }, |
| 502 | 509 | ||
| 503 | inline fn init(seed: u64) Accumulator { | 510 | inline fn init(seed: u64) Accumulator { |
| 504 | var self = Accumulator{ .seed = seed }; | 511 | const seed_block: Block = .{ |
| 505 | for ( | 512 | seed, @as(u64, 0) -% seed, |
| 506 | std.mem.bytesAsSlice(Block, &self.secret), | 513 | seed, @as(u64, 0) -% seed, |
| 507 | std.mem.bytesAsSlice(Block, &default_secret), | 514 | seed, @as(u64, 0) -% seed, |
| 508 | ) |*dst, src| { | 515 | seed, @as(u64, 0) -% seed, |
| 509 | dst.* = swap(swap(src) +% Block{ | 516 | }; |
| 510 | seed, @as(u64, 0) -% seed, | 517 | |
| 511 | seed, @as(u64, 0) -% seed, | 518 | var secret: [192]u8 = undefined; |
| 512 | seed, @as(u64, 0) -% seed, | 519 | const secret_blocks: []InputBlock = @ptrCast(&secret); |
| 513 | seed, @as(u64, 0) -% seed, | 520 | const default_secret_blocks: []const InputBlock = @ptrCast(&default_secret); |
| 514 | }); | 521 | for (secret_blocks, default_secret_blocks) |*dst, *src| { |
| 522 | dst.store(src.load() +% seed_block); | ||
| 515 | } | 523 | } |
| 516 | return self; | 524 | |
| 525 | return .{ .seed = seed, .secret = secret }; | ||
| 517 | } | 526 | } |
| 518 | 527 | ||
| 519 | inline fn round( | 528 | inline fn round( |
| 520 | noalias state: *Block, | 529 | noalias state: *Block, |
| 521 | noalias input_block: *align(1) const Block, | 530 | noalias input_block: *const InputBlock, |
| 522 | noalias secret_block: *align(1) const Block, | 531 | noalias secret_block: *const InputBlock, |
| 523 | ) void { | 532 | ) void { |
| 524 | const data = swap(input_block.*); | 533 | const data = input_block.load(); |
| 525 | const mixed = data ^ swap(secret_block.*); | 534 | const mixed = data ^ secret_block.load(); |
| 526 | state.* +%= (mixed & @as(Block, @splat(0xffffffff))) *% (mixed >> @splat(32)); | 535 | state.* +%= (mixed & @as(Block, @splat(0xffffffff))) *% (mixed >> @splat(32)); |
| 527 | state.* +%= @shuffle(u64, data, undefined, [_]i32{ 1, 0, 3, 2, 5, 4, 7, 6 }); | 536 | state.* +%= @shuffle(u64, data, undefined, [_]i32{ 1, 0, 3, 2, 5, 4, 7, 6 }); |
| 528 | } | 537 | } |
| 529 | 538 | ||
| 530 | fn accumulate(noalias self: *Accumulator, blocks: []align(1) const Block) void { | 539 | fn accumulate(noalias self: *Accumulator, blocks: []const InputBlock) void { |
| 531 | const secret = std.mem.bytesAsSlice(u64, self.secret[self.consumed * 8 ..]); | 540 | const secret = std.mem.bytesAsSlice(u64, self.secret[self.consumed * 8 ..]); |
| 532 | for (blocks, secret[0..blocks.len]) |*input_block, *secret_block| { | 541 | for (blocks, secret[0..blocks.len]) |*input_block, *secret_block| { |
| 533 | @prefetch(@as([*]const u8, @ptrCast(input_block)) + 320, .{}); | 542 | @prefetch(@as([*]const u8, @ptrCast(input_block)) + 320, .{}); |
| ... | @@ -536,14 +545,14 @@ pub const XxHash3 = struct { | ... | @@ -536,14 +545,14 @@ pub const XxHash3 = struct { |
| 536 | } | 545 | } |
| 537 | 546 | ||
| 538 | fn scramble(self: *Accumulator) void { | 547 | fn scramble(self: *Accumulator) void { |
| 539 | const secret_block: Block = @bitCast(self.secret[192 - @sizeOf(Block) .. 192].*); | 548 | const secret_block: Block = @bitCast(self.secret[192 - block_bytes .. 192].*); |
| 540 | self.state ^= self.state >> @splat(47); | 549 | self.state ^= self.state >> @splat(47); |
| 541 | self.state ^= swap(secret_block); | 550 | self.state ^= secret_block; |
| 542 | self.state *%= @as(Block, @splat(XxHash32.prime_1)); | 551 | self.state *%= @as(Block, @splat(XxHash32.prime_1)); |
| 543 | } | 552 | } |
| 544 | 553 | ||
| 545 | fn consume(noalias self: *Accumulator, input_blocks: []align(1) const Block) void { | 554 | fn consume(noalias self: *Accumulator, input_blocks: []const InputBlock) void { |
| 546 | const blocks_per_scramble = 1024 / @sizeOf(Block); | 555 | const blocks_per_scramble = 1024 / block_bytes; |
| 547 | std.debug.assert(self.consumed <= blocks_per_scramble); | 556 | std.debug.assert(self.consumed <= blocks_per_scramble); |
| 548 | 557 | ||
| 549 | var blocks = input_blocks; | 558 | var blocks = input_blocks; |
| ... | @@ -561,12 +570,12 @@ pub const XxHash3 = struct { | ... | @@ -561,12 +570,12 @@ pub const XxHash3 = struct { |
| 561 | self.consumed += blocks.len; | 570 | self.consumed += blocks.len; |
| 562 | } | 571 | } |
| 563 | 572 | ||
| 564 | fn digest(noalias self: *Accumulator, total_len: u64, noalias last_block: *align(1) const Block) u64 { | 573 | fn digest(noalias self: *Accumulator, total_len: u64, noalias last_block: *const InputBlock) u64 { |
| 565 | const secret_block = self.secret[192 - @sizeOf(Block) - 7 ..][0..@sizeOf(Block)]; | 574 | const secret_block = self.secret[192 - block_bytes - 7 ..][0..block_bytes]; |
| 566 | round(&self.state, last_block, @ptrCast(secret_block)); | 575 | round(&self.state, last_block, @ptrCast(secret_block)); |
| 567 | 576 | ||
| 568 | const merge_block: Block = @bitCast(self.secret[11 .. 11 + @sizeOf(Block)].*); | 577 | const merge_block: Block = @bitCast(self.secret[11 .. 11 + block_bytes].*); |
| 569 | self.state ^= swap(merge_block); | 578 | self.state ^= merge_block; |
| 570 | 579 | ||
| 571 | var result = XxHash64.prime_1 *% total_len; | 580 | var result = XxHash64.prime_1 *% total_len; |
| 572 | inline for (0..4) |i| { | 581 | inline for (0..4) |i| { |
| ... | @@ -588,7 +597,7 @@ pub const XxHash3 = struct { | ... | @@ -588,7 +597,7 @@ pub const XxHash3 = struct { |
| 588 | if (input.len > 0) return hash3(seed, input, secret); | 597 | if (input.len > 0) return hash3(seed, input, secret); |
| 589 | 598 | ||
| 590 | const flip: [2]u64 = @bitCast(secret[56..72].*); | 599 | const flip: [2]u64 = @bitCast(secret[56..72].*); |
| 591 | const key = swap(flip[0]) ^ swap(flip[1]); | 600 | const key = flip[0] ^ flip[1]; |
| 592 | return avalanche(.h64, seed ^ key); | 601 | return avalanche(.h64, seed ^ key); |
| 593 | } | 602 | } |
| 594 | 603 | ||
| ... | @@ -604,8 +613,8 @@ pub const XxHash3 = struct { | ... | @@ -604,8 +613,8 @@ pub const XxHash3 = struct { |
| 604 | input[input.len / 2], | 613 | input[input.len / 2], |
| 605 | }); | 614 | }); |
| 606 | 615 | ||
| 607 | const key = @as(u64, swap(flip[0]) ^ swap(flip[1])) +% seed; | 616 | const key = @as(u64, flip[0] ^ flip[1]) +% seed; |
| 608 | return avalanche(.h64, key ^ swap(blk)); | 617 | return avalanche(.h64, key ^ blk); |
| 609 | } | 618 | } |
| 610 | 619 | ||
| 611 | fn hash8(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 { | 620 | fn hash8(seed: u64, input: anytype, noalias secret: *const [192]u8) u64 { |
| ... | @@ -619,8 +628,8 @@ pub const XxHash3 = struct { | ... | @@ -619,8 +628,8 @@ pub const XxHash3 = struct { |
| 619 | }); | 628 | }); |
| 620 | 629 | ||
| 621 | const mixed = seed ^ (@as(u64, @byteSwap(@as(u32, @truncate(seed)))) << 32); | 630 | const mixed = seed ^ (@as(u64, @byteSwap(@as(u32, @truncate(seed)))) << 32); |
| 622 | const key = (swap(flip[0]) ^ swap(flip[1])) -% mixed; | 631 | const key = (flip[0] ^ flip[1]) -% mixed; |
| 623 | const combined = (@as(u64, swap(blk[0])) << 32) +% swap(blk[1]); | 632 | const combined = (@as(u64, blk[0]) << 32) +% blk[1]; |
| 624 | return avalanche(.{ .rrmxmx = input.len }, key ^ combined); | 633 | return avalanche(.{ .rrmxmx = input.len }, key ^ combined); |
| 625 | } | 634 | } |
| 626 | 635 | ||
| ... | @@ -634,8 +643,8 @@ pub const XxHash3 = struct { | ... | @@ -634,8 +643,8 @@ pub const XxHash3 = struct { |
| 634 | input[input.len - 8 ..][0..8].*, | 643 | input[input.len - 8 ..][0..8].*, |
| 635 | }); | 644 | }); |
| 636 | 645 | ||
| 637 | const lo = swap(blk[0]) ^ ((swap(flip[0]) ^ swap(flip[1])) +% seed); | 646 | const lo = blk[0] ^ ((flip[0] ^ flip[1]) +% seed); |
| 638 | const hi = swap(blk[1]) ^ ((swap(flip[2]) ^ swap(flip[3])) -% seed); | 647 | const hi = blk[1] ^ ((flip[2] ^ flip[3]) -% seed); |
| 639 | const combined = @as(u64, input.len) +% @byteSwap(lo) +% hi +% fold(lo, hi); | 648 | const combined = @as(u64, input.len) +% @byteSwap(lo) +% hi +% fold(lo, hi); |
| 640 | return avalanche(.h3, combined); | 649 | return avalanche(.h3, combined); |
| 641 | } | 650 | } |
| ... | @@ -679,11 +688,11 @@ pub const XxHash3 = struct { | ... | @@ -679,11 +688,11 @@ pub const XxHash3 = struct { |
| 679 | @branchHint(.unlikely); | 688 | @branchHint(.unlikely); |
| 680 | std.debug.assert(input.len >= 240); | 689 | std.debug.assert(input.len >= 240); |
| 681 | 690 | ||
| 682 | const block_count = ((input.len - 1) / @sizeOf(Block)) * @sizeOf(Block); | 691 | const block_count = ((input.len - 1) / block_bytes) * block_bytes; |
| 683 | const last_block = input[input.len - @sizeOf(Block) ..][0..@sizeOf(Block)]; | 692 | const last_block = input[input.len - block_bytes ..][0..block_bytes]; |
| 684 | 693 | ||
| 685 | var acc = Accumulator.init(seed); | 694 | var acc = Accumulator.init(seed); |
| 686 | acc.consume(std.mem.bytesAsSlice(Block, input[0..block_count])); | 695 | acc.consume(std.mem.bytesAsSlice(InputBlock, input[0..block_count])); |
| 687 | return acc.digest(input.len, @ptrCast(last_block)); | 696 | return acc.digest(input.len, @ptrCast(last_block)); |
| 688 | } | 697 | } |
| 689 | 698 | ||
| ... | @@ -716,21 +725,21 @@ pub const XxHash3 = struct { | ... | @@ -716,21 +725,21 @@ pub const XxHash3 = struct { |
| 716 | @memcpy(self.buffer[self.buffered..], consumable[0..remaining]); | 725 | @memcpy(self.buffer[self.buffered..], consumable[0..remaining]); |
| 717 | consumable = consumable[remaining..]; | 726 | consumable = consumable[remaining..]; |
| 718 | 727 | ||
| 719 | self.accumulator.consume(std.mem.bytesAsSlice(Block, &self.buffer)); | 728 | self.accumulator.consume(std.mem.bytesAsSlice(InputBlock, &self.buffer)); |
| 720 | self.buffered = 0; | 729 | self.buffered = 0; |
| 721 | } | 730 | } |
| 722 | 731 | ||
| 723 | // The input isn't small enough to fit in the buffer. Consume it directly. | 732 | // The input isn't small enough to fit in the buffer. Consume it directly. |
| 724 | if (consumable.len > self.buffer.len) { | 733 | if (consumable.len > self.buffer.len) { |
| 725 | const block_count = ((consumable.len - 1) / @sizeOf(Block)) * @sizeOf(Block); | 734 | const block_count = ((consumable.len - 1) / block_bytes) * block_bytes; |
| 726 | self.accumulator.consume(std.mem.bytesAsSlice(Block, consumable[0..block_count])); | 735 | self.accumulator.consume(std.mem.bytesAsSlice(InputBlock, consumable[0..block_count])); |
| 727 | consumable = consumable[block_count..]; | 736 | consumable = consumable[block_count..]; |
| 728 | 737 | ||
| 729 | // In case we consume all remaining input, write the last block to end of the buffer | 738 | // In case we consume all remaining input, write the last block to end of the buffer |
| 730 | // to populate the last_block_copy in final() similar to hashLong()'s last_block. | 739 | // to populate the last_block_copy in final() similar to hashLong()'s last_block. |
| 731 | @memcpy( | 740 | @memcpy( |
| 732 | self.buffer[self.buffer.len - @sizeOf(Block) .. self.buffer.len], | 741 | self.buffer[self.buffer.len - block_bytes .. self.buffer.len], |
| 733 | (consumable.ptr - @sizeOf(Block))[0..@sizeOf(Block)], | 742 | (consumable.ptr - block_bytes)[0..block_bytes], |
| 734 | ); | 743 | ); |
| 735 | } | 744 | } |
| 736 | 745 | ||
| ... | @@ -751,16 +760,16 @@ pub const XxHash3 = struct { | ... | @@ -751,16 +760,16 @@ pub const XxHash3 = struct { |
| 751 | 760 | ||
| 752 | // Make a copy of the Accumulator state in case `self` needs to update() / be used later. | 761 | // Make a copy of the Accumulator state in case `self` needs to update() / be used later. |
| 753 | var accumulator_copy = self.accumulator; | 762 | var accumulator_copy = self.accumulator; |
| 754 | var last_block_copy: [@sizeOf(Block)]u8 = undefined; | 763 | var last_block_copy: [block_bytes]u8 = undefined; |
| 755 | 764 | ||
| 756 | // Digest the last block onthe Accumulator copy. | 765 | // Digest the last block onthe Accumulator copy. |
| 757 | return accumulator_copy.digest(self.total_len, last_block: { | 766 | return accumulator_copy.digest(self.total_len, last_block: { |
| 758 | if (self.buffered >= @sizeOf(Block)) { | 767 | if (self.buffered >= block_bytes) { |
| 759 | const block_count = ((self.buffered - 1) / @sizeOf(Block)) * @sizeOf(Block); | 768 | const block_count = ((self.buffered - 1) / block_bytes) * block_bytes; |
| 760 | accumulator_copy.consume(std.mem.bytesAsSlice(Block, self.buffer[0..block_count])); | 769 | accumulator_copy.consume(std.mem.bytesAsSlice(InputBlock, self.buffer[0..block_count])); |
| 761 | break :last_block @ptrCast(self.buffer[self.buffered - @sizeOf(Block) ..][0..@sizeOf(Block)]); | 770 | break :last_block @ptrCast(self.buffer[self.buffered - block_bytes ..][0..block_bytes]); |
| 762 | } else { | 771 | } else { |
| 763 | const remaining = @sizeOf(Block) - self.buffered; | 772 | const remaining = block_bytes - self.buffered; |
| 764 | @memcpy(last_block_copy[0..remaining], self.buffer[self.buffer.len - remaining ..][0..remaining]); | 773 | @memcpy(last_block_copy[0..remaining], self.buffer[self.buffer.len - remaining ..][0..remaining]); |
| 765 | @memcpy(last_block_copy[remaining..][0..self.buffered], self.buffer[0..self.buffered]); | 774 | @memcpy(last_block_copy[remaining..][0..self.buffered], self.buffer[0..self.buffered]); |
| 766 | break :last_block @ptrCast(&last_block_copy); | 775 | break :last_block @ptrCast(&last_block_copy); |
lib/std/hash_map.zig+2-2| ... | @@ -593,8 +593,8 @@ fn Custom( | ... | @@ -593,8 +593,8 @@ fn Custom( |
| 593 | fingerprint: FingerPrint = free, | 593 | fingerprint: FingerPrint = free, |
| 594 | used: u1 = 0, | 594 | used: u1 = 0, |
| 595 | 595 | ||
| 596 | const slot_free = @as(u8, @bitCast(Metadata{ .fingerprint = free })); | 596 | const slot_free: u8 = @bitCast(Metadata{ .fingerprint = free }); |
| 597 | const slot_tombstone = @as(u8, @bitCast(Metadata{ .fingerprint = tombstone })); | 597 | const slot_tombstone: u8 = @bitCast(Metadata{ .fingerprint = tombstone }); |
| 598 | 598 | ||
| 599 | pub fn isUsed(self: Metadata) bool { | 599 | pub fn isUsed(self: Metadata) bool { |
| 600 | return self.used == 1; | 600 | return self.used == 1; |
lib/std/http/HeadParser.zig+5-8| ... | @@ -116,11 +116,8 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize { | ... | @@ -116,11 +116,8 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize { |
| 116 | 116 | ||
| 117 | const chunk = bytes[index..][0..vector_len]; | 117 | const chunk = bytes[index..][0..vector_len]; |
| 118 | const v: Vector = chunk.*; | 118 | const v: Vector = chunk.*; |
| 119 | // depends on https://github.com/ziglang/zig/issues/19755 | 119 | const matches_r: BitVector = @bitCast(v == @as(Vector, @splat('\r'))); |
| 120 | // const matches_r: BitVector = @bitCast(v == @as(Vector, @splat('\r'))); | 120 | const matches_n: BitVector = @bitCast(v == @as(Vector, @splat('\n'))); |
| 121 | // const matches_n: BitVector = @bitCast(v == @as(Vector, @splat('\n'))); | ||
| 122 | const matches_r: BitVector = @select(u1, v == @as(Vector, @splat('\r')), @as(Vector, @splat(1)), @as(Vector, @splat(0))); | ||
| 123 | const matches_n: BitVector = @select(u1, v == @as(Vector, @splat('\n')), @as(Vector, @splat(1)), @as(Vector, @splat(0))); | ||
| 124 | const matches_or: SizeVector = matches_r | matches_n; | 121 | const matches_or: SizeVector = matches_r | matches_n; |
| 125 | 122 | ||
| 126 | const matches = @reduce(.Add, matches_or); | 123 | const matches = @reduce(.Add, matches_or); |
| ... | @@ -331,15 +328,15 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize { | ... | @@ -331,15 +328,15 @@ pub fn feed(p: *HeadParser, bytes: []const u8) usize { |
| 331 | } | 328 | } |
| 332 | 329 | ||
| 333 | inline fn int16(array: *const [2]u8) u16 { | 330 | inline fn int16(array: *const [2]u8) u16 { |
| 334 | return @bitCast(array.*); | 331 | return std.mem.toNative(u16, @bitCast(array.*), .little); |
| 335 | } | 332 | } |
| 336 | 333 | ||
| 337 | inline fn int24(array: *const [3]u8) u24 { | 334 | inline fn int24(array: *const [3]u8) u24 { |
| 338 | return @bitCast(array.*); | 335 | return std.mem.toNative(u24, @bitCast(array.*), .little); |
| 339 | } | 336 | } |
| 340 | 337 | ||
| 341 | inline fn int32(array: *const [4]u8) u32 { | 338 | inline fn int32(array: *const [4]u8) u32 { |
| 342 | return @bitCast(array.*); | 339 | return std.mem.toNative(u32, @bitCast(array.*), .little); |
| 343 | } | 340 | } |
| 344 | 341 | ||
| 345 | inline fn intShift(comptime T: type, x: anytype) T { | 342 | inline fn intShift(comptime T: type, x: anytype) T { |
lib/std/http/Server.zig+10-5| ... | @@ -726,7 +726,7 @@ pub const WebSocket = struct { | ... | @@ -726,7 +726,7 @@ pub const WebSocket = struct { |
| 726 | else => @intFromEnum(h1.payload_len), | 726 | else => @intFromEnum(h1.payload_len), |
| 727 | }; | 727 | }; |
| 728 | if (len > in.buffer.len) return error.MessageOversize; | 728 | if (len > in.buffer.len) return error.MessageOversize; |
| 729 | const mask: u32 = @bitCast((try in.takeArray(4)).*); | 729 | const mask: [4]u8 = (try in.takeArray(4)).*; |
| 730 | const payload = try in.take(len); | 730 | const payload = try in.take(len); |
| 731 | 731 | ||
| 732 | // Skip pongs. | 732 | // Skip pongs. |
| ... | @@ -734,11 +734,16 @@ pub const WebSocket = struct { | ... | @@ -734,11 +734,16 @@ pub const WebSocket = struct { |
| 734 | 734 | ||
| 735 | // The last item may contain a partial word of unused data. | 735 | // The last item may contain a partial word of unused data. |
| 736 | const floored_len = (payload.len / 4) * 4; | 736 | const floored_len = (payload.len / 4) * 4; |
| 737 | const u32_payload: []align(1) u32 = @ptrCast(payload[0..floored_len]); | 737 | |
| 738 | for (u32_payload) |*elem| elem.* ^= mask; | 738 | const payload_chunks: [][4]u8 = @ptrCast(payload[0..floored_len]); |
| 739 | const mask_bytes: []const u8 = @ptrCast(&mask); | 739 | for (payload_chunks) |*chunk| { |
| 740 | for (payload[floored_len..], mask_bytes[0 .. payload.len - floored_len]) |*leftover, m| | 740 | const mask_i: u32 = @bitCast(mask); |
| 741 | const chunk_i: u32 = @bitCast(chunk.*); | ||
| 742 | chunk.* = @bitCast(chunk_i ^ mask_i); | ||
| 743 | } | ||
| 744 | for (payload[floored_len..], mask[0 .. payload.len - floored_len]) |*leftover, m| { | ||
| 741 | leftover.* ^= m; | 745 | leftover.* ^= m; |
| 746 | } | ||
| 742 | 747 | ||
| 743 | return .{ | 748 | return .{ |
| 744 | .opcode = h0.opcode, | 749 | .opcode = h0.opcode, |
lib/std/mem.zig+80-58| ... | @@ -1848,18 +1848,18 @@ pub fn readVarPackedInt( | ... | @@ -1848,18 +1848,18 @@ pub fn readVarPackedInt( |
| 1848 | if (@bitSizeOf(T) <= 8) { | 1848 | if (@bitSizeOf(T) <= 8) { |
| 1849 | // These are the same shifts/masks we perform below, but adds `@truncate`/`@intCast` | 1849 | // These are the same shifts/masks we perform below, but adds `@truncate`/`@intCast` |
| 1850 | // where needed since int is smaller than a byte. | 1850 | // where needed since int is smaller than a byte. |
| 1851 | const value = if (read_size == 1) b: { | 1851 | const value: uN = if (read_size == 1) b: { |
| 1852 | break :b @as(uN, @truncate(read_bytes[0] >> bit_shift)); | 1852 | break :b @truncate(read_bytes[0] >> bit_shift); |
| 1853 | } else b: { | 1853 | } else b: { |
| 1854 | const i: u1 = @intFromBool(endian == .big); | 1854 | const i: u1 = @intFromBool(endian == .big); |
| 1855 | const head = @as(uN, @truncate(read_bytes[i] >> bit_shift)); | 1855 | const head: uN = @truncate(read_bytes[i] >> bit_shift); |
| 1856 | const tail_shift = @as(Log2N, @intCast(@as(u4, 8) - bit_shift)); | 1856 | const tail_shift: Log2N = @intCast(@as(u4, 8) - bit_shift); |
| 1857 | const tail = @as(uN, @truncate(read_bytes[1 - i])); | 1857 | const tail: uN = @truncate(read_bytes[1 - i]); |
| 1858 | break :b (tail << tail_shift) | head; | 1858 | break :b (tail << tail_shift) | head; |
| 1859 | }; | 1859 | }; |
| 1860 | switch (signedness) { | 1860 | switch (signedness) { |
| 1861 | .signed => return @as(T, @intCast((@as(iN, @bitCast(value)) << pad) >> pad)), | 1861 | .signed => return @intCast((@as(iN, @bitCast(value)) << pad) >> pad), |
| 1862 | .unsigned => return @as(T, @intCast((@as(uN, @bitCast(value)) << pad) >> pad)), | 1862 | .unsigned => return @intCast((value << pad) >> pad), |
| 1863 | } | 1863 | } |
| 1864 | } | 1864 | } |
| 1865 | 1865 | ||
| ... | @@ -1880,8 +1880,8 @@ pub fn readVarPackedInt( | ... | @@ -1880,8 +1880,8 @@ pub fn readVarPackedInt( |
| 1880 | }, | 1880 | }, |
| 1881 | } | 1881 | } |
| 1882 | switch (signedness) { | 1882 | switch (signedness) { |
| 1883 | .signed => return @as(T, @intCast((@as(iN, @bitCast(int)) << pad) >> pad)), | 1883 | .signed => return @intCast((@as(iN, @bitCast(int)) << pad) >> pad), |
| 1884 | .unsigned => return @as(T, @intCast((@as(uN, @bitCast(int)) << pad) >> pad)), | 1884 | .unsigned => return @intCast((int << pad) >> pad), |
| 1885 | } | 1885 | } |
| 1886 | } | 1886 | } |
| 1887 | 1887 | ||
| ... | @@ -1896,8 +1896,13 @@ test readVarPackedInt { | ... | @@ -1896,8 +1896,13 @@ test readVarPackedInt { |
| 1896 | /// The bit count of T must be evenly divisible by 8. | 1896 | /// The bit count of T must be evenly divisible by 8. |
| 1897 | /// This function cannot fail and cannot cause undefined behavior. | 1897 | /// This function cannot fail and cannot cause undefined behavior. |
| 1898 | pub inline fn readInt(comptime T: type, buffer: *const [@divExact(@typeInfo(T).int.bits, 8)]u8, endian: Endian) T { | 1898 | pub inline fn readInt(comptime T: type, buffer: *const [@divExact(@typeInfo(T).int.bits, 8)]u8, endian: Endian) T { |
| 1899 | const value: T = @bitCast(buffer.*); | 1899 | // Zig's logical bit order aligns with a little-endian byte array, so when reading in big-endian |
| 1900 | return if (endian == native_endian) value else @byteSwap(value); | 1900 | // we must `@byteSwap` the int after we `@bitCast` to it. |
| 1901 | const little_val: T = @bitCast(buffer.*); | ||
| 1902 | return switch (endian) { | ||
| 1903 | .little => little_val, | ||
| 1904 | .big => @byteSwap(little_val), | ||
| 1905 | }; | ||
| 1901 | } | 1906 | } |
| 1902 | 1907 | ||
| 1903 | test readInt { | 1908 | test readInt { |
| ... | @@ -1940,13 +1945,15 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T | ... | @@ -1940,13 +1945,15 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T |
| 1940 | // Read by loading a LoadInt, and then follow it up with a 1-byte read | 1945 | // Read by loading a LoadInt, and then follow it up with a 1-byte read |
| 1941 | // of the tail if bit_offset pushed us over a byte boundary. | 1946 | // of the tail if bit_offset pushed us over a byte boundary. |
| 1942 | const read_bytes = bytes[bit_offset / 8 ..]; | 1947 | const read_bytes = bytes[bit_offset / 8 ..]; |
| 1943 | const val = @as(uN, @truncate(readInt(LoadInt, read_bytes[0..load_size], .little) >> bit_shift)); | 1948 | const val: uN = @truncate(readInt(LoadInt, read_bytes[0..load_size], .little) >> bit_shift); |
| 1944 | if (bit_shift > load_tail_bits) { | 1949 | if (bit_shift > load_tail_bits) { |
| 1945 | const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits)); | 1950 | const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits)); |
| 1946 | const tail_byte = read_bytes[load_size]; | 1951 | const tail_byte = read_bytes[load_size]; |
| 1947 | const tail_truncated = if (bit_count < 8) @as(uN, @truncate(tail_byte)) else @as(uN, tail_byte); | 1952 | const tail_truncated = if (bit_count < 8) @as(uN, @truncate(tail_byte)) else @as(uN, tail_byte); |
| 1948 | return @as(T, @bitCast(val | (tail_truncated << (@as(Log2N, @truncate(bit_count)) -% tail_bits)))); | 1953 | return @bitCast(val | (tail_truncated << (@as(Log2N, @truncate(bit_count)) -% tail_bits))); |
| 1949 | } else return @as(T, @bitCast(val)); | 1954 | } else { |
| 1955 | return @bitCast(val); | ||
| 1956 | } | ||
| 1950 | } | 1957 | } |
| 1951 | 1958 | ||
| 1952 | fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { | 1959 | fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { |
| ... | @@ -1972,8 +1979,10 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { | ... | @@ -1972,8 +1979,10 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { |
| 1972 | if (bit_shift > load_tail_bits) { | 1979 | if (bit_shift > load_tail_bits) { |
| 1973 | const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits)); | 1980 | const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits)); |
| 1974 | const tail_byte = if (bit_count < 8) @as(uN, @truncate(read_bytes[0])) else @as(uN, read_bytes[0]); | 1981 | const tail_byte = if (bit_count < 8) @as(uN, @truncate(read_bytes[0])) else @as(uN, read_bytes[0]); |
| 1975 | return @as(T, @bitCast(val | (tail_byte << (@as(Log2N, @truncate(bit_count)) -% tail_bits)))); | 1982 | return @bitCast(val | (tail_byte << (@as(Log2N, @truncate(bit_count)) -% tail_bits))); |
| 1976 | } else return @as(T, @bitCast(val)); | 1983 | } else { |
| 1984 | return @bitCast(val); | ||
| 1985 | } | ||
| 1977 | } | 1986 | } |
| 1978 | 1987 | ||
| 1979 | /// Loads an integer from packed memory. | 1988 | /// Loads an integer from packed memory. |
| ... | @@ -2011,7 +2020,12 @@ test "comptime read/write int" { | ... | @@ -2011,7 +2020,12 @@ test "comptime read/write int" { |
| 2011 | /// This function always succeeds, has defined behavior for all inputs, but | 2020 | /// This function always succeeds, has defined behavior for all inputs, but |
| 2012 | /// the integer bit width must be divisible by 8. | 2021 | /// the integer bit width must be divisible by 8. |
| 2013 | pub inline fn writeInt(comptime T: type, buffer: *[@divExact(@typeInfo(T).int.bits, 8)]u8, value: T, endian: Endian) void { | 2022 | pub inline fn writeInt(comptime T: type, buffer: *[@divExact(@typeInfo(T).int.bits, 8)]u8, value: T, endian: Endian) void { |
| 2014 | buffer.* = @bitCast(if (endian == native_endian) value else @byteSwap(value)); | 2023 | // Zig's logical bit order aligns with a little-endian byte array, so when writing in big-endian |
| 2024 | // we must `@byteSwap` the int before we `@bitCast` to an array. | ||
| 2025 | buffer.* = switch (endian) { | ||
| 2026 | .little => @bitCast(value), | ||
| 2027 | .big => @bitCast(@byteSwap(value)), | ||
| 2028 | }; | ||
| 2015 | } | 2029 | } |
| 2016 | 2030 | ||
| 2017 | test writeInt { | 2031 | test writeInt { |
| ... | @@ -2209,10 +2223,10 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { | ... | @@ -2209,10 +2223,10 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { |
| 2209 | /// (Changing their endianness) | 2223 | /// (Changing their endianness) |
| 2210 | pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *align(a.toByteUnits()) S) void { | 2224 | pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *align(a.toByteUnits()) S) void { |
| 2211 | switch (@typeInfo(S)) { | 2225 | switch (@typeInfo(S)) { |
| 2212 | .@"struct" => |struct_info| { | 2226 | .@"struct" => |@"struct"| { |
| 2213 | if (struct_info.backing_integer) |Int| { | 2227 | if (@"struct".backing_integer) |Int| { |
| 2214 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); | 2228 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); |
| 2215 | } else inline for (struct_info.field_types, struct_info.field_names, struct_info.field_attrs) |f_type, f_name, f_attr| { | 2229 | } else inline for (@"struct".field_types, @"struct".field_names, @"struct".field_attrs) |f_type, f_name, f_attr| { |
| 2216 | switch (@typeInfo(f_type)) { | 2230 | switch (@typeInfo(f_type)) { |
| 2217 | .@"struct" => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), | 2231 | .@"struct" => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), |
| 2218 | .@"union", .array => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), | 2232 | .@"union", .array => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), |
| ... | @@ -2220,8 +2234,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a | ... | @@ -2220,8 +2234,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a |
| 2220 | @field(ptr, f_name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f_name)))); | 2234 | @field(ptr, f_name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f_name)))); |
| 2221 | }, | 2235 | }, |
| 2222 | .bool => {}, | 2236 | .bool => {}, |
| 2223 | .float => |float_info| { | 2237 | .float => |float| { |
| 2224 | @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float_info.bits), @bitCast(@field(ptr, f_name))))); | 2238 | @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float.bits), @bitCast(@field(ptr, f_name))))); |
| 2225 | }, | 2239 | }, |
| 2226 | else => { | 2240 | else => { |
| 2227 | @field(ptr, f_name) = @byteSwap(@field(ptr, f_name)); | 2241 | @field(ptr, f_name) = @byteSwap(@field(ptr, f_name)); |
| ... | @@ -2229,23 +2243,26 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a | ... | @@ -2229,23 +2243,26 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a |
| 2229 | } | 2243 | } |
| 2230 | } | 2244 | } |
| 2231 | }, | 2245 | }, |
| 2232 | .@"union" => |union_info| { | 2246 | .@"union" => |@"union"| if (@"union".backing_integer) |Int| { |
| 2233 | if (union_info.tag_type != null) { | 2247 | ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); |
| 2234 | @compileError("byteSwapAllFields expects an untagged union"); | 2248 | } else { |
| 2249 | if (@"union".layout != .@"extern") { | ||
| 2250 | @compileError("byteSwapAllFields expects a packed or extern union"); | ||
| 2235 | } | 2251 | } |
| 2236 | 2252 | ||
| 2237 | const first_size = @bitSizeOf(union_info.field_types[0]); | 2253 | const first_size = @bitSizeOf(@"union".field_types[0]); |
| 2238 | inline for (union_info.field_types) |field_type| { | 2254 | inline for (@"union".field_types) |field_type| { |
| 2239 | if (@bitSizeOf(field_type) != first_size) { | 2255 | if (@bitSizeOf(field_type) != first_size) { |
| 2240 | @compileError("Unable to byte-swap unions with varying field sizes"); | 2256 | @compileError("Unable to byte-swap unions with varying field sizes"); |
| 2241 | } | 2257 | } |
| 2242 | } | 2258 | } |
| 2243 | 2259 | ||
| 2244 | const BackingInt = @Int(.unsigned, @bitSizeOf(S)); | 2260 | const FieldInt = @Int(.unsigned, first_size); |
| 2245 | ptr.* = @bitCast(@byteSwap(@as(BackingInt, @bitCast(ptr.*)))); | 2261 | const field_ptr = &@field(ptr, @"union".field_names[0]); |
| 2262 | field_ptr.* = @bitCast(@byteSwap(@as(FieldInt, @bitCast(field_ptr.*)))); | ||
| 2246 | }, | 2263 | }, |
| 2247 | .array => |info| { | 2264 | .array => |array| { |
| 2248 | byteSwapAllElements(info.child, ptr); | 2265 | byteSwapAllElements(array.child, ptr); |
| 2249 | }, | 2266 | }, |
| 2250 | else => { | 2267 | else => { |
| 2251 | ptr.* = @byteSwap(ptr.*); | 2268 | ptr.* = @byteSwap(ptr.*); |
| ... | @@ -2291,7 +2308,7 @@ test byteSwapAllFields { | ... | @@ -2291,7 +2308,7 @@ test byteSwapAllFields { |
| 2291 | .f2 = 0x12345678, | 2308 | .f2 = 0x12345678, |
| 2292 | .f3 = .{0x12}, | 2309 | .f3 = .{0x12}, |
| 2293 | .f4 = true, | 2310 | .f4 = true, |
| 2294 | .f5 = @as(f32, @bitCast(@as(u32, 0x4640e400))), | 2311 | .f5 = @bitCast(@as(u32, 0x4640e400)), |
| 2295 | .f6 = .{ .f0 = 0x1234 }, | 2312 | .f6 = .{ .f0 = 0x1234 }, |
| 2296 | }; | 2313 | }; |
| 2297 | var k = K{ | 2314 | var k = K{ |
| ... | @@ -2300,7 +2317,7 @@ test byteSwapAllFields { | ... | @@ -2300,7 +2317,7 @@ test byteSwapAllFields { |
| 2300 | .f2 = 0x1234, | 2317 | .f2 = 0x1234, |
| 2301 | .f3 = .{0x12}, | 2318 | .f3 = .{0x12}, |
| 2302 | .f4 = false, | 2319 | .f4 = false, |
| 2303 | .f5 = @as(f32, @bitCast(@as(u32, 0x45d42800))), | 2320 | .f5 = @bitCast(@as(u32, 0x45d42800)), |
| 2304 | }; | 2321 | }; |
| 2305 | var p: P = @bitCast(@as(u32, 0x01234567)); | 2322 | var p: P = @bitCast(@as(u32, 0x01234567)); |
| 2306 | var a: A = A{ | 2323 | var a: A = A{ |
| ... | @@ -2318,7 +2335,7 @@ test byteSwapAllFields { | ... | @@ -2318,7 +2335,7 @@ test byteSwapAllFields { |
| 2318 | .f2 = 0x78563412, | 2335 | .f2 = 0x78563412, |
| 2319 | .f3 = .{0x12}, | 2336 | .f3 = .{0x12}, |
| 2320 | .f4 = true, | 2337 | .f4 = true, |
| 2321 | .f5 = @as(f32, @bitCast(@as(u32, 0x00e44046))), | 2338 | .f5 = @bitCast(@as(u32, 0x00e44046)), |
| 2322 | .f6 = .{ .f0 = 0x3412 }, | 2339 | .f6 = .{ .f0 = 0x3412 }, |
| 2323 | }, s); | 2340 | }, s); |
| 2324 | try std.testing.expectEqual(K{ | 2341 | try std.testing.expectEqual(K{ |
| ... | @@ -2327,7 +2344,7 @@ test byteSwapAllFields { | ... | @@ -2327,7 +2344,7 @@ test byteSwapAllFields { |
| 2327 | .f2 = 0x3412, | 2344 | .f2 = 0x3412, |
| 2328 | .f3 = .{0x12}, | 2345 | .f3 = .{0x12}, |
| 2329 | .f4 = false, | 2346 | .f4 = false, |
| 2330 | .f5 = @as(f32, @bitCast(@as(u32, 0x0028d445))), | 2347 | .f5 = @bitCast(@as(u32, 0x0028d445)), |
| 2331 | }, k); | 2348 | }, k); |
| 2332 | try std.testing.expectEqual(@as(P, @bitCast(@as(u32, 0x67452301))), p); | 2349 | try std.testing.expectEqual(@as(P, @bitCast(@as(u32, 0x67452301))), p); |
| 2333 | try std.testing.expectEqual(A{ | 2350 | try std.testing.expectEqual(A{ |
| ... | @@ -2348,8 +2365,9 @@ pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void { | ... | @@ -2348,8 +2365,9 @@ pub fn byteSwapAllElements(comptime Elem: type, slice: []Elem) void { |
| 2348 | elem.* = @enumFromInt(@byteSwap(@intFromEnum(elem.*))); | 2365 | elem.* = @enumFromInt(@byteSwap(@intFromEnum(elem.*))); |
| 2349 | }, | 2366 | }, |
| 2350 | .bool => {}, | 2367 | .bool => {}, |
| 2351 | .float => |float_info| { | 2368 | .float => |float| { |
| 2352 | elem.* = @bitCast(@byteSwap(@as(@Int(.unsigned, float_info.bits), @bitCast(elem.*)))); | 2369 | const int_repr: @Int(.unsigned, float.bits) = @bitCast(elem.*); |
| 2370 | elem.* = @bitCast(@byteSwap(int_repr)); | ||
| 2353 | }, | 2371 | }, |
| 2354 | else => { | 2372 | else => { |
| 2355 | elem.* = @byteSwap(elem.*); | 2373 | elem.* = @byteSwap(elem.*); |
| ... | @@ -3870,25 +3888,29 @@ inline fn reverseVector(comptime N: usize, comptime T: type, a: []T) [N]T { | ... | @@ -3870,25 +3888,29 @@ inline fn reverseVector(comptime N: usize, comptime T: type, a: []T) [N]T { |
| 3870 | pub fn reverse(comptime T: type, items: []T) void { | 3888 | pub fn reverse(comptime T: type, items: []T) void { |
| 3871 | var i: usize = 0; | 3889 | var i: usize = 0; |
| 3872 | const end = items.len / 2; | 3890 | const end = items.len / 2; |
| 3873 | if (use_vectors and | 3891 | |
| 3874 | !@inComptime() and | 3892 | vec: { |
| 3875 | @bitSizeOf(T) > 0 and | 3893 | if (!use_vectors) break :vec; |
| 3876 | std.math.isPowerOfTwo(@bitSizeOf(T))) | 3894 | if (@inComptime()) break :vec; |
| 3877 | { | 3895 | switch (@typeInfo(T)) { |
| 3878 | if (std.simd.suggestVectorLength(T)) |simd_size| { | 3896 | .int, .float => {}, |
| 3879 | if (simd_size <= end) { | 3897 | .pointer => |pointer| if (pointer.size == .slice) break :vec, |
| 3880 | const simd_end = end - (simd_size - 1); | 3898 | else => break :vec, |
| 3881 | while (i < simd_end) : (i += simd_size) { | 3899 | } |
| 3882 | const left_slice = items[i .. i + simd_size]; | 3900 | if (@bitSizeOf(T) == 0 or !comptime std.math.isPowerOfTwo(@bitSizeOf(T))) break :vec; |
| 3883 | const right_slice = items[items.len - i - simd_size .. items.len - i]; | 3901 | const simd_size = std.simd.suggestVectorLength(T) orelse break :vec; |
| 3884 | 3902 | if (simd_size > end) break :vec; | |
| 3885 | const left_shuffled: [simd_size]T = reverseVector(simd_size, T, left_slice); | 3903 | |
| 3886 | const right_shuffled: [simd_size]T = reverseVector(simd_size, T, right_slice); | 3904 | const simd_end = end - (simd_size - 1); |
| 3887 | 3905 | while (i < simd_end) : (i += simd_size) { | |
| 3888 | @memcpy(right_slice, &left_shuffled); | 3906 | const left_slice = items[i .. i + simd_size]; |
| 3889 | @memcpy(left_slice, &right_shuffled); | 3907 | const right_slice = items[items.len - i - simd_size .. items.len - i]; |
| 3890 | } | 3908 | |
| 3891 | } | 3909 | const left_shuffled: [simd_size]T = reverseVector(simd_size, T, left_slice); |
| 3910 | const right_shuffled: [simd_size]T = reverseVector(simd_size, T, right_slice); | ||
| 3911 | |||
| 3912 | @memcpy(right_slice, &left_shuffled); | ||
| 3913 | @memcpy(left_slice, &right_shuffled); | ||
| 3892 | } | 3914 | } |
| 3893 | } | 3915 | } |
| 3894 | 3916 | ||
| ... | @@ -5009,8 +5031,8 @@ test "read/write(Var)PackedInt" { | ... | @@ -5009,8 +5031,8 @@ test "read/write(Var)PackedInt" { |
| 5009 | for ([_]PackedType{ | 5031 | for ([_]PackedType{ |
| 5010 | ~@as(PackedType, 0), // all ones: -1 iN / maxInt uN | 5032 | ~@as(PackedType, 0), // all ones: -1 iN / maxInt uN |
| 5011 | @as(PackedType, 0), // all zeros: 0 iN / 0 uN | 5033 | @as(PackedType, 0), // all zeros: 0 iN / 0 uN |
| 5012 | @as(PackedType, @bitCast(@as(iPackedType, math.maxInt(iPackedType)))), // maxInt iN | 5034 | @bitCast(@as(iPackedType, math.maxInt(iPackedType))), // maxInt iN |
| 5013 | @as(PackedType, @bitCast(@as(iPackedType, math.minInt(iPackedType)))), // maxInt iN | 5035 | @bitCast(@as(iPackedType, math.minInt(iPackedType))), // maxInt iN |
| 5014 | random.int(PackedType), // random | 5036 | random.int(PackedType), // random |
| 5015 | random.int(PackedType), // random | 5037 | random.int(PackedType), // random |
| 5016 | }) |write_value| { | 5038 | }) |write_value| { |
lib/std/os/linux/IoUring/test.zig+24-8| ... | @@ -526,7 +526,9 @@ test "sendmsg/recvmsg" { | ... | @@ -526,7 +526,9 @@ test "sendmsg/recvmsg" { |
| 526 | 526 | ||
| 527 | var address_server: linux.sockaddr.in = .{ | 527 | var address_server: linux.sockaddr.in = .{ |
| 528 | .port = 0, | 528 | .port = 0, |
| 529 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 529 | .addr = @as(*align(1) const u32, @ptrCast( |
| 530 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 531 | )).*, | ||
| 530 | }; | 532 | }; |
| 531 | 533 | ||
| 532 | const server = try socket(address_server.family, posix.SOCK.DGRAM, 0); | 534 | const server = try socket(address_server.family, posix.SOCK.DGRAM, 0); |
| ... | @@ -1028,7 +1030,9 @@ test "shutdown" { | ... | @@ -1028,7 +1030,9 @@ test "shutdown" { |
| 1028 | 1030 | ||
| 1029 | var address: linux.sockaddr.in = .{ | 1031 | var address: linux.sockaddr.in = .{ |
| 1030 | .port = 0, | 1032 | .port = 0, |
| 1031 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 1033 | .addr = @as(*align(1) const u32, @ptrCast( |
| 1034 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 1035 | )).*, | ||
| 1032 | }; | 1036 | }; |
| 1033 | 1037 | ||
| 1034 | // Socket bound, expect shutdown to work | 1038 | // Socket bound, expect shutdown to work |
| ... | @@ -1740,7 +1744,9 @@ test "accept multishot" { | ... | @@ -1740,7 +1744,9 @@ test "accept multishot" { |
| 1740 | 1744 | ||
| 1741 | var address: linux.sockaddr.in = .{ | 1745 | var address: linux.sockaddr.in = .{ |
| 1742 | .port = 0, | 1746 | .port = 0, |
| 1743 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 1747 | .addr = @as(*align(1) const u32, @ptrCast( |
| 1748 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 1749 | )).*, | ||
| 1744 | }; | 1750 | }; |
| 1745 | const listener_socket = try createListenerSocket(&address); | 1751 | const listener_socket = try createListenerSocket(&address); |
| 1746 | defer _ = linux.close(listener_socket); | 1752 | defer _ = linux.close(listener_socket); |
| ... | @@ -1842,7 +1848,9 @@ test "accept_direct" { | ... | @@ -1842,7 +1848,9 @@ test "accept_direct" { |
| 1842 | defer ring.deinit(); | 1848 | defer ring.deinit(); |
| 1843 | var address: linux.sockaddr.in = .{ | 1849 | var address: linux.sockaddr.in = .{ |
| 1844 | .port = 0, | 1850 | .port = 0, |
| 1845 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 1851 | .addr = @as(*align(1) const u32, @ptrCast( |
| 1852 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 1853 | )).*, | ||
| 1846 | }; | 1854 | }; |
| 1847 | 1855 | ||
| 1848 | // register direct file descriptors | 1856 | // register direct file descriptors |
| ... | @@ -1931,7 +1939,9 @@ test "accept_multishot_direct" { | ... | @@ -1931,7 +1939,9 @@ test "accept_multishot_direct" { |
| 1931 | 1939 | ||
| 1932 | var address: linux.sockaddr.in = .{ | 1940 | var address: linux.sockaddr.in = .{ |
| 1933 | .port = 0, | 1941 | .port = 0, |
| 1934 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 1942 | .addr = @as(*align(1) const u32, @ptrCast( |
| 1943 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 1944 | )).*, | ||
| 1935 | }; | 1945 | }; |
| 1936 | 1946 | ||
| 1937 | var registered_fds: [2]linux.fd_t = @splat(-1); | 1947 | var registered_fds: [2]linux.fd_t = @splat(-1); |
| ... | @@ -2041,7 +2051,9 @@ test "socket_direct/socket_direct_alloc/close_direct" { | ... | @@ -2041,7 +2051,9 @@ test "socket_direct/socket_direct_alloc/close_direct" { |
| 2041 | // use sockets from registered_fds in connect operation | 2051 | // use sockets from registered_fds in connect operation |
| 2042 | var address: linux.sockaddr.in = .{ | 2052 | var address: linux.sockaddr.in = .{ |
| 2043 | .port = 0, | 2053 | .port = 0, |
| 2044 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 2054 | .addr = @as(*align(1) const u32, @ptrCast( |
| 2055 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 2056 | )).*, | ||
| 2045 | }; | 2057 | }; |
| 2046 | const listener_socket = try createListenerSocket(&address); | 2058 | const listener_socket = try createListenerSocket(&address); |
| 2047 | defer _ = linux.close(listener_socket); | 2059 | defer _ = linux.close(listener_socket); |
| ... | @@ -2426,7 +2438,9 @@ test "bind/listen/connect" { | ... | @@ -2426,7 +2438,9 @@ test "bind/listen/connect" { |
| 2426 | 2438 | ||
| 2427 | var addr: linux.sockaddr.in = .{ | 2439 | var addr: linux.sockaddr.in = .{ |
| 2428 | .port = 0, | 2440 | .port = 0, |
| 2429 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 2441 | .addr = @as(*align(1) const u32, @ptrCast( |
| 2442 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 2443 | )).*, | ||
| 2430 | }; | 2444 | }; |
| 2431 | const proto: u32 = if (addr.family == linux.AF.UNIX) 0 else linux.IPPROTO.TCP; | 2445 | const proto: u32 = if (addr.family == linux.AF.UNIX) 0 else linux.IPPROTO.TCP; |
| 2432 | 2446 | ||
| ... | @@ -2614,7 +2628,9 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { | ... | @@ -2614,7 +2628,9 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness { |
| 2614 | // Create a TCP server socket | 2628 | // Create a TCP server socket |
| 2615 | var address: linux.sockaddr.in = .{ | 2629 | var address: linux.sockaddr.in = .{ |
| 2616 | .port = 0, | 2630 | .port = 0, |
| 2617 | .addr = @bitCast([4]u8{ 127, 0, 0, 1 }), | 2631 | .addr = @as(*align(1) const u32, @ptrCast( |
| 2632 | &@as([4]u8, .{ 127, 0, 0, 1 }), | ||
| 2633 | )).*, | ||
| 2618 | }; | 2634 | }; |
| 2619 | const listener_socket = try createListenerSocket(&address); | 2635 | const listener_socket = try createListenerSocket(&address); |
| 2620 | errdefer _ = linux.close(listener_socket); | 2636 | errdefer _ = linux.close(listener_socket); |
lib/std/os/uefi.zig+1-1| ... | @@ -218,7 +218,7 @@ pub const TimeCapabilities = extern struct { | ... | @@ -218,7 +218,7 @@ pub const TimeCapabilities = extern struct { |
| 218 | pub const FileHandle = *opaque {}; | 218 | pub const FileHandle = *opaque {}; |
| 219 | 219 | ||
| 220 | test "GUID formatting" { | 220 | test "GUID formatting" { |
| 221 | const bytes = [_]u8{ 137, 60, 203, 50, 128, 128, 124, 66, 186, 19, 80, 73, 135, 59, 194, 135 }; | 221 | const bytes: [16]u8 = .{ 137, 60, 203, 50, 128, 128, 124, 66, 186, 19, 80, 73, 135, 59, 194, 135 }; |
| 222 | const guid: Guid = @bitCast(bytes); | 222 | const guid: Guid = @bitCast(bytes); |
| 223 | 223 | ||
| 224 | const str = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{guid}); | 224 | const str = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{guid}); |
lib/std/os/windows.zig+37-36| ... | @@ -4189,19 +4189,11 @@ pub const GUID = extern struct { | ... | @@ -4189,19 +4189,11 @@ pub const GUID = extern struct { |
| 4189 | Data3: u16, | 4189 | Data3: u16, |
| 4190 | Data4: [8]u8, | 4190 | Data4: [8]u8, |
| 4191 | 4191 | ||
| 4192 | const hex_offsets = switch (builtin.target.cpu.arch.endian()) { | 4192 | const hex_offsets: [16]u6 = .{ |
| 4193 | .big => [16]u6{ | 4193 | 6, 4, 2, 0, |
| 4194 | 0, 2, 4, 6, | 4194 | 11, 9, 16, 14, |
| 4195 | 9, 11, 14, 16, | 4195 | 19, 21, 24, 26, |
| 4196 | 19, 21, 24, 26, | 4196 | 28, 30, 32, 34, |
| 4197 | 28, 30, 32, 34, | ||
| 4198 | }, | ||
| 4199 | .little => [16]u6{ | ||
| 4200 | 6, 4, 2, 0, | ||
| 4201 | 11, 9, 16, 14, | ||
| 4202 | 19, 21, 24, 26, | ||
| 4203 | 28, 30, 32, 34, | ||
| 4204 | }, | ||
| 4205 | }; | 4197 | }; |
| 4206 | 4198 | ||
| 4207 | pub fn parse(s: []const u8) GUID { | 4199 | pub fn parse(s: []const u8) GUID { |
| ... | @@ -4216,12 +4208,21 @@ pub const GUID = extern struct { | ... | @@ -4216,12 +4208,21 @@ pub const GUID = extern struct { |
| 4216 | assert(s[13] == '-'); | 4208 | assert(s[13] == '-'); |
| 4217 | assert(s[18] == '-'); | 4209 | assert(s[18] == '-'); |
| 4218 | assert(s[23] == '-'); | 4210 | assert(s[23] == '-'); |
| 4219 | var bytes: [16]u8 = undefined; | 4211 | var raw1: [4]u8 = undefined; |
| 4220 | for (hex_offsets, 0..) |hex_offset, i| { | 4212 | var raw2: [2]u8 = undefined; |
| 4221 | bytes[i] = (try std.fmt.charToDigit(s[hex_offset], 16)) << 4 | | 4213 | var raw3: [2]u8 = undefined; |
| 4222 | try std.fmt.charToDigit(s[hex_offset + 1], 16); | 4214 | var raw4: [8]u8 = undefined; |
| 4223 | } | 4215 | assert((try std.fmt.hexToBytes(&raw1, s[0..8])).len == raw1.len); |
| 4224 | return @as(GUID, @bitCast(bytes)); | 4216 | assert((try std.fmt.hexToBytes(&raw2, s[9..13])).len == raw2.len); |
| 4217 | assert((try std.fmt.hexToBytes(&raw3, s[14..18])).len == raw3.len); | ||
| 4218 | assert((try std.fmt.hexToBytes(raw4[0..2], s[19..23])).len == 2); | ||
| 4219 | assert((try std.fmt.hexToBytes(raw4[2..8], s[24..36])).len == 6); | ||
| 4220 | return .{ | ||
| 4221 | .Data1 = @byteSwap(@as(u32, @bitCast(raw1))), | ||
| 4222 | .Data2 = @byteSwap(@as(u16, @bitCast(raw2))), | ||
| 4223 | .Data3 = @byteSwap(@as(u16, @bitCast(raw3))), | ||
| 4224 | .Data4 = raw4, | ||
| 4225 | }; | ||
| 4225 | } | 4226 | } |
| 4226 | 4227 | ||
| 4227 | pub fn format(self: GUID, w: *std.Io.Writer) std.Io.Writer.Error!void { | 4228 | pub fn format(self: GUID, w: *std.Io.Writer) std.Io.Writer.Error!void { |
| ... | @@ -4233,28 +4234,28 @@ pub const GUID = extern struct { | ... | @@ -4233,28 +4234,28 @@ pub const GUID = extern struct { |
| 4233 | self.Data4[2..8], | 4234 | self.Data4[2..8], |
| 4234 | }); | 4235 | }); |
| 4235 | } | 4236 | } |
| 4236 | }; | ||
| 4237 | 4237 | ||
| 4238 | test GUID { | 4238 | test parse { |
| 4239 | try std.testing.expectEqual( | 4239 | const expected: GUID = .{ |
| 4240 | GUID{ | ||
| 4241 | .Data1 = 0x01234567, | 4240 | .Data1 = 0x01234567, |
| 4242 | .Data2 = 0x89ab, | 4241 | .Data2 = 0x89ab, |
| 4243 | .Data3 = 0xef10, | 4242 | .Data3 = 0xef10, |
| 4244 | .Data4 = "\x32\x54\x76\x98\xba\xdc\xfe\x91".*, | 4243 | .Data4 = "\x32\x54\x76\x98\xba\xdc\xfe\x91".*, |
| 4245 | }, | 4244 | }; |
| 4246 | GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}"), | 4245 | try std.testing.expectEqual(expected, GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}")); |
| 4247 | ); | 4246 | } |
| 4248 | try std.testing.expectFmt( | 4247 | |
| 4249 | "{01234567-89ab-ef10-3254-7698badcfe91}", | 4248 | test format { |
| 4250 | "{f}", | 4249 | const guid0: GUID = .{ .Data1 = 1, .Data2 = 1, .Data3 = 1, .Data4 = .{ 0, 1, 0, 0, 0, 0, 0, 1 } }; |
| 4251 | .{GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}")}, | 4250 | try std.testing.expectFmt("{00000001-0001-0001-0001-000000000001}", "{f}", .{guid0}); |
| 4252 | ); | 4251 | |
| 4253 | try std.testing.expectFmt( | 4252 | const guid1: GUID = .parse("{01234567-89AB-EF10-3254-7698badcfe91}"); |
| 4254 | "{00000001-0001-0001-0001-000000000001}", | 4253 | try std.testing.expectFmt("{01234567-89ab-ef10-3254-7698badcfe91}", "{f}", .{guid1}); |
| 4255 | "{f}", | 4254 | } |
| 4256 | .{GUID{ .Data1 = 1, .Data2 = 1, .Data3 = 1, .Data4 = [_]u8{ 0, 1, 0, 0, 0, 0, 0, 1 } }}, | 4255 | }; |
| 4257 | ); | 4256 | |
| 4257 | test { | ||
| 4258 | _ = GUID; | ||
| 4258 | } | 4259 | } |
| 4259 | 4260 | ||
| 4260 | pub const COORD = extern struct { | 4261 | pub const COORD = extern struct { |
lib/std/testing.zig+30-24| ... | @@ -141,39 +141,45 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void { | ... | @@ -141,39 +141,45 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void { |
| 141 | try expectEqualSlices(info.child, &expect_array, &actual_array); | 141 | try expectEqualSlices(info.child, &expect_array, &actual_array); |
| 142 | }, | 142 | }, |
| 143 | 143 | ||
| 144 | .@"struct" => |structType| { | 144 | .@"struct" => |@"struct"| { |
| 145 | inline for (structType.field_names) |field_name| { | 145 | inline for (@"struct".field_names) |field_name| { |
| 146 | try expectEqual(@field(expected, field_name), @field(actual, field_name)); | 146 | try expectEqual(@field(expected, field_name), @field(actual, field_name)); |
| 147 | } | 147 | } |
| 148 | }, | 148 | }, |
| 149 | 149 | ||
| 150 | .@"union" => |union_info| { | 150 | .@"union" => |@"union"| if (@"union".backing_integer) |Int| { |
| 151 | if (union_info.tag_type == null) { | 151 | try expectEqual(@as(Int, @bitCast(expected)), @as(Int, @bitCast(actual))); |
| 152 | const first_size = @bitSizeOf(union_info.field_types[0]); | 152 | } else switch (@"union".layout) { |
| 153 | inline for (union_info.field_types) |field_type| { | 153 | .@"packed" => { |
| 154 | const Int = @Int(.unsigned, @bitSizeOf(T)); | ||
| 155 | try expectEqual(@as(Int, @bitCast(expected)), @as(Int, @bitCast(actual))); | ||
| 156 | }, | ||
| 157 | .@"extern" => { | ||
| 158 | const first_size = @bitSizeOf(@"union".field_types[0]); | ||
| 159 | inline for (@"union".field_types) |field_type| { | ||
| 154 | if (@bitSizeOf(field_type) != first_size) { | 160 | if (@bitSizeOf(field_type) != first_size) { |
| 155 | @compileError("Unable to compare untagged unions with varying field sizes for type " ++ @typeName(@TypeOf(actual))); | 161 | @compileError("Unable to compare extern unions with varying field sizes for type " ++ @typeName(T)); |
| 156 | } | 162 | } |
| 157 | } | 163 | } |
| 158 | 164 | const FieldInt = @Int(.unsigned, first_size); | |
| 159 | const BackingInt = @Int(.unsigned, @bitSizeOf(T)); | 165 | const expected_field = @field(expected, @"union".field_names[0]); |
| 166 | const actual_field = @field(actual, @"union".field_names[0]); | ||
| 160 | return expectEqual( | 167 | return expectEqual( |
| 161 | @as(BackingInt, @bitCast(expected)), | 168 | @as(FieldInt, @bitCast(expected_field)), |
| 162 | @as(BackingInt, @bitCast(actual)), | 169 | @as(FieldInt, @bitCast(actual_field)), |
| 163 | ); | 170 | ); |
| 164 | } | 171 | }, |
| 165 | 172 | .auto => { | |
| 166 | const Tag = std.meta.Tag(@TypeOf(expected)); | 173 | const Tag = @"union".tag_type orelse @compileError("byteSwapAllFields expects packed, extern, or tagged union"); |
| 167 | 174 | ||
| 168 | const expectedTag = @as(Tag, expected); | 175 | try expectEqual(@as(Tag, expected), @as(Tag, actual)); |
| 169 | const actualTag = @as(Tag, actual); | 176 | switch (expected) { |
| 170 | 177 | inline else => |expected_payload, tag| { | |
| 171 | try expectEqual(expectedTag, actualTag); | 178 | const actual_payload = @field(actual, @tagName(tag)); |
| 172 | 179 | try expectEqual(expected_payload, actual_payload); | |
| 173 | // we only reach this switch if the tags are equal | 180 | }, |
| 174 | switch (expected) { | 181 | } |
| 175 | inline else => |val, tag| try expectEqual(val, @field(actual, @tagName(tag))), | 182 | }, |
| 176 | } | ||
| 177 | }, | 183 | }, |
| 178 | 184 | ||
| 179 | .optional => { | 185 | .optional => { |
lib/std/zig/llvm/Builder.zig+2-2| ... | @@ -1816,7 +1816,7 @@ pub const Linkage = enum(u4) { | ... | @@ -1816,7 +1816,7 @@ pub const Linkage = enum(u4) { |
| 1816 | } | 1816 | } |
| 1817 | }; | 1817 | }; |
| 1818 | 1818 | ||
| 1819 | pub const Preemption = enum { | 1819 | pub const Preemption = enum(u2) { |
| 1820 | dso_preemptable, | 1820 | dso_preemptable, |
| 1821 | dso_local, | 1821 | dso_local, |
| 1822 | implicit_dso_local, | 1822 | implicit_dso_local, |
| ... | @@ -2011,7 +2011,7 @@ pub const AddrSpace = enum(u24) { | ... | @@ -2011,7 +2011,7 @@ pub const AddrSpace = enum(u24) { |
| 2011 | } | 2011 | } |
| 2012 | }; | 2012 | }; |
| 2013 | 2013 | ||
| 2014 | pub const ExternallyInitialized = enum { | 2014 | pub const ExternallyInitialized = enum(u1) { |
| 2015 | default, | 2015 | default, |
| 2016 | externally_initialized, | 2016 | externally_initialized, |
| 2017 | 2017 |