forked from mirrors/gecko-dev
Upgrades to Glean v50.0.1, which comes with a rewritten core and UniFFI-powered bindings. Glean has some API changes, so we swap it over to that. Mostly mechanical changes. Also upgrades to inherent v1.0 in fog. This matches what Glean uses internally and gets rid of one duplicated crate. Also upgrades to glean-parser==6.0.1 One crate duplication now (change in `python/mozbuild/mozbuild/vendor/vendor_rust.py` required). Some new crates now vendored. These are transitive dependencies of Glean dependencies, all with valid licenses and already used in other products (mobile). Differential Revision: https://phabricator.services.mozilla.com/D146062
395 lines
13 KiB
Rust
395 lines
13 KiB
Rust
mod stackvec;
|
|
|
|
use core::cmp;
|
|
use minimal_lexical::bigint;
|
|
use stackvec::{vec_from_u32, VecType};
|
|
|
|
// u64::MAX and Limb::MAX for older Rustc versions.
|
|
const U64_MAX: u64 = 0xffff_ffff_ffff_ffff;
|
|
// LIMB_MAX
|
|
#[cfg(all(target_pointer_width = "64", not(target_arch = "sparc")))]
|
|
const LIMB_MAX: u64 = U64_MAX;
|
|
#[cfg(not(all(target_pointer_width = "64", not(target_arch = "sparc"))))]
|
|
const LIMB_MAX: u32 = 0xffff_ffff;
|
|
|
|
#[test]
|
|
fn simple_test() {
|
|
// Test the simple properties of the stack vector.
|
|
let mut x = VecType::from_u64(1);
|
|
assert_eq!(x.len(), 1);
|
|
assert_eq!(x.is_empty(), false);
|
|
assert_eq!(x.capacity(), bigint::BIGINT_LIMBS);
|
|
x.try_push(5).unwrap();
|
|
assert_eq!(x.len(), 2);
|
|
assert_eq!(x.pop(), Some(5));
|
|
assert_eq!(x.len(), 1);
|
|
assert_eq!(&*x, &[1]);
|
|
x.try_extend(&[2, 3, 4]).unwrap();
|
|
assert_eq!(x.len(), 4);
|
|
assert_eq!(&*x, &[1, 2, 3, 4]);
|
|
x.try_resize(6, 0).unwrap();
|
|
assert_eq!(x.len(), 6);
|
|
assert_eq!(&*x, &[1, 2, 3, 4, 0, 0]);
|
|
x.try_resize(0, 0).unwrap();
|
|
assert_eq!(x.len(), 0);
|
|
assert_eq!(x.is_empty(), true);
|
|
|
|
let x = VecType::try_from(&[5, 1]).unwrap();
|
|
assert_eq!(x.len(), 2);
|
|
assert_eq!(x.is_empty(), false);
|
|
if bigint::LIMB_BITS == 32 {
|
|
assert_eq!(x.hi64(), (0x8000000280000000, false));
|
|
} else {
|
|
assert_eq!(x.hi64(), (0x8000000000000002, true));
|
|
}
|
|
let rview = bigint::rview(&x);
|
|
assert_eq!(x[0], 5);
|
|
assert_eq!(x[1], 1);
|
|
assert_eq!(rview[0], 1);
|
|
assert_eq!(rview[1], 5);
|
|
assert_eq!(x.len(), 2);
|
|
|
|
assert_eq!(VecType::from_u64(U64_MAX).hi64(), (U64_MAX, false));
|
|
}
|
|
|
|
#[test]
|
|
fn hi64_test() {
|
|
assert_eq!(VecType::from_u64(0xA).hi64(), (0xA000000000000000, false));
|
|
assert_eq!(VecType::from_u64(0xAB).hi64(), (0xAB00000000000000, false));
|
|
assert_eq!(VecType::from_u64(0xAB00000000).hi64(), (0xAB00000000000000, false));
|
|
assert_eq!(VecType::from_u64(0xA23456789A).hi64(), (0xA23456789A000000, false));
|
|
}
|
|
|
|
#[test]
|
|
fn cmp_test() {
|
|
// Simple
|
|
let x = VecType::from_u64(1);
|
|
let y = VecType::from_u64(2);
|
|
assert_eq!(x.partial_cmp(&x), Some(cmp::Ordering::Equal));
|
|
assert_eq!(x.cmp(&x), cmp::Ordering::Equal);
|
|
assert_eq!(x.cmp(&y), cmp::Ordering::Less);
|
|
|
|
// Check asymmetric
|
|
let x = VecType::try_from(&[5, 1]).unwrap();
|
|
let y = VecType::from_u64(2);
|
|
assert_eq!(x.cmp(&x), cmp::Ordering::Equal);
|
|
assert_eq!(x.cmp(&y), cmp::Ordering::Greater);
|
|
|
|
// Check when we use reverse ordering properly.
|
|
let x = VecType::try_from(&[5, 1, 9]).unwrap();
|
|
let y = VecType::try_from(&[6, 2, 8]).unwrap();
|
|
assert_eq!(x.cmp(&x), cmp::Ordering::Equal);
|
|
assert_eq!(x.cmp(&y), cmp::Ordering::Greater);
|
|
|
|
// Complex scenario, check it properly uses reverse ordering.
|
|
let x = VecType::try_from(&[0, 1, 9]).unwrap();
|
|
let y = VecType::try_from(&[4294967295, 0, 9]).unwrap();
|
|
assert_eq!(x.cmp(&x), cmp::Ordering::Equal);
|
|
assert_eq!(x.cmp(&y), cmp::Ordering::Greater);
|
|
}
|
|
|
|
#[test]
|
|
fn math_test() {
|
|
let mut x = VecType::try_from(&[0, 1, 9]).unwrap();
|
|
assert_eq!(x.is_normalized(), true);
|
|
x.try_push(0).unwrap();
|
|
assert_eq!(&*x, &[0, 1, 9, 0]);
|
|
assert_eq!(x.is_normalized(), false);
|
|
x.normalize();
|
|
assert_eq!(&*x, &[0, 1, 9]);
|
|
assert_eq!(x.is_normalized(), true);
|
|
|
|
x.add_small(1);
|
|
assert_eq!(&*x, &[1, 1, 9]);
|
|
x.add_small(LIMB_MAX);
|
|
assert_eq!(&*x, &[0, 2, 9]);
|
|
|
|
x.mul_small(3);
|
|
assert_eq!(&*x, &[0, 6, 27]);
|
|
x.mul_small(LIMB_MAX);
|
|
let expected: VecType = if bigint::LIMB_BITS == 32 {
|
|
vec_from_u32(&[0, 4294967290, 4294967274, 26])
|
|
} else {
|
|
vec_from_u32(&[0, 0, 4294967290, 4294967295, 4294967274, 4294967295, 26])
|
|
};
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
let mut x = VecType::from_u64(0xFFFFFFFF);
|
|
let y = VecType::from_u64(5);
|
|
x *= &y;
|
|
let expected: VecType = vec_from_u32(&[0xFFFFFFFB, 0x4]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Test with carry
|
|
let mut x = VecType::from_u64(1);
|
|
assert_eq!(&*x, &[1]);
|
|
x.add_small(LIMB_MAX);
|
|
assert_eq!(&*x, &[0, 1]);
|
|
}
|
|
|
|
#[test]
|
|
fn scalar_add_test() {
|
|
assert_eq!(bigint::scalar_add(5, 5), (10, false));
|
|
assert_eq!(bigint::scalar_add(LIMB_MAX, 1), (0, true));
|
|
}
|
|
|
|
#[test]
|
|
fn scalar_mul_test() {
|
|
assert_eq!(bigint::scalar_mul(5, 5, 0), (25, 0));
|
|
assert_eq!(bigint::scalar_mul(5, 5, 1), (26, 0));
|
|
assert_eq!(bigint::scalar_mul(LIMB_MAX, 2, 0), (LIMB_MAX - 1, 1));
|
|
}
|
|
|
|
#[test]
|
|
fn small_add_test() {
|
|
let mut x = VecType::from_u64(4294967295);
|
|
bigint::small_add(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[4, 1]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
let mut x = VecType::from_u64(5);
|
|
bigint::small_add(&mut x, 7);
|
|
let expected = VecType::from_u64(12);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Single carry, internal overflow
|
|
let mut x = VecType::from_u64(0x80000000FFFFFFFF);
|
|
bigint::small_add(&mut x, 7);
|
|
let expected: VecType = vec_from_u32(&[6, 0x80000001]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Double carry, overflow
|
|
let mut x = VecType::from_u64(0xFFFFFFFFFFFFFFFF);
|
|
bigint::small_add(&mut x, 7);
|
|
let expected: VecType = vec_from_u32(&[6, 0, 1]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn small_mul_test() {
|
|
// No overflow check, 1-int.
|
|
let mut x = VecType::from_u64(5);
|
|
bigint::small_mul(&mut x, 7);
|
|
let expected = VecType::from_u64(35);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// No overflow check, 2-ints.
|
|
let mut x = VecType::from_u64(0x4000000040000);
|
|
bigint::small_mul(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[0x00140000, 0x140000]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Overflow, 1 carry.
|
|
let mut x = VecType::from_u64(0x33333334);
|
|
bigint::small_mul(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[4, 1]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Overflow, 1 carry, internal.
|
|
let mut x = VecType::from_u64(0x133333334);
|
|
bigint::small_mul(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[4, 6]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Overflow, 2 carries.
|
|
let mut x = VecType::from_u64(0x3333333333333334);
|
|
bigint::small_mul(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[4, 0, 1]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn pow_test() {
|
|
let mut x = VecType::from_u64(1);
|
|
bigint::pow(&mut x, 2);
|
|
let expected = VecType::from_u64(25);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
let mut x = VecType::from_u64(1);
|
|
bigint::pow(&mut x, 15);
|
|
let expected: VecType = vec_from_u32(&[452807053, 7]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
let mut x = VecType::from_u64(1);
|
|
bigint::pow(&mut x, 16);
|
|
let expected: VecType = vec_from_u32(&[2264035265, 35]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
let mut x = VecType::from_u64(1);
|
|
bigint::pow(&mut x, 17);
|
|
let expected: VecType = vec_from_u32(&[2730241733, 177]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
let mut x = VecType::from_u64(1);
|
|
bigint::pow(&mut x, 302);
|
|
let expected: VecType = vec_from_u32(&[
|
|
2443090281, 2149694430, 2297493928, 1584384001, 1279504719, 1930002239, 3312868939,
|
|
3735173465, 3523274756, 2025818732, 1641675015, 2431239749, 4292780461, 3719612855,
|
|
4174476133, 3296847770, 2677357556, 638848153, 2198928114, 3285049351, 2159526706,
|
|
626302612,
|
|
]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn large_add_test() {
|
|
// Overflow, both single values
|
|
let mut x = VecType::from_u64(4294967295);
|
|
let y = VecType::from_u64(5);
|
|
bigint::large_add(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[4, 1]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// No overflow, single value
|
|
let mut x = VecType::from_u64(5);
|
|
let y = VecType::from_u64(7);
|
|
bigint::large_add(&mut x, &y);
|
|
let expected = VecType::from_u64(12);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Single carry, internal overflow
|
|
let mut x = VecType::from_u64(0x80000000FFFFFFFF);
|
|
let y = VecType::from_u64(7);
|
|
bigint::large_add(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[6, 0x80000001]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// 1st overflows, 2nd doesn't.
|
|
let mut x = VecType::from_u64(0x7FFFFFFFFFFFFFFF);
|
|
let y = VecType::from_u64(0x7FFFFFFFFFFFFFFF);
|
|
bigint::large_add(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[0xFFFFFFFE, 0xFFFFFFFF]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Both overflow.
|
|
let mut x = VecType::from_u64(0x8FFFFFFFFFFFFFFF);
|
|
let y = VecType::from_u64(0x7FFFFFFFFFFFFFFF);
|
|
bigint::large_add(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[0xFFFFFFFE, 0x0FFFFFFF, 1]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn large_mul_test() {
|
|
// Test by empty
|
|
let mut x = VecType::from_u64(0xFFFFFFFF);
|
|
let y = VecType::new();
|
|
bigint::large_mul(&mut x, &y);
|
|
let expected = VecType::new();
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Simple case
|
|
let mut x = VecType::from_u64(0xFFFFFFFF);
|
|
let y = VecType::from_u64(5);
|
|
bigint::large_mul(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[0xFFFFFFFB, 0x4]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Large u32, but still just as easy.
|
|
let mut x = VecType::from_u64(0xFFFFFFFF);
|
|
let y = VecType::from_u64(0xFFFFFFFE);
|
|
bigint::large_mul(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[0x2, 0xFFFFFFFD]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Let's multiply two large values together.
|
|
let mut x: VecType = vec_from_u32(&[0xFFFFFFFE, 0x0FFFFFFF, 1]);
|
|
let y: VecType = vec_from_u32(&[0x99999999, 0x99999999, 0xCCCD9999, 0xCCCC]);
|
|
bigint::large_mul(&mut x, &y);
|
|
let expected: VecType =
|
|
vec_from_u32(&[0xCCCCCCCE, 0x5CCCCCCC, 0x9997FFFF, 0x33319999, 0x999A7333, 0xD999]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn very_large_mul_test() {
|
|
// Test cases triggered to that would normally use `karatsuba_mul`.
|
|
// Karatsuba multiplication was ripped out, however, these are useful
|
|
// test cases.
|
|
let mut x: VecType = vec_from_u32(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
|
|
let y: VecType = vec_from_u32(&[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
|
|
bigint::large_mul(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[
|
|
4, 13, 28, 50, 80, 119, 168, 228, 300, 385, 484, 598, 728, 875, 1040, 1224, 1340, 1435,
|
|
1508, 1558, 1584, 1585, 1560, 1508, 1428, 1319, 1180, 1010, 808, 573, 304,
|
|
]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// Test cases triggered to that would normally use `karatsuba_uneven_mul`.
|
|
let mut x: VecType = vec_from_u32(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
|
|
let y: VecType = vec_from_u32(&[
|
|
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
|
28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
|
|
]);
|
|
bigint::large_mul(&mut x, &y);
|
|
let expected: VecType = vec_from_u32(&[
|
|
4, 13, 28, 50, 80, 119, 168, 228, 300, 385, 484, 598, 728, 875, 1040, 1224, 1360, 1496,
|
|
1632, 1768, 1904, 2040, 2176, 2312, 2448, 2584, 2720, 2856, 2992, 3128, 3264, 3400, 3536,
|
|
3672, 3770, 3829, 3848, 3826, 3762, 3655, 3504, 3308, 3066, 2777, 2440, 2054, 1618, 1131,
|
|
592,
|
|
]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn bit_length_test() {
|
|
let x: VecType = vec_from_u32(&[0, 0, 0, 1]);
|
|
assert_eq!(bigint::bit_length(&x), 97);
|
|
|
|
let x: VecType = vec_from_u32(&[0, 0, 0, 3]);
|
|
assert_eq!(bigint::bit_length(&x), 98);
|
|
|
|
let x = VecType::from_u64(1 << 31);
|
|
assert_eq!(bigint::bit_length(&x), 32);
|
|
}
|
|
|
|
#[test]
|
|
fn shl_bits_test() {
|
|
let mut x = VecType::from_u64(0xD2210408);
|
|
bigint::shl_bits(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[0x44208100, 0x1A]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn shl_limbs_test() {
|
|
let mut x = VecType::from_u64(0xD2210408);
|
|
bigint::shl_limbs(&mut x, 2);
|
|
let expected: VecType = if bigint::LIMB_BITS == 32 {
|
|
vec_from_u32(&[0, 0, 0xD2210408])
|
|
} else {
|
|
vec_from_u32(&[0, 0, 0, 0, 0xD2210408])
|
|
};
|
|
assert_eq!(&*x, &*expected);
|
|
}
|
|
|
|
#[test]
|
|
fn shl_test() {
|
|
// Pattern generated via `''.join(["1" +"0"*i for i in range(20)])`
|
|
let mut x = VecType::from_u64(0xD2210408);
|
|
bigint::shl(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[0x44208100, 0x1A]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
bigint::shl(&mut x, 32);
|
|
let expected: VecType = vec_from_u32(&[0, 0x44208100, 0x1A]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
bigint::shl(&mut x, 27);
|
|
let expected: VecType = vec_from_u32(&[0, 0, 0xD2210408]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
// 96-bits of previous pattern
|
|
let mut x: VecType = vec_from_u32(&[0x20020010, 0x8040100, 0xD2210408]);
|
|
bigint::shl(&mut x, 5);
|
|
let expected: VecType = vec_from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
bigint::shl(&mut x, 32);
|
|
let expected: VecType = vec_from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A]);
|
|
assert_eq!(&*x, &*expected);
|
|
|
|
bigint::shl(&mut x, 27);
|
|
let expected: VecType = vec_from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408]);
|
|
assert_eq!(&*x, &*expected);
|
|
}
|