use super::Instance;
use std::alloc::Layout;
use std::convert::TryFrom;
use std::ptr::{self, NonNull};
use std::sync::{Arc, Weak};
#[derive(Debug)]
#[repr(C)]
struct InstanceInner {
instance_layout: Layout,
instance: NonNull<Instance>,
}
impl InstanceInner {
unsafe fn deallocate_instance(&mut self) {
let instance_ptr = self.instance.as_ptr();
ptr::drop_in_place(instance_ptr);
std::alloc::dealloc(instance_ptr as *mut u8, self.instance_layout);
}
#[inline]
pub(crate) fn as_ref(&self) -> &Instance {
unsafe { self.instance.as_ref() }
}
#[inline]
pub(super) fn as_mut(&mut self) -> &mut Instance {
unsafe { self.instance.as_mut() }
}
}
impl PartialEq for InstanceInner {
fn eq(&self, other: &Self) -> bool {
self.instance == other.instance
}
}
impl Drop for InstanceInner {
fn drop(&mut self) {
unsafe { Self::deallocate_instance(self) };
}
}
unsafe impl Send for InstanceInner {}
unsafe impl Sync for InstanceInner {}
#[derive(Debug, PartialEq, Clone)]
pub struct InstanceRef(Arc<InstanceInner>);
impl InstanceRef {
pub(super) unsafe fn new(instance: NonNull<Instance>, instance_layout: Layout) -> Self {
Self(Arc::new(InstanceInner {
instance_layout,
instance,
}))
}
#[inline]
pub(crate) fn as_ref(&self) -> &Instance {
(&*self.0).as_ref()
}
#[inline]
pub(super) fn as_mut(&mut self) -> Option<&mut Instance> {
Some(Arc::get_mut(&mut self.0)?.as_mut())
}
}