Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/compiler_rt/udivmodei4.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const common = @import("common.zig");
const shr = std.math.shr;
const shl = std.math.shl;

const max_limbs = std.math.divCeil(usize, 65535, 32) catch unreachable; // max supported type is u65535
const max_limbs: usize = std.math.divCeilAssert(comptime_int, 65535, 32); // max supported type is u65535

comptime {
@export(__udivei4, .{ .name = "__udivei4", .linkage = common.linkage, .visibility = common.visibility });
Expand Down
4 changes: 2 additions & 2 deletions lib/std/crypto/aes_gcm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn AesGcm(comptime Aes: anytype) type {
mem.writeIntBig(u32, j[nonce_length..][0..4], 1);
aes.encrypt(&t, &j);

const block_count = (math.divCeil(usize, ad.len, Ghash.block_length) catch unreachable) + (math.divCeil(usize, c.len, Ghash.block_length) catch unreachable) + 1;
const block_count = math.divCeilAssert(usize, ad.len, Ghash.block_length) + math.divCeilAssert(usize, c.len, Ghash.block_length) + 1;
var mac = Ghash.initForBlockCount(&h, block_count);
mac.update(ad);
mac.pad();
Expand Down Expand Up @@ -78,7 +78,7 @@ fn AesGcm(comptime Aes: anytype) type {
mem.writeIntBig(u32, j[nonce_length..][0..4], 1);
aes.encrypt(&t, &j);

const block_count = (math.divCeil(usize, ad.len, Ghash.block_length) catch unreachable) + (math.divCeil(usize, c.len, Ghash.block_length) catch unreachable) + 1;
const block_count = math.divCeilAssert(usize, ad.len, Ghash.block_length) + math.divCeilAssert(usize, c.len, Ghash.block_length) + 1;
var mac = Ghash.initForBlockCount(&h, block_count);
mac.update(ad);
mac.pad();
Expand Down
3 changes: 2 additions & 1 deletion lib/std/crypto/ascon.zig
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ pub fn State(comptime endian: builtin.Endian) type {

/// Set the words storing the bytes of a given range to zero.
pub fn clear(self: *Self, from: usize, to: usize) void {
@memset(self.st[from / 8 .. (to + 7) / 8], 0);
const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1);
@memset(self.st[from / 8 .. @intCast(std.math.divCeilAssert(UsizePlusOne, to, 8))], 0);
}

/// Clear the entire state, disabling compiler optimizations.
Expand Down
13 changes: 8 additions & 5 deletions lib/std/crypto/ff.zig
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ pub fn Uint(comptime max_bits: comptime_int) type {
return struct {
const Self = @This();

const max_limbs_count = math.divCeil(usize, max_bits, t_bits) catch unreachable;
const max_limbs_count: usize = math.divCeilAssert(comptime_int, max_bits, t_bits);
const Limbs = BoundedArray(Limb, max_limbs_count);
limbs: Limbs,

/// Number of bytes required to serialize an integer.
pub const encoded_bytes = math.divCeil(usize, max_bits, 8) catch unreachable;
pub const encoded_bytes: usize = math.divCeilAssert(comptime_int, max_bits, 8);

// Returns the number of active limbs.
fn limbs_count(self: Self) usize {
Expand Down Expand Up @@ -788,9 +788,12 @@ pub fn Modulus(comptime max_bits: comptime_int) type {
/// Returns x^e (mod m), assuming that the exponent is public.
/// The function remains constant time with respect to `x`.
pub fn powPublic(self: Self, x: Fe, e: Fe) NullExponentError!Fe {
var e_normalized = Fe{ .v = e.v.normalize() };
var buf_: [Fe.encoded_bytes]u8 = undefined;
var buf = buf_[0 .. math.divCeil(usize, e_normalized.v.limbs_count() * t_bits, 8) catch unreachable];
const e_normalized: Fe = .{ .v = e.v.normalize() };
var buf: []u8 = buf: {
var buf_: [Fe.encoded_bytes]u8 = undefined;
const buf_end: usize = math.divCeilAssert(usize, e_normalized.v.limbs_count() * t_bits, 8);
break :buf buf_[0..buf_end];
};
e_normalized.toBytes(buf, .Little) catch unreachable;
const leading = @clz(e_normalized.v.limbs.get(e_normalized.v.limbs_count() - carry_bits));
buf = buf[0 .. buf.len - leading / 8];
Expand Down
2 changes: 1 addition & 1 deletion lib/std/crypto/pbkdf2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub fn pbkdf2(dk: []u8, password: []const u8, salt: []const u8, rounds: u32, com
// block
//

const blocks_count = @as(u32, @intCast(std.math.divCeil(usize, dk_len, h_len) catch unreachable));
const blocks_count: u32 = @intCast(std.math.divCeilAssert(usize, dk_len, h_len));
var r = dk_len % h_len;
if (r == 0) {
r = h_len;
Expand Down
2 changes: 1 addition & 1 deletion lib/std/hash/auto_hash.zig
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
} else {
// Take only the part containing the key value, the remaining
// bytes are undefined and must not be hashed!
const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
const byte_size: usize = comptime std.math.divCeilAssert(comptime_int, @bitSizeOf(Key), 8);
@call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key)[0..byte_size] });
}
},
Expand Down
10 changes: 5 additions & 5 deletions lib/std/io/Reader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -278,28 +278,28 @@ pub fn readBoundedBytes(self: Self, comptime num_bytes: usize) anyerror!std.Boun

/// Reads a native-endian integer
pub fn readIntNative(self: Self, comptime T: type) anyerror!T {
const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8)));
const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8));
return mem.readIntNative(T, &bytes);
}

/// Reads a foreign-endian integer
pub fn readIntForeign(self: Self, comptime T: type) anyerror!T {
const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8)));
const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8));
return mem.readIntForeign(T, &bytes);
}

pub fn readIntLittle(self: Self, comptime T: type) anyerror!T {
const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8)));
const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8));
return mem.readIntLittle(T, &bytes);
}

pub fn readIntBig(self: Self, comptime T: type) anyerror!T {
const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8)));
const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8));
return mem.readIntBig(T, &bytes);
}

pub fn readInt(self: Self, comptime T: type, endian: std.builtin.Endian) anyerror!T {
const bytes = try self.readBytesNoEof(@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8)));
const bytes = try self.readBytesNoEof(math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8));
return mem.readInt(T, &bytes, endian);
}

Expand Down
25 changes: 15 additions & 10 deletions lib/std/io/writer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,38 @@ pub fn Writer(

/// Write a native-endian integer.
pub fn writeIntNative(self: Self, comptime T: type, value: T) Error!void {
var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined;
mem.writeIntNative(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
const ByteAlignedT = std.math.ByteAlignedInt(T);
var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined;
mem.writeIntNative(ByteAlignedT, &bytes, value);
return self.writeAll(&bytes);
}

/// Write a foreign-endian integer.
pub fn writeIntForeign(self: Self, comptime T: type, value: T) Error!void {
var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined;
mem.writeIntForeign(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
const ByteAlignedT = std.math.ByteAlignedInt(T);
var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined;
mem.writeIntForeign(ByteAlignedT, &bytes, value);
return self.writeAll(&bytes);
}

pub fn writeIntLittle(self: Self, comptime T: type, value: T) Error!void {
var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined;
mem.writeIntLittle(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
const ByteAlignedT = std.math.ByteAlignedInt(T);
var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined;
mem.writeIntLittle(ByteAlignedT, &bytes, value);
return self.writeAll(&bytes);
}

pub fn writeIntBig(self: Self, comptime T: type, value: T) Error!void {
var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined;
mem.writeIntBig(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
const ByteAlignedT = std.math.ByteAlignedInt(T);
var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined;
mem.writeIntBig(ByteAlignedT, &bytes, value);
return self.writeAll(&bytes);
}

pub fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {
var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8 = undefined;
mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
const ByteAlignedT = std.math.ByteAlignedInt(T);
var bytes: [@bitSizeOf(ByteAlignedT) / 8]u8 = undefined;
mem.writeInt(ByteAlignedT, &bytes, value, endian);
return self.writeAll(&bytes);
}

Expand Down
11 changes: 8 additions & 3 deletions lib/std/math.zig
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,12 @@ pub fn divCeil(comptime T: type, numerator: T, denominator: T) !T {
}
}

/// Divide numerator by denominator, rounding toward positive
/// infinity. Asserts that the value fits and denominator is not zero.
pub fn divCeilAssert(comptime T: type, numerator: T, denominator: T) T {
return divCeil(T, numerator, denominator) catch unreachable;
}

test "divCeil" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;

Expand Down Expand Up @@ -1040,9 +1046,8 @@ test isPowerOfTwo {
/// Aligns the given integer type bit width to a width divisible by 8.
pub fn ByteAlignedInt(comptime T: type) type {
const info = @typeInfo(T).Int;
const bits = (info.bits + 7) / 8 * 8;
const extended_type = std.meta.Int(info.signedness, bits);
return extended_type;
const bytes_aligned: u14 = divCeilAssert(comptime_int, info.bits, 8);
return std.meta.Int(info.signedness, bytes_aligned * 8);
}

test "ByteAlignedInt" {
Expand Down
18 changes: 10 additions & 8 deletions lib/std/math/big/int.zig
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn calcSqrtLimbsBufferLen(a_bit_count: usize) usize {

// Compute the number of limbs required to store a 2s-complement number of `bit_count` bits.
pub fn calcTwosCompLimbCount(bit_count: usize) usize {
return std.math.divCeil(usize, bit_count, @bitSizeOf(Limb)) catch unreachable;
return math.divCeilAssert(usize, bit_count, limb_bits);
}

/// a + b * c + *carry, sets carry to the overflow bits
Expand Down Expand Up @@ -1910,14 +1910,16 @@ pub const Mutable = struct {
// Check whether the input is negative
var positive = true;
if (signedness == .signed) {
const total_bits = bit_offset + bit_count;
var last_byte = switch (endian) {
.Little => ((total_bits + 7) / 8) - 1,
.Big => buffer.len - ((total_bits + 7) / 8),
};
const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1);

const total_bits: usize = bit_offset + bit_count;
const last_byte_pos: usize = @intCast(switch (endian) {
.Little => math.divCeilAssert(UsizePlusOne, total_bits, 8) - 1,
.Big => @as(UsizePlusOne, buffer.len) - math.divCeilAssert(UsizePlusOne, total_bits, 8),
});

const sign_bit = @as(u8, 1) << @as(u3, @intCast((total_bits - 1) % 8));
positive = ((buffer[last_byte] & sign_bit) == 0);
const sign_bit = @as(u8, 1) << @intCast((total_bits - 1) % 8);
positive = ((buffer[last_byte_pos] & sign_bit) == 0);
}

// Copy all complete limbs
Expand Down
2 changes: 1 addition & 1 deletion lib/std/mem.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ test "readIntBig and readIntLittle" {
/// accepts any integer bit width.
/// This function stores in native endian, which means it is implemented as a simple
/// memory store.
pub fn writeIntNative(comptime T: type, buf: *[@as(u16, @intCast((@as(u17, @typeInfo(T).Int.bits) + 7) / 8))]u8, value: T) void {
pub fn writeIntNative(comptime T: type, buf: *[math.divCeilAssert(comptime_int, @typeInfo(T).Int.bits, 8)]u8, value: T) void {
@as(*align(1) T, @ptrCast(buf)).* = value;
}

Expand Down
35 changes: 19 additions & 16 deletions lib/std/packed_int_array.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const debug = std.debug;
const testing = std.testing;
const native_endian = builtin.target.cpu.arch.endian();
const Endian = std.builtin.Endian;
const divCeilAssert = std.math.divCeilAssert;

/// Provides a set of functions for reading and writing packed integers from a
/// slice of bytes.
Expand All @@ -26,24 +27,23 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {
// of the memory.
const int_bits = @bitSizeOf(Int);

// We bitcast the desired Int type to an unsigned version of itself
// to avoid issues with shifting signed ints.
const UnInt = std.meta.Int(.unsigned, int_bits);

// In the best case, this is the number of bytes we need to touch
// to read or write a value, as bits.
const min_io_bits = ((int_bits + 7) / 8) * 8;
const min_io_bits = @bitSizeOf(std.math.ByteAlignedInt(UnInt));

// In the worst case, this is the number of bytes we need to touch
// to read or write a value, as bits. To calculate for int_bits > 1,
// set aside 2 bits to touch the first and last bytes, then divide
// by 8 to see how many bytes can be filled up in between.
const max_io_bits = switch (int_bits) {
0 => 0,
1 => 8,
0, 1 => min_io_bits,
else => ((int_bits - 2) / 8 + 2) * 8,
};

// We bitcast the desired Int type to an unsigned version of itself
// to avoid issues with shifting signed ints.
const UnInt = std.meta.Int(.unsigned, int_bits);

// The maximum container int type
const MinIo = std.meta.Int(.unsigned, min_io_bits);

Expand Down Expand Up @@ -147,10 +147,12 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {
pub fn slice(bytes: []u8, bit_offset: u3, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
debug.assert(end >= start);

const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1);

const length = end - start;
const bit_index = (start * int_bits) + bit_offset;
const start_byte = bit_index / 8;
const end_byte = (bit_index + (length * int_bits) + 7) / 8;
const end_byte: usize = @intCast(divCeilAssert(UsizePlusOne, bit_index + (length * int_bits), 8));
const new_bytes = bytes[start_byte..end_byte];

if (length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0);
Expand Down Expand Up @@ -196,7 +198,7 @@ pub fn PackedIntArray(comptime Int: type, comptime int_count: usize) type {
pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptime int_count: usize) type {
const int_bits = @bitSizeOf(Int);
const total_bits = int_bits * int_count;
const total_bytes = (total_bits + 7) / 8;
const total_bytes: usize = divCeilAssert(comptime_int, total_bits, 8);

const Io = PackedIntIo(Int, endian);

Expand Down Expand Up @@ -293,7 +295,8 @@ pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: Endian) type {
/// of `Int`s.
pub fn bytesRequired(int_count: usize) usize {
const total_bits = int_bits * int_count;
const total_bytes = (total_bits + 7) / 8;
const UsizePlusOne = std.meta.Int(.unsigned, @bitSizeOf(usize) + 1);
const total_bytes: usize = @intCast(divCeilAssert(UsizePlusOne, total_bits, 8));
return total_bytes;
}

Expand Down Expand Up @@ -362,7 +365,7 @@ test "PackedIntArray" {
const I = std.meta.Int(sign, bits);

const PackedArray = PackedIntArray(I, int_count);
const expected_bytes = ((bits * int_count) + 7) / 8;
const expected_bytes: usize = divCeilAssert(comptime_int, bits * int_count, 8);
try testing.expect(@sizeOf(PackedArray) == expected_bytes);

var data = @as(PackedArray, undefined);
Expand Down Expand Up @@ -419,7 +422,7 @@ test "PackedIntSlice" {
const max_bits = 256;
const int_count = 19;
const total_bits = max_bits * int_count;
const total_bytes = (total_bits + 7) / 8;
const total_bytes: usize = divCeilAssert(comptime_int, total_bits, 8);

var buffer: [total_bytes]u8 = undefined;

Expand Down Expand Up @@ -476,7 +479,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
var packed_slice = packed_array.slice(2, 5);
try testing.expect(packed_slice.len == 3);
const ps_bit_count = (bits * packed_slice.len) + packed_slice.bit_offset;
const ps_expected_bytes = (ps_bit_count + 7) / 8;
const ps_expected_bytes: usize = divCeilAssert(comptime_int, ps_bit_count, 8);
try testing.expect(packed_slice.bytes.len == ps_expected_bytes);
try testing.expect(packed_slice.get(0) == 2 % limit);
try testing.expect(packed_slice.get(1) == 3 % limit);
Expand All @@ -491,7 +494,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
const packed_slice_two = packed_slice.slice(0, 3);
try testing.expect(packed_slice_two.len == 3);
const ps2_bit_count = (bits * packed_slice_two.len) + packed_slice_two.bit_offset;
const ps2_expected_bytes = (ps2_bit_count + 7) / 8;
const ps2_expected_bytes: usize = divCeilAssert(comptime_int, ps2_bit_count, 8);
try testing.expect(packed_slice_two.bytes.len == ps2_expected_bytes);
try testing.expect(packed_slice_two.get(1) == 7 % limit);
try testing.expect(packed_slice_two.get(2) == 4 % limit);
Expand All @@ -500,7 +503,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
const packed_slice_three = packed_slice_two.slice(1, 2);
try testing.expect(packed_slice_three.len == 1);
const ps3_bit_count = (bits * packed_slice_three.len) + packed_slice_three.bit_offset;
const ps3_expected_bytes = (ps3_bit_count + 7) / 8;
const ps3_expected_bytes: usize = divCeilAssert(comptime_int, ps3_bit_count, 8);
try testing.expect(packed_slice_three.bytes.len == ps3_expected_bytes);
try testing.expect(packed_slice_three.get(0) == 7 % limit);

Expand All @@ -513,7 +516,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
const packed_slice_edge = packed_array.slice(8, 16);
try testing.expect(packed_slice_edge.len == 8);
const pse_bit_count = (bits * packed_slice_edge.len) + packed_slice_edge.bit_offset;
const pse_expected_bytes = (pse_bit_count + 7) / 8;
const pse_expected_bytes: usize = divCeilAssert(comptime_int, pse_bit_count, 8);
try testing.expect(packed_slice_edge.bytes.len == pse_expected_bytes);
try testing.expect(packed_slice_edge.bit_offset == 0);
}
Expand Down
Loading