2019-10-16 15:47:34 -07:00
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::mem::size_of;
|
2019-10-22 14:52:43 -07:00
|
|
|
use std::mem::transmute;
|
2019-11-15 16:21:34 -08:00
|
|
|
use std::mem::MaybeUninit;
|
2019-10-22 14:52:43 -07:00
|
|
|
use std::ops::Deref;
|
|
|
|
use std::ops::DerefMut;
|
2019-10-16 15:47:34 -07:00
|
|
|
|
2019-10-19 17:15:23 -07:00
|
|
|
pub use std::os::raw::c_int as int;
|
|
|
|
|
2019-10-16 15:47:34 -07:00
|
|
|
pub type Opaque = [usize; 0];
|
|
|
|
|
2019-10-17 16:46:54 -07:00
|
|
|
pub trait Delete
|
|
|
|
where
|
|
|
|
Self: Sized + 'static,
|
|
|
|
{
|
|
|
|
fn delete(&'static mut self) -> ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Pointer to object allocated on the C++ heap.
|
|
|
|
#[repr(transparent)]
|
2019-10-17 17:58:31 -07:00
|
|
|
#[derive(Debug)]
|
2019-10-17 16:46:54 -07:00
|
|
|
pub struct UniquePtr<T>(Option<&'static mut T>)
|
|
|
|
where
|
|
|
|
T: Delete;
|
|
|
|
|
2019-10-22 14:52:43 -07:00
|
|
|
impl<T> UniquePtr<T>
|
2019-10-17 16:46:54 -07:00
|
|
|
where
|
|
|
|
T: Delete,
|
|
|
|
{
|
2019-10-22 14:52:43 -07:00
|
|
|
pub fn null() -> Self {
|
|
|
|
Self(None)
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
|
|
|
|
2019-10-22 14:52:43 -07:00
|
|
|
pub fn new(r: &'static mut T) -> Self {
|
|
|
|
Self(Some(r))
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
|
|
|
|
2019-10-22 14:52:43 -07:00
|
|
|
pub unsafe fn from_raw(p: *mut T) -> Self {
|
|
|
|
transmute(p)
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
2019-11-15 16:21:34 -08:00
|
|
|
|
|
|
|
pub fn into_raw(self) -> *mut T {
|
|
|
|
unsafe { transmute(self) }
|
|
|
|
}
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
|
|
|
|
2019-10-22 14:52:43 -07:00
|
|
|
impl<T> Deref for UniquePtr<T>
|
2019-10-17 16:46:54 -07:00
|
|
|
where
|
|
|
|
T: Delete,
|
|
|
|
{
|
2019-10-22 14:52:43 -07:00
|
|
|
type Target = Option<&'static mut T>;
|
2019-10-17 16:46:54 -07:00
|
|
|
fn deref(&self) -> &Self::Target {
|
2019-10-22 14:52:43 -07:00
|
|
|
&self.0
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-22 14:52:43 -07:00
|
|
|
impl<T> DerefMut for UniquePtr<T>
|
2019-10-17 16:46:54 -07:00
|
|
|
where
|
|
|
|
T: Delete,
|
|
|
|
{
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
2019-10-22 14:52:43 -07:00
|
|
|
&mut self.0
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-22 14:52:43 -07:00
|
|
|
impl<T> Drop for UniquePtr<T>
|
2019-10-17 16:46:54 -07:00
|
|
|
where
|
|
|
|
T: Delete,
|
|
|
|
{
|
|
|
|
fn drop(&mut self) {
|
2019-10-22 20:00:26 -07:00
|
|
|
if let Some(v) = self.0.take() {
|
|
|
|
Delete::delete(v)
|
|
|
|
}
|
2019-10-17 16:46:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
#[repr(transparent)]
|
|
|
|
pub struct CxxVTable(pub *const Opaque);
|
|
|
|
|
2019-10-16 15:47:34 -07:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub struct RustVTable<DynT>(pub *const Opaque, pub PhantomData<DynT>);
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct FieldOffset<F>(usize, PhantomData<F>);
|
|
|
|
|
|
|
|
unsafe impl<F> Send for FieldOffset<F> where F: Send {}
|
|
|
|
unsafe impl<F> Sync for FieldOffset<F> where F: Sync {}
|
2019-10-20 16:10:40 -07:00
|
|
|
|
2019-10-16 15:47:34 -07:00
|
|
|
impl<F> Copy for FieldOffset<F> {}
|
|
|
|
|
|
|
|
impl<F> Clone for FieldOffset<F> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self(self.0, self.1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<F> FieldOffset<F> {
|
|
|
|
pub fn from_ptrs<E>(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::<F>()) <= (embedder_addr + size_of::<E>()));
|
2019-10-22 15:46:42 -07:00
|
|
|
Self(field_addr - embedder_addr, PhantomData)
|
2019-10-16 15:47:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn to_embedder<E>(self, field: &F) -> &E {
|
|
|
|
(((field as *const _ as usize) - self.0) as *const E)
|
|
|
|
.as_ref()
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn to_embedder_mut<E>(self, field: &mut F) -> &mut E {
|
|
|
|
(((field as *mut _ as usize) - self.0) as *mut E)
|
|
|
|
.as_mut()
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
2019-11-15 16:21:34 -08:00
|
|
|
|
|
|
|
pub(crate) trait ConstructOnStack
|
|
|
|
where
|
|
|
|
Self: Sized,
|
|
|
|
{
|
|
|
|
type Args;
|
|
|
|
|
|
|
|
// The `buf` parameter represents a pointer to uninitialized memory.
|
|
|
|
fn construct(buf: &mut MaybeUninit<Self>, args: &Self::Args);
|
|
|
|
fn destruct(buf: &mut Self);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) struct StackOnly<T>(MaybeUninit<T>)
|
|
|
|
where
|
|
|
|
T: ConstructOnStack;
|
|
|
|
|
|
|
|
impl<T> StackOnly<T>
|
|
|
|
where
|
|
|
|
T: ConstructOnStack,
|
|
|
|
{
|
|
|
|
unsafe fn uninit() -> Self {
|
|
|
|
Self(MaybeUninit::<T>::uninit())
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn init(&mut self, args: &T::Args) {
|
|
|
|
T::construct(&mut self.0, args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Deref for StackOnly<T>
|
|
|
|
where
|
|
|
|
T: ConstructOnStack,
|
|
|
|
{
|
|
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &T {
|
|
|
|
unsafe { &*(self as *const StackOnly<T> as *const T) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> DerefMut for StackOnly<T>
|
|
|
|
where
|
|
|
|
T: ConstructOnStack,
|
|
|
|
{
|
|
|
|
fn deref_mut(&mut self) -> &mut T {
|
|
|
|
unsafe { &mut *(self as *mut StackOnly<T> as *mut T) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Drop for StackOnly<T>
|
|
|
|
where
|
|
|
|
T: ConstructOnStack,
|
|
|
|
{
|
|
|
|
fn drop(&mut self) {
|
|
|
|
T::destruct(&mut *self)
|
|
|
|
}
|
|
|
|
}
|