Reduced amount of null pointers in create_object

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 3 years ago
parent db608c8eb1
commit edda77cf7f
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -63,7 +63,9 @@ impl MultitraitObject {
original_typeid: TypeId::of::<T>(), original_typeid: TypeId::of::<T>(),
traits: Default::default(), traits: Default::default(),
}; };
unsafe {
this._register::<dyn Any>(any_vtable); this._register::<dyn Any>(any_vtable);
}
this this
} }
@ -85,6 +87,7 @@ impl MultitraitObject {
None None
} else { } else {
unsafe { unsafe {
// SAFETY: We've checked the size of the pointer
self._downcast_trait_mut::<T1>() self._downcast_trait_mut::<T1>()
} }
} }
@ -96,6 +99,7 @@ impl MultitraitObject {
None None
} else { } else {
unsafe { unsafe {
// SAFETY: We've checked the size of the pointer
self._downcast_boxed_trait::<T1>() self._downcast_boxed_trait::<T1>()
} }
} }
@ -146,14 +150,14 @@ impl MultitraitObject {
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
pub fn _register<T2: 'static + ?Sized>(&mut self, vtable_ptr: *const ()) { pub unsafe fn _register<T2: 'static + ?Sized>(&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::<T2>(), vtable_ptr); self.traits.insert(TypeId::of::<T2>(), vtable_ptr);
} }
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
unsafe fn _downcast_trait<T1: 'static + ?Sized>(&self) -> Option<&T1> { unsafe fn _downcast_trait<T1: 'static + ?Sized>(&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::<T1>())?; let vptr = *self.traits.get(&TypeId::of::<T1>())?;
let fat_pointer = FatPointer { data: self.data, vptr }; let fat_pointer = FatPointer { data: self.data, vptr };
let value = std::mem::transmute::<_, &&T1>(&fat_pointer); let value = std::mem::transmute::<_, &&T1>(&fat_pointer);
@ -164,7 +168,6 @@ impl MultitraitObject {
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
unsafe fn _downcast_trait_mut<T1: 'static + ?Sized>(&mut self) -> Option<&mut T1> { unsafe fn _downcast_trait_mut<T1: 'static + ?Sized>(&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::<T1>())?; let vptr = *self.traits.get(&TypeId::of::<T1>())?;
let mut fat_pointer = FatPointer { data: self.data, vptr }; let mut fat_pointer = FatPointer { data: self.data, vptr };
let value = std::mem::transmute::<_, &mut &mut T1>(&mut fat_pointer); let value = std::mem::transmute::<_, &mut &mut T1>(&mut fat_pointer);
@ -175,7 +178,6 @@ impl MultitraitObject {
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
unsafe fn _downcast_boxed_trait<T1: 'static + ?Sized>(&mut self) -> Option<Box<T1>> { unsafe fn _downcast_boxed_trait<T1: 'static + ?Sized>(&mut self) -> Option<Box<T1>> {
// SAFETY: Creating a fat pointer from the given v-table and data has no side effects
let vptr = *self.traits.get(&TypeId::of::<T1>())?; let vptr = *self.traits.get(&TypeId::of::<T1>())?;
let fat_pointer = FatPointer { data: self.data, vptr }; let fat_pointer = FatPointer { data: self.data, vptr };
let value = std::mem::transmute::<_, *const *mut T1>(&fat_pointer); let value = std::mem::transmute::<_, *const *mut T1>(&fat_pointer);

@ -20,7 +20,10 @@ macro_rules! impl_trait_object {
fn into_multitrait(self) -> $crate::MultitraitObject { fn into_multitrait(self) -> $crate::MultitraitObject {
let mut mto = $crate::MultitraitObject::new(self); let mut mto = $crate::MultitraitObject::new(self);
$( $(
unsafe {
// SAFETY: We're only passing v-tables associated with the given type
mto._register::<$trt>($crate::__fat_pointer!($obj as $trt).vptr); mto._register::<$trt>($crate::__fat_pointer!($obj as $trt).vptr);
}
)* )*
mto mto
@ -58,12 +61,13 @@ macro_rules! create_object {
}; };
let mut mto = $crate::MultitraitObject::new($v); let mut mto = $crate::MultitraitObject::new($v);
$( $(
let vptr = unsafe { unsafe {
// SAFETY: We're never accessing the null value // SAFETY: We're never accessing the null value
let ptr = $crate::null_ptr(&*null_ptr) as *const $t; let ptr = null_ptr as *const $t;
std::mem::transmute::<_, $crate::FatPointer>(ptr).vptr 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._register::<$t>(vptr);
}
)+ )+
mto mto
} }

Loading…
Cancel
Save