From edda77cf7f4e9803a8f5bd7a9de50f08959d4133 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 13 Mar 2022 21:28:04 +0100 Subject: [PATCH] Reduced amount of null pointers in create_object Signed-off-by: trivernis --- src/lib.rs | 12 +++++++----- src/macros.rs | 16 ++++++++++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9d55232..d180548 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,9 @@ impl MultitraitObject { original_typeid: TypeId::of::(), traits: Default::default(), }; - this._register::(any_vtable); + unsafe { + this._register::(any_vtable); + } this } @@ -85,6 +87,7 @@ impl MultitraitObject { None } else { unsafe { + // SAFETY: We've checked the size of the pointer self._downcast_trait_mut::() } } @@ -96,6 +99,7 @@ impl MultitraitObject { None } else { unsafe { + // SAFETY: We've checked the size of the pointer self._downcast_boxed_trait::() } } @@ -146,14 +150,14 @@ impl MultitraitObject { #[doc(hidden)] #[inline] - pub fn _register(&mut self, vtable_ptr: *const ()) { + pub unsafe fn _register(&mut self, vtable_ptr: *const ()) { + // this function is considers unsafe as there is no validation of the given raw pointer self.traits.insert(TypeId::of::(), vtable_ptr); } #[doc(hidden)] #[inline] unsafe fn _downcast_trait(&self) -> Option<&T1> { - // SAFETY: Creating a fat pointer from the given v-table and data has no side effects let vptr = *self.traits.get(&TypeId::of::())?; let fat_pointer = FatPointer { data: self.data, vptr }; let value = std::mem::transmute::<_, &&T1>(&fat_pointer); @@ -164,7 +168,6 @@ impl MultitraitObject { #[doc(hidden)] #[inline] unsafe fn _downcast_trait_mut(&mut self) -> Option<&mut T1> { - // SAFETY: Creating a fat pointer from the given v-table and data has no side effects let vptr = *self.traits.get(&TypeId::of::())?; let mut fat_pointer = FatPointer { data: self.data, vptr }; let value = std::mem::transmute::<_, &mut &mut T1>(&mut fat_pointer); @@ -175,7 +178,6 @@ impl MultitraitObject { #[doc(hidden)] #[inline] unsafe fn _downcast_boxed_trait(&mut self) -> Option> { - // SAFETY: Creating a fat pointer from the given v-table and data has no side effects let vptr = *self.traits.get(&TypeId::of::())?; let fat_pointer = FatPointer { data: self.data, vptr }; let value = std::mem::transmute::<_, *const *mut T1>(&fat_pointer); diff --git a/src/macros.rs b/src/macros.rs index 854e07b..d0f78de 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -20,7 +20,10 @@ macro_rules! impl_trait_object { fn into_multitrait(self) -> $crate::MultitraitObject { let mut mto = $crate::MultitraitObject::new(self); $( - mto._register::<$trt>($crate::__fat_pointer!($obj as $trt).vptr); + unsafe { + // SAFETY: We're only passing v-tables associated with the given type + mto._register::<$trt>($crate::__fat_pointer!($obj as $trt).vptr); + } )* mto @@ -58,12 +61,13 @@ macro_rules! create_object { }; let mut mto = $crate::MultitraitObject::new($v); $( - let vptr = unsafe { + unsafe { // SAFETY: We're never accessing the null value - let ptr = $crate::null_ptr(&*null_ptr) as *const $t; - std::mem::transmute::<_, $crate::FatPointer>(ptr).vptr - }; - mto._register::<$t>(vptr); + let ptr = null_ptr as *const $t; + let vptr = std::mem::transmute::<_, $crate::FatPointer>(ptr).vptr; + // SAFETY: We're only passing v-tables associated with the given type + mto._register::<$t>(vptr); + } )+ mto }