Skip to content

Commit a74829b

Browse files
joshlftkaitchuck
andauthored
Remove most unsafe code (tkaitchuck#162)
The only remaining `unsafe` code is used to call SIMD intrinsics. Co-authored-by: Tom Kaitchuck <tkaitchuck@users.noreply.github.com>
1 parent 8332f50 commit a74829b

File tree

4 files changed

+18
-27
lines changed

4 files changed

+18
-27
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ serde = { version = "1.0.117", optional = true }
8080
cfg-if = "1.0"
8181
atomic-polyfill = { version="1.0.1", optional=true}
8282
getrandom = { version = "0.2.7", optional = true }
83+
zerocopy = { version = "0.7.0", default-features = false, features = ["simd"] }
8384

8485
[target.'cfg(not(all(target_arch = "arm", target_os = "none")))'.dependencies]
8586
once_cell = { version = "1.13.1", default-features = false, features = ["unstable", "alloc"] }

src/convert.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ macro_rules! convert {
77
impl Convert<$b> for $a {
88
#[inline(always)]
99
fn convert(self) -> $b {
10-
unsafe { core::mem::transmute::<$a, $b>(self) }
10+
zerocopy::transmute!(self)
1111
}
1212
}
1313
impl Convert<$a> for $b {
1414
#[inline(always)]
1515
fn convert(self) -> $a {
16-
unsafe { core::mem::transmute::<$b, $a>(self) }
16+
zerocopy::transmute!(self)
1717
}
1818
}
1919
};
@@ -65,8 +65,7 @@ macro_rules! as_array {
6565
{
6666
#[inline(always)]
6767
fn as_array<T>(slice: &[T]) -> &[T; $len] {
68-
assert_eq!(slice.len(), $len);
69-
unsafe { &*(slice.as_ptr() as *const [_; $len]) }
68+
core::convert::TryFrom::try_from(slice).unwrap()
7069
}
7170
as_array($input)
7271
}

src/hash_quality_test.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,8 @@ fn test_no_full_collisions<T: Hasher>(gen_hash: impl Fn() -> T) {
7171
gen_combinations(&options, 7, Vec::new(), &mut combinations);
7272
let mut map: HashMap<u64, Vec<u8>> = HashMap::new();
7373
for combination in combinations {
74-
let array = unsafe {
75-
let (begin, middle, end) = combination.align_to::<u8>();
76-
assert_eq!(0, begin.len());
77-
assert_eq!(0, end.len());
78-
middle.to_vec()
79-
};
74+
use zerocopy::AsBytes;
75+
let array = combination.as_slice().as_bytes().to_vec();
8076
let mut hasher = gen_hash();
8177
hasher.write(&array);
8278
let hash = hasher.finish();

src/operations.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::convert::*;
2+
use zerocopy::transmute;
23

34
///This constant comes from Kunth's prng (Empirically it works better than those from splitmix32).
45
pub(crate) const MULTIPLE: u64 = 6364136223846793005;
@@ -55,8 +56,7 @@ pub(crate) fn shuffle(a: u128) -> u128 {
5556
use core::arch::x86::*;
5657
#[cfg(target_arch = "x86_64")]
5758
use core::arch::x86_64::*;
58-
use core::mem::transmute;
59-
unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(SHUFFLE_MASK))) }
59+
unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(SHUFFLE_MASK))) }
6060
}
6161
#[cfg(not(all(target_feature = "ssse3", not(miri))))]
6262
{
@@ -81,13 +81,12 @@ pub(crate) fn shuffle_and_add(base: u128, to_add: u128) -> u128 {
8181
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri)))]
8282
#[inline(always)]
8383
pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] {
84-
use core::mem::transmute;
8584
unsafe {
8685
#[cfg(target_arch = "x86")]
8786
use core::arch::x86::*;
8887
#[cfg(target_arch = "x86_64")]
8988
use core::arch::x86_64::*;
90-
transmute(_mm_add_epi64(transmute(a), transmute(b)))
89+
transmute!(_mm_add_epi64(transmute!(a), transmute!(b)))
9190
}
9291
}
9392

@@ -105,10 +104,9 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
105104
use core::arch::x86::*;
106105
#[cfg(target_arch = "x86_64")]
107106
use core::arch::x86_64::*;
108-
use core::mem::transmute;
109107
unsafe {
110-
let value = transmute(value);
111-
transmute(_mm_aesenc_si128(value, transmute(xor)))
108+
let value = transmute!(value);
109+
transmute!(_mm_aesenc_si128(value, transmute!(xor)))
112110
}
113111
}
114112

@@ -125,10 +123,9 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 {
125123
use core::arch::aarch64::*;
126124
#[cfg(target_arch = "arm")]
127125
use core::arch::arm::*;
128-
use core::mem::transmute;
129126
unsafe {
130-
let value = transmute(value);
131-
xor ^ transmute::<_, u128>(vaesmcq_u8(vaeseq_u8(value, transmute(0u128))))
127+
let value = transmute!(value);
128+
xor ^ transmute::<_, u128>(vaesmcq_u8(vaeseq_u8(value, transmute!(0u128))))
132129
}
133130
}
134131

@@ -140,10 +137,9 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
140137
use core::arch::x86::*;
141138
#[cfg(target_arch = "x86_64")]
142139
use core::arch::x86_64::*;
143-
use core::mem::transmute;
144140
unsafe {
145-
let value = transmute(value);
146-
transmute(_mm_aesdec_si128(value, transmute(xor)))
141+
let value = transmute!(value);
142+
transmute!(_mm_aesdec_si128(value, transmute!(xor)))
147143
}
148144
}
149145

@@ -160,10 +156,9 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 {
160156
use core::arch::aarch64::*;
161157
#[cfg(target_arch = "arm")]
162158
use core::arch::arm::*;
163-
use core::mem::transmute;
164159
unsafe {
165-
let value = transmute(value);
166-
xor ^ transmute::<_, u128>(vaesimcq_u8(vaesdq_u8(value, transmute(0u128))))
160+
let value = transmute!(value);
161+
xor ^ transmute::<_, u128>(vaesimcq_u8(vaesdq_u8(value, transmute!(0u128))))
167162
}
168163
}
169164

@@ -207,7 +202,7 @@ mod test {
207202
// #[cfg(target_arch = "x86_64")]
208203
// use core::arch::x86_64::*;
209204
// MASK.with(|mask| {
210-
// unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(mask.get()))) }
205+
// unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(mask.get()))) }
211206
// })
212207
// }
213208
//

0 commit comments

Comments
 (0)