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