mirror of
https://github.com/Noratrieb/safe-stuff.git
synced 2026-01-14 16:35:05 +01:00
bad things, ignore pls
This commit is contained in:
parent
83f4ce6f51
commit
fc2325731e
3 changed files with 99 additions and 15 deletions
48
src/lib.rs
48
src/lib.rs
|
|
@ -2,13 +2,57 @@
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
|
pub mod ptr;
|
||||||
mod strategy;
|
mod strategy;
|
||||||
|
|
||||||
pub use stuff::Backend;
|
pub use stuff::Backend;
|
||||||
|
|
||||||
use crate::strategy::{SafeStrategyAdaptor, SafeStuffingStrategy};
|
use crate::strategy::{SafeStrategyAdaptor, SafeStuffingStrategy};
|
||||||
|
|
||||||
pub struct StuffedPtr<T, S, B = usize>(stuff::StuffedPtr<T, SafeStrategyAdaptor<S>, B>)
|
pub struct SafeStuffedPtr<T, S, B = usize>(stuff::StuffedPtr<T, SafeStrategyAdaptor<S>, B>)
|
||||||
where
|
where
|
||||||
S: SafeStuffingStrategy<B>,
|
S: SafeStuffingStrategy<B>,
|
||||||
B: Backend<T>;
|
B: Backend<T>,
|
||||||
|
B: TryInto<usize>,
|
||||||
|
usize: TryInto<B>;
|
||||||
|
|
||||||
|
impl<T, S, B> SafeStuffedPtr<T, S, B>
|
||||||
|
where
|
||||||
|
S: SafeStuffingStrategy<B>,
|
||||||
|
B: Backend<T>,
|
||||||
|
B: TryInto<usize>,
|
||||||
|
usize: TryInto<B>,
|
||||||
|
{
|
||||||
|
pub fn new_ptr(ptr: *mut T) -> Self {
|
||||||
|
Self(stuff::StuffedPtr::new_ptr(ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_extra(ptr: *mut T) -> Self {
|
||||||
|
Self(stuff::StuffedPtr::new_ptr(ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_ptr(&self) -> Option<*const T> {
|
||||||
|
self.0.get_ptr().map(|ptr| ptr as *const _)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut_ptr(&mut self) -> Option<*mut T> {
|
||||||
|
self.0.get_ptr()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_other(self) -> Option<S::Other> {
|
||||||
|
self.0.into_other()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S, B> SafeStuffedPtr<T, S, B>
|
||||||
|
where
|
||||||
|
S: SafeStuffingStrategy<B>,
|
||||||
|
B: Backend<T>,
|
||||||
|
B: TryInto<usize>,
|
||||||
|
usize: TryInto<B>,
|
||||||
|
S::Other: Copy,
|
||||||
|
{
|
||||||
|
pub fn copy_other(&self) -> Option<S::Other> {
|
||||||
|
self.0.copy_other()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
38
src/ptr.rs
Normal file
38
src/ptr.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/// # Safety
|
||||||
|
/// Same invariants as [`stuff::StuffingStrategy]
|
||||||
|
pub unsafe trait PtrStuffingStrategy: sealed::Sealed {
|
||||||
|
fn stuff_ptr(addr: usize) -> usize;
|
||||||
|
fn extract_ptr(addr: usize) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod sealed {
|
||||||
|
pub trait Sealed {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Identity;
|
||||||
|
|
||||||
|
impl sealed::Sealed for Identity {}
|
||||||
|
|
||||||
|
unsafe impl PtrStuffingStrategy for Identity {
|
||||||
|
fn stuff_ptr(addr: usize) -> usize {
|
||||||
|
addr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_ptr(addr: usize) -> usize {
|
||||||
|
addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mask1<const MASK: usize>;
|
||||||
|
|
||||||
|
impl<const MASK: usize> sealed::Sealed for Mask1<MASK> {}
|
||||||
|
|
||||||
|
unsafe impl<const MASK: usize> PtrStuffingStrategy for Mask1<MASK> {
|
||||||
|
fn stuff_ptr(addr: usize) -> usize {
|
||||||
|
addr & MASK
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_ptr(addr: usize) -> usize {
|
||||||
|
addr & !MASK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use stuff::Backend;
|
use crate::ptr::PtrStuffingStrategy;
|
||||||
|
|
||||||
pub trait SafeStuffingStrategy<B> {
|
pub trait SafeStuffingStrategy<B> {
|
||||||
type Extra;
|
type Other;
|
||||||
|
|
||||||
fn stuff_extra(extra: &Self::Extra) -> B;
|
fn stuff_other(extra: &Self::Other) -> B;
|
||||||
|
|
||||||
fn extract_extra(addr: B) -> Option<Self::Extra>;
|
fn extract_other(addr: B) -> Option<Self::Other>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An internal type to convert from the safe to the unsafe trait
|
/// An internal type to convert from the safe to the unsafe trait
|
||||||
|
|
@ -19,28 +19,30 @@ pub(crate) struct SafeStrategyAdaptor<S>(PhantomData<S>);
|
||||||
unsafe impl<S, B> stuff::StuffingStrategy<B> for SafeStrategyAdaptor<S>
|
unsafe impl<S, B> stuff::StuffingStrategy<B> for SafeStrategyAdaptor<S>
|
||||||
where
|
where
|
||||||
S: SafeStuffingStrategy<B>,
|
S: SafeStuffingStrategy<B>,
|
||||||
|
B: TryInto<usize>,
|
||||||
|
usize: TryInto<B>,
|
||||||
{
|
{
|
||||||
type Extra = S::Extra;
|
type Other = S::Other;
|
||||||
|
|
||||||
fn is_extra(data: B) -> bool {
|
fn is_other(data: B) -> bool {
|
||||||
S::extract_extra(data).is_some()
|
S::extract_other(data).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stuff_extra(inner: Self::Extra) -> B {
|
fn stuff_other(inner: Self::Other) -> B {
|
||||||
let b = S::stuff_extra(&inner);
|
let b = S::stuff_other(&inner);
|
||||||
core::mem::forget(inner);
|
core::mem::forget(inner);
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn extract_extra(data: B) -> Self::Extra {
|
unsafe fn extract_other(data: B) -> Self::Other {
|
||||||
S::extract_extra(data).unwrap()
|
S::extract_other(data).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stuff_ptr(addr: usize) -> B {
|
fn stuff_ptr(addr: usize) -> B {
|
||||||
addr
|
addr.try_into().unwrap_or_else(|_| panic!())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_ptr(inner: B) -> usize {
|
fn extract_ptr(inner: B) -> usize {
|
||||||
inner
|
inner.try_into().unwrap_or_else(|_| panic!())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue