use std::marker::PhantomData; use std::mem::size_of; use std::mem::transmute; use std::mem::MaybeUninit; use std::ops::Deref; use std::ops::DerefMut; pub use std::os::raw::c_int as int; pub type Opaque = [usize; 0]; pub trait Delete where Self: Sized + 'static, { fn delete(&'static mut self) -> (); } /// Pointer to object allocated on the C++ heap. #[repr(transparent)] #[derive(Debug)] pub struct UniquePtr(Option<&'static mut T>) where T: Delete; impl UniquePtr where T: Delete, { pub fn null() -> Self { Self(None) } pub fn new(r: &'static mut T) -> Self { Self(Some(r)) } pub unsafe fn from_raw(p: *mut T) -> Self { transmute(p) } pub fn into_raw(self) -> *mut T { unsafe { transmute(self) } } } impl Deref for UniquePtr where T: Delete, { type Target = Option<&'static mut T>; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for UniquePtr where T: Delete, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl Drop for UniquePtr where T: Delete, { fn drop(&mut self) { if let Some(v) = self.0.take() { Delete::delete(v) } } } #[derive(Copy, Clone, Debug)] #[repr(transparent)] pub struct CxxVTable(pub *const Opaque); #[derive(Copy, Clone, Debug)] pub struct RustVTable(pub *const Opaque, pub PhantomData); #[derive(Debug)] pub struct FieldOffset(usize, PhantomData); unsafe impl Send for FieldOffset where F: Send {} unsafe impl Sync for FieldOffset where F: Sync {} impl Copy for FieldOffset {} impl Clone for FieldOffset { fn clone(&self) -> Self { Self(self.0, self.1) } } impl FieldOffset { pub fn from_ptrs(embedder_ptr: *const E, field_ptr: *const F) -> Self { let embedder_addr = embedder_ptr as usize; let field_addr = field_ptr as usize; assert!(field_addr >= embedder_addr); assert!((field_addr + size_of::()) <= (embedder_addr + size_of::())); Self(field_addr - embedder_addr, PhantomData) } pub unsafe fn to_embedder(self, field: &F) -> &E { (((field as *const _ as usize) - self.0) as *const E) .as_ref() .unwrap() } pub unsafe fn to_embedder_mut(self, field: &mut F) -> &mut E { (((field as *mut _ as usize) - self.0) as *mut E) .as_mut() .unwrap() } } pub(crate) trait ConstructOnStack where Self: Sized, { type Args; // The `buf` parameter represents a pointer to uninitialized memory. fn construct(buf: &mut MaybeUninit, args: &Self::Args); fn destruct(buf: &mut Self); } pub(crate) struct StackOnly(MaybeUninit) where T: ConstructOnStack; impl StackOnly where T: ConstructOnStack, { unsafe fn uninit() -> Self { Self(MaybeUninit::::uninit()) } unsafe fn init(&mut self, args: &T::Args) { T::construct(&mut self.0, args); } } impl Deref for StackOnly where T: ConstructOnStack, { type Target = T; fn deref(&self) -> &T { unsafe { &*(self as *const StackOnly as *const T) } } } impl DerefMut for StackOnly where T: ConstructOnStack, { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *(self as *mut StackOnly as *mut T) } } } impl Drop for StackOnly where T: ConstructOnStack, { fn drop(&mut self) { T::destruct(&mut *self) } }