0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-02-15 10:05:55 -05:00
denoland-rusty-v8/src/support.rs

280 lines
5.2 KiB
Rust
Raw Normal View History

2019-10-16 15:47:34 -07:00
use std::marker::PhantomData;
2019-11-20 13:34:32 -08:00
use std::mem::replace;
2019-10-16 15:47:34 -07:00
use std::mem::size_of;
2019-10-22 14:52:43 -07:00
use std::mem::transmute;
use std::ops::Deref;
use std::ops::DerefMut;
2019-11-20 13:34:32 -08:00
use std::ptr::NonNull;
2019-10-16 15:47:34 -07:00
// TODO use libc::intptr_t when stable.
// https://doc.rust-lang.org/1.7.0/libc/type.intptr_t.html
#[allow(non_camel_case_types)]
pub type intptr_t = isize;
2019-12-04 08:03:17 +01:00
pub use std::os::raw::c_char as char;
2019-10-19 17:15:23 -07:00
pub use std::os::raw::c_int as int;
pub use std::os::raw::c_long as long;
2019-10-19 17:15:23 -07:00
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) -> ();
}
2019-11-20 13:34:32 -08:00
/// Pointer to object allocated on the C++ heap. The pointer may be null.
2019-10-17 16:46:54 -07:00
#[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
}
pub fn into_raw(self) -> *mut T {
unsafe { transmute(self) }
}
2019-11-20 13:34:32 -08:00
pub fn unwrap(self) -> UniqueRef<T> {
let p = self.into_raw();
assert!(!p.is_null());
unsafe { UniqueRef::from_raw(p) }
}
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
}
}
2019-11-20 13:34:32 -08:00
/// Pointer to object allocated on the C++ heap. The pointer may not be null.
#[repr(transparent)]
#[derive(Debug)]
pub struct UniqueRef<T>(&'static mut T)
where
T: Delete;
impl<T> UniqueRef<T>
where
T: Delete,
{
pub fn new(r: &'static mut T) -> Self {
Self(r)
}
pub unsafe fn from_raw(p: *mut T) -> Self {
transmute(NonNull::new(p))
}
pub fn into_raw(self) -> *mut T {
unsafe { transmute(self) }
}
}
impl<T> Deref for UniqueRef<T>
where
T: Delete,
{
type Target = &'static mut T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for UniqueRef<T>
where
T: Delete,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> Drop for UniqueRef<T>
where
T: Delete,
{
fn drop(&mut self) {
let inner = replace(&mut self.0, unsafe {
transmute(NonNull::<&'static mut T>::dangling())
});
Delete::delete(inner)
}
}
pub trait Shared
where
Self: Sized + 'static,
{
fn deref(shared_ptr: *const SharedRef<Self>) -> *mut Self;
fn reset(shared_ptr: *mut SharedRef<Self>);
fn use_count(shared_ptr: *const SharedRef<Self>) -> long;
}
/// Wrapper around a C++ shared_ptr. The shared_ptr is assumed to contain a
/// value and not be null.
#[repr(C)]
#[derive(Debug)]
pub struct SharedRef<T>([*mut Opaque; 2], PhantomData<T>)
where
T: Shared;
impl<T> SharedRef<T>
where
T: Shared,
{
pub fn use_count(&self) -> long {
<T as Shared>::use_count(self)
}
}
unsafe impl<T> Send for SharedRef<T> where T: Shared + Send {}
impl<T> Deref for SharedRef<T>
where
T: Shared,
{
// TODO: Maybe this should deref to UnsafeCell<T>?
type Target = T;
fn deref(&self) -> &T {
unsafe { &*<T as Shared>::deref(self) }
}
}
impl<T> DerefMut for SharedRef<T>
where
T: Shared,
{
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *<T as Shared>::deref(self) }
}
}
impl<T> Drop for SharedRef<T>
where
T: Shared,
{
fn drop(&mut self) {
<T as Shared>::reset(self);
}
}
#[repr(C)]
#[derive(Debug, PartialEq)]
pub enum MaybeBool {
JustFalse = 0,
JustTrue = 1,
Nothing = 2,
}
impl Into<Option<bool>> for MaybeBool {
fn into(self) -> Option<bool> {
match self {
MaybeBool::JustFalse => Some(false),
MaybeBool::JustTrue => Some(true),
MaybeBool::Nothing => None,
}
}
}
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()
}
}
#[repr(C)]
#[derive(Default)]
pub struct Maybe<T> {
has_value: bool,
value: T,
}
impl<T> Into<Option<T>> for Maybe<T> {
fn into(self) -> Option<T> {
if self.has_value {
Some(self.value)
} else {
None
}
}
}