diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2020-04-05 14:22:59 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2020-04-05 14:22:59 +0200 |
commit | fff906a78ba545e77d087a82711b30bcc8e0d0c5 (patch) | |
tree | 27b6fef7478e694518b739e6c75692d41fe83f16 | |
parent | de9bc974a6b423b7f086af23e50c47a097dcd352 (diff) | |
download | neco-fff906a78ba545e77d087a82711b30bcc8e0d0c5.tar neco-fff906a78ba545e77d087a82711b30bcc8e0d0c5.zip |
Introduce SafePtr trait, cleanup
-rw-r--r-- | safe_libc/src/boxed.rs | 104 | ||||
-rw-r--r-- | src/main.rs | 31 |
2 files changed, 60 insertions, 75 deletions
diff --git a/safe_libc/src/boxed.rs b/safe_libc/src/boxed.rs index 625c5b0..fa3e45d 100644 --- a/safe_libc/src/boxed.rs +++ b/safe_libc/src/boxed.rs @@ -26,11 +26,40 @@ fn slice_len<T>(p: *const [T]) -> usize { unsafe { mem::transmute::<_, [usize; 2]>(p)[1] } } -pub struct CBox<T: ?Sized>(*mut T); +pub trait SafePtr { + fn safe_ptr(p: *mut Self) -> *mut Self; +} + +impl<T> SafePtr for T { + #[inline] + fn safe_ptr(p: *mut T) -> *mut T { + if util::zst::<T>(1) { + return dangling(); + } + + debug_assert!(!p.is_null(), "NULL ptr"); + p + } +} + +impl<T> SafePtr for [T] { + #[inline] + fn safe_ptr(p: *mut [T]) -> *mut [T] { + let len = slice_len(p); + if util::zst::<T>(len) { + return ptr::slice_from_raw_parts_mut(dangling(), len); + } -impl<T: ?Sized> CBox<T> { + debug_assert!(!p.is_null(), "NULL ptr"); + p + } +} + +pub struct CBox<T: SafePtr + ?Sized>(*mut T); + +impl<T: SafePtr + ?Sized> CBox<T> { #[inline] - pub const unsafe fn from_raw_unchecked(p: *mut T) -> CBox<T> { + pub unsafe fn from_raw_unchecked(p: *mut T) -> CBox<T> { CBox(p) } @@ -42,7 +71,7 @@ impl<T: ?Sized> CBox<T> { } #[inline] - pub const fn as_ptr(&self) -> *const T { + pub fn as_ptr(&self) -> *const T { self.0 } @@ -78,32 +107,9 @@ impl<T> CBox<T> { util::check_ptr(p, len); CBox::slice_from_raw_parts_unchecked(p, len) } - - #[inline] - fn safe_ptr(&self) -> *mut T { - if util::zst::<T>(1) { - return dangling(); - } - - debug_assert!(!self.0.is_null(), "NULL ptr"); - self.0 - } -} - -impl<T> CBox<[T]> { - #[inline] - fn safe_ptr(&self) -> *mut [T] { - if self.0.is_null() { - let len = slice_len(self.0); - debug_assert!(util::zst::<T>(len), "NULL ptr"); - return ptr::slice_from_raw_parts_mut(dangling(), len); - } - - self.0 - } } -impl<T: ?Sized> Drop for CBox<T> { +impl<T: SafePtr + ?Sized> Drop for CBox<T> { #[inline] fn drop(&mut self) { unsafe { @@ -113,60 +119,30 @@ impl<T: ?Sized> Drop for CBox<T> { } } -impl<T> Deref for CBox<T> { +impl<T: SafePtr + ?Sized> Deref for CBox<T> { type Target = T; #[inline] fn deref(&self) -> &T { - unsafe { &*self.safe_ptr() } + unsafe { &*T::safe_ptr(self.0) } } } -impl<T> DerefMut for CBox<T> { +impl<T: SafePtr + ?Sized> DerefMut for CBox<T> { #[inline] fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.safe_ptr() } - } -} - -impl<T> Deref for CBox<[T]> { - type Target = [T]; - - #[inline] - fn deref(&self) -> &[T] { - unsafe { &*self.safe_ptr() } - } -} - -impl<T> DerefMut for CBox<[T]> { - #[inline] - fn deref_mut(&mut self) -> &mut [T] { - unsafe { &mut *self.safe_ptr() } - } -} - -impl<T: fmt::Debug> fmt::Debug for CBox<T> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) + unsafe { &mut *T::safe_ptr(self.0) } } } -impl<T> fmt::Debug for CBox<[T]> where [T]: fmt::Debug { +impl<T: fmt::Debug + SafePtr + ?Sized> fmt::Debug for CBox<T> { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } -impl<T: fmt::Display> fmt::Display for CBox<T> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<T> fmt::Display for CBox<[T]> where [T]: fmt::Display { +impl<T: fmt::Display + SafePtr + ?Sized> fmt::Display for CBox<T> { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&**self, f) diff --git a/src/main.rs b/src/main.rs index 944b7ab..c79f1da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,17 +9,26 @@ use core::fmt::Write; #[no_mangle] pub extern "C" fn main(_nargs: libc::c_int, _args: *const *const libc::c_char) -> libc::c_int { let mut stdout = unsafe { libc::stdio::stdout() }; - let x = libc::string::CString::from("foo"); - let l = x.len(); - let y = x.into_raw(); - let z = unsafe { - libc::boxed::CBox::slice_from_raw_parts(y, l) - }; - let foo = cstr!("Foo!\n"); - stdout.puts(foo); - let _ = writeln!(stdout, "Foo: {} {} {}", z[0], z[1], z[2]); - let b = libc::boxed::CBox::new(42); - let _ = writeln!(stdout, "Bar: {}", b); + + { + let foo = cstr!("Foo!\n"); + stdout.puts(foo); + } + + { + let x = libc::string::CString::from("foo"); + let l = x.len(); + let y = x.into_raw(); + let z = unsafe { + libc::boxed::CBox::slice_from_raw_parts(y, l) + }; + let _ = writeln!(stdout, "Foo: {} {} {}", z[0], z[1], z[2]); + } + + { + let b = libc::boxed::CBox::new(42); + let _ = writeln!(stdout, "Bar: {}", b); + } 0 } |