Skip to content

Commit

Permalink
Remove most unsafe code (#162)
Browse files Browse the repository at this point in the history
The only remaining `unsafe` code is used to call SIMD intrinsics.

Co-authored-by: Tom Kaitchuck <tkaitchuck@users.noreply.github.com>
  • Loading branch information
joshlf and tkaitchuck committed Oct 20, 2023
1 parent 8332f50 commit a74829b
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 27 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -80,6 +80,7 @@ serde = { version = "1.0.117", optional = true }
cfg-if = "1.0"
atomic-polyfill = { version="1.0.1", optional=true}
getrandom = { version = "0.2.7", optional = true }
zerocopy = { version = "0.7.0", default-features = false, features = ["simd"] }

[target.'cfg(not(all(target_arch = "arm", target_os = "none")))'.dependencies]
once_cell = { version = "1.13.1", default-features = false, features = ["unstable", "alloc"] }
Expand Down
7 changes: 3 additions & 4 deletions src/convert.rs
Expand Up @@ -7,13 +7,13 @@ macro_rules! convert {
impl Convert<$b> for $a {
#[inline(always)]
fn convert(self) -> $b {
unsafe { core::mem::transmute::<$a, $b>(self) }
zerocopy::transmute!(self)
}
}
impl Convert<$a> for $b {
#[inline(always)]
fn convert(self) -> $a {
unsafe { core::mem::transmute::<$b, $a>(self) }
zerocopy::transmute!(self)
}
}
};
Expand Down Expand Up @@ -65,8 +65,7 @@ macro_rules! as_array {
{
#[inline(always)]
fn as_array<T>(slice: &[T]) -> &[T; $len] {
assert_eq!(slice.len(), $len);
unsafe { &*(slice.as_ptr() as *const [_; $len]) }
core::convert::TryFrom::try_from(slice).unwrap()
}
as_array($input)
}
Expand Down
8 changes: 2 additions & 6 deletions src/hash_quality_test.rs
Expand Up @@ -71,12 +71,8 @@ fn test_no_full_collisions<T: Hasher>(gen_hash: impl Fn() -> T) {
gen_combinations(&options, 7, Vec::new(), &mut combinations);
let mut map: HashMap<u64, Vec<u8>> = HashMap::new();
for combination in combinations {
let array = unsafe {
let (begin, middle, end) = combination.align_to::<u8>();
assert_eq!(0, begin.len());
assert_eq!(0, end.len());
middle.to_vec()
};
use zerocopy::AsBytes;
let array = combination.as_slice().as_bytes().to_vec();
let mut hasher = gen_hash();
hasher.write(&array);
let hash = hasher.finish();
Expand Down
29 changes: 12 additions & 17 deletions src/operations.rs
@@ -1,4 +1,5 @@
use crate::convert::*;
use zerocopy::transmute;

Check warning on line 2 in src/operations.rs

View workflow job for this annotation

GitHub Actions / Linux ARMv7

unused import: `zerocopy::transmute`

Check warning on line 2 in src/operations.rs

View workflow job for this annotation

GitHub Actions / thumbv6m

unused import: `zerocopy::transmute`

Check warning on line 2 in src/operations.rs

View workflow job for this annotation

GitHub Actions / wasm

unused import: `zerocopy::transmute`

///This constant comes from Kunth's prng (Empirically it works better than those from splitmix32).
pub(crate) const MULTIPLE: u64 = 6364136223846793005;
Expand Down Expand Up @@ -55,8 +56,7 @@ pub(crate) fn shuffle(a: u128) -> u128 {
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
use core::mem::transmute;
unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(SHUFFLE_MASK))) }
unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(SHUFFLE_MASK))) }
}
#[cfg(not(all(target_feature = "ssse3", not(miri))))]
{
Expand All @@ -81,13 +81,12 @@ pub(crate) fn shuffle_and_add(base: u128, to_add: u128) -> u128 {
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri)))]
#[inline(always)]
pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
use core::mem::transmute;
unsafe {
#[cfg(target_arch = "x86")]
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
transmute(_mm_add_epi64(transmute(a), transmute(b)))
transmute!(_mm_add_epi64(transmute!(a), transmute!(b)))
}
}

Expand All @@ -105,10 +104,9 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
use core::mem::transmute;
unsafe {
let value = transmute(value);
transmute(_mm_aesenc_si128(value, transmute(xor)))
let value = transmute!(value);
transmute!(_mm_aesenc_si128(value, transmute!(xor)))
}
}

Expand All @@ -125,10 +123,9 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
use core::arch::aarch64::*;
#[cfg(target_arch = "arm")]
use core::arch::arm::*;
use core::mem::transmute;
unsafe {
let value = transmute(value);
xor ^ transmute::<_, u128>(vaesmcq_u8(vaeseq_u8(value, transmute(0u128))))
let value = transmute!(value);
xor ^ transmute::<_, u128>(vaesmcq_u8(vaeseq_u8(value, transmute!(0u128))))
}
}

Expand All @@ -140,10 +137,9 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
use core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::*;
use core::mem::transmute;
unsafe {
let value = transmute(value);
transmute(_mm_aesdec_si128(value, transmute(xor)))
let value = transmute!(value);
transmute!(_mm_aesdec_si128(value, transmute!(xor)))
}
}

Expand All @@ -160,10 +156,9 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
use core::arch::aarch64::*;
#[cfg(target_arch = "arm")]
use core::arch::arm::*;
use core::mem::transmute;
unsafe {
let value = transmute(value);
xor ^ transmute::<_, u128>(vaesimcq_u8(vaesdq_u8(value, transmute(0u128))))
let value = transmute!(value);
xor ^ transmute::<_, u128>(vaesimcq_u8(vaesdq_u8(value, transmute!(0u128))))
}
}

Expand Down Expand Up @@ -207,7 +202,7 @@ mod test {
// #[cfg(target_arch = "x86_64")]
// use core::arch::x86_64::*;
// MASK.with(|mask| {
// unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(mask.get()))) }
// unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(mask.get()))) }
// })
// }
//
Expand Down

0 comments on commit a74829b

Please sign in to comment.