Skip to content

Commit

Permalink
Merge pull request #1349 from joshlf/remove-unsafe
Browse files Browse the repository at this point in the history
Use zerocopy to replace some unsafe code
  • Loading branch information
vks committed Nov 2, 2023
2 parents 240cd43 + 5216f9a commit 870c679
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 18 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -43,7 +43,7 @@ alloc = ["rand_core/alloc"]
getrandom = ["rand_core/getrandom"]

# Option (requires nightly Rust): experimental SIMD support
simd_support = []
simd_support = ["zerocopy/simd-nightly"]

# Option (enabled by default): enable StdRng
std_rng = ["rand_chacha"]
Expand All @@ -69,6 +69,7 @@ rand_core = { path = "rand_core", version = "0.7.0" }
log = { version = "0.4.4", optional = true }
serde = { version = "1.0.103", features = ["derive"], optional = true }
rand_chacha = { path = "rand_chacha", version = "0.4.0", default-features = false, optional = true }
zerocopy = { version = "0.7.20", default-features = false, features = ["simd"] }

[target.'cfg(unix)'.dependencies]
# Used for fork protection (reseeding.rs)
Expand Down
1 change: 1 addition & 0 deletions rand_core/Cargo.toml
Expand Up @@ -32,3 +32,4 @@ serde1 = ["serde"] # enables serde for BlockRng wrapper
[dependencies]
serde = { version = "1", features = ["derive"], optional = true }
getrandom = { version = "0.2", optional = true }
zerocopy = { version = "0.7.20", default-features = false }
18 changes: 3 additions & 15 deletions rand_core/src/impls.rs
Expand Up @@ -19,6 +19,7 @@

use crate::RngCore;
use core::cmp::min;
use zerocopy::AsBytes;

/// Implement `next_u64` via `next_u32`, little-endian order.
pub fn next_u64_via_u32<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
Expand Down Expand Up @@ -52,31 +53,18 @@ pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
}
}

trait Observable: Copy {
trait Observable: AsBytes + Copy {
fn to_le(self) -> Self;

// Contract: observing self is memory-safe (implies no uninitialised padding)
fn as_byte_slice(x: &[Self]) -> &[u8];
}
impl Observable for u32 {
fn to_le(self) -> Self {
self.to_le()
}
fn as_byte_slice(x: &[Self]) -> &[u8] {
let ptr = x.as_ptr() as *const u8;
let len = x.len() * core::mem::size_of::<Self>();
unsafe { core::slice::from_raw_parts(ptr, len) }
}
}
impl Observable for u64 {
fn to_le(self) -> Self {
self.to_le()
}
fn as_byte_slice(x: &[Self]) -> &[u8] {
let ptr = x.as_ptr() as *const u8;
let len = x.len() * core::mem::size_of::<Self>();
unsafe { core::slice::from_raw_parts(ptr, len) }
}
}

/// Fill dest from src
Expand All @@ -98,7 +86,7 @@ fn fill_via_chunks<T: Observable>(src: &mut [T], dest: &mut [u8]) -> (usize, usi
}
}

dest[..byte_len].copy_from_slice(&T::as_byte_slice(&src[..num_chunks])[..byte_len]);
dest[..byte_len].copy_from_slice(&<[T]>::as_bytes(&src[..num_chunks])[..byte_len]);

(num_chunks, byte_len)
}
Expand Down
3 changes: 1 addition & 2 deletions src/distributions/integer.rs
Expand Up @@ -134,8 +134,7 @@ macro_rules! x86_intrinsic_impl {
let mut buf = [0_u8; mem::size_of::<$intrinsic>()];
rng.fill_bytes(&mut buf);
// x86 is little endian so no need for conversion
// SAFETY: we know [u8; N] and $intrinsic have the same size
unsafe { mem::transmute_copy(&buf) }
zerocopy::transmute!(buf)
}
}
)+};
Expand Down

0 comments on commit 870c679

Please sign in to comment.