Use unsafe blocks in stdlib.h implementation

This commit is contained in:
sourceturner
2026-01-18 21:10:34 +01:00
parent 891eb61239
commit 59fb13ee2c
3 changed files with 228 additions and 195 deletions
+13 -10
View File
@@ -1,6 +1,9 @@
//! Helper functions for random() and friends, see https://pubs.opengroup.org/onlinepubs/7908799/xsh/initstate.html
// Ported from musl's implementation (src/prng/random.c)
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
platform::types::*,
sync::{Mutex, MutexGuard},
@@ -34,23 +37,23 @@ impl State {
/// To be called in any function that may read from X_PTR
pub unsafe fn ensure_x_ptr_init(&mut self) {
if self.x_ptr.is_null() {
let x_u32_ptr: *mut u32 = DEFAULT_X.get().cast::<u32>().add(1);
let x_u32_ptr: *mut u32 = unsafe { DEFAULT_X.get().cast::<u32>().add(1) };
self.x_ptr = x_u32_ptr.cast::<[u8; 4]>();
}
}
pub unsafe fn save(&mut self) -> *mut [u8; 4] {
self.ensure_x_ptr_init();
unsafe { self.ensure_x_ptr_init() };
let stash_value: u32 =
(u32::from(self.n) << 16) | (u32::from(self.i) << 8) | u32::from(self.j);
*self.x_ptr.offset(-1) = stash_value.to_ne_bytes();
self.x_ptr.offset(-1)
unsafe { *self.x_ptr.offset(-1) = stash_value.to_ne_bytes() };
unsafe { self.x_ptr.offset(-1) }
}
pub unsafe fn load(&mut self, state_ptr: *mut [u8; 4]) {
let stash_value = u32::from_ne_bytes(*state_ptr);
self.x_ptr = state_ptr.offset(1);
let stash_value = u32::from_ne_bytes(unsafe { *state_ptr });
self.x_ptr = unsafe { state_ptr.offset(1) };
/* This calculation of n does not have a bit mask in the musl
* original, in principle resulting in a u16, but obtaining a value
@@ -63,12 +66,12 @@ impl State {
}
pub unsafe fn seed(&mut self, seed: c_uint) {
self.ensure_x_ptr_init();
unsafe { self.ensure_x_ptr_init() };
let mut s = seed as u64;
if self.n == 0 {
*self.x_ptr = (s as u32).to_ne_bytes();
unsafe { *self.x_ptr = (s as u32).to_ne_bytes() };
} else {
self.i = if self.n == 31 || self.n == 7 { 3 } else { 1 };
@@ -79,11 +82,11 @@ impl State {
// Conversion will always succeed (value is a 32-bit right-
// shift of a 64-bit integer).
*self.x_ptr.add(k) = u32::try_from(s >> 32).unwrap().to_ne_bytes();
unsafe { *self.x_ptr.add(k) = u32::try_from(s >> 32).unwrap().to_ne_bytes() };
}
// ensure X contains at least one odd number
*self.x_ptr = (u32::from_ne_bytes(*self.x_ptr) | 1).to_ne_bytes();
unsafe { *self.x_ptr = (u32::from_ne_bytes(*self.x_ptr) | 1).to_ne_bytes() };
}
}
}