202 lines
4.2 KiB
Rust
Executable File
202 lines
4.2 KiB
Rust
Executable File
use crate::ImmutableList;
|
|
use core::cmp::Ordering;
|
|
use core::hash::{Hash, Hasher};
|
|
use core::intrinsics::transmute;
|
|
use core::marker::PhantomData;
|
|
|
|
#[repr(C)]
|
|
pub struct ExternRef<T> {
|
|
p: u32,
|
|
resource_type: PhantomData<T>,
|
|
}
|
|
|
|
impl<T> ExternRef<T> {
|
|
pub fn is_null(&self) -> bool {
|
|
self.p == 0
|
|
}
|
|
|
|
pub(crate) fn get_internal_index(&self) -> u32 {
|
|
self.p
|
|
}
|
|
|
|
#[inline]
|
|
pub fn get_value(&self) -> Option<T>
|
|
where
|
|
T: ExternalReferenceType,
|
|
T: Sized,
|
|
T:,
|
|
{
|
|
T::instantiate_from_extern_value(*self)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn not_null(&self) -> T
|
|
where
|
|
T: ExternalReferenceType,
|
|
T: Sized,
|
|
T:,
|
|
{
|
|
T::instantiate_from_extern_value(*self).unwrap()
|
|
}
|
|
|
|
#[inline]
|
|
pub(crate) fn cast<TCast>(&self) -> ExternRef<TCast> {
|
|
ExternRef::<TCast> {
|
|
p: self.p,
|
|
resource_type: Default::default(),
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "mock_data")]
|
|
pub(crate) fn mock() -> Self {
|
|
Self {
|
|
p: 0,
|
|
resource_type: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> Clone for ExternRef<T> {
|
|
fn clone(&self) -> Self {
|
|
Self {
|
|
p: self.p,
|
|
resource_type: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> Copy for ExternRef<T> {}
|
|
|
|
impl<T> Eq for ExternRef<T> {}
|
|
|
|
impl<T> PartialEq<Self> for ExternRef<T> {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
u32::eq(&self.p, &other.p)
|
|
}
|
|
}
|
|
|
|
impl<T> PartialOrd<Self> for ExternRef<T> {
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
u32::partial_cmp(&self.p, &other.p)
|
|
}
|
|
}
|
|
|
|
impl<T> Ord for ExternRef<T> {
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
u32::cmp(&self.p, &other.p)
|
|
}
|
|
}
|
|
|
|
impl<T> Hash for ExternRef<T> {
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
self.p.hash(state)
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
pub struct VecExternRef<T> {
|
|
v: u64,
|
|
resource_type: PhantomData<T>,
|
|
}
|
|
|
|
impl<T> VecExternRef<T> {
|
|
pub fn is_null(&self) -> bool {
|
|
self.v == 0
|
|
}
|
|
|
|
pub(crate) fn get_internal_index(&self) -> u32 {
|
|
let v: (u32, u32) = unsafe { transmute(self.v) };
|
|
v.0
|
|
}
|
|
|
|
pub(crate) fn len(&self) -> u32 {
|
|
let v: (u32, u32) = unsafe { transmute(self.v) };
|
|
v.1
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
pub(crate) fn at(&self, index: u32) -> ExternRef<T> {
|
|
let p = unsafe { _vec_extern_ref_get_value(self.get_internal_index(), index) };
|
|
ExternRef {
|
|
p,
|
|
resource_type: Default::default(),
|
|
}
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
pub(crate) fn get_immutable_list(&self) -> ImmutableList<T>
|
|
where
|
|
T: Clone,
|
|
T: ExternalReferenceType,
|
|
{
|
|
ImmutableList::from_ref(*self)
|
|
}
|
|
}
|
|
|
|
impl<T> Clone for VecExternRef<T> {
|
|
fn clone(&self) -> Self {
|
|
Self {
|
|
v: self.v,
|
|
resource_type: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> Copy for VecExternRef<T> {}
|
|
|
|
impl<T> Eq for VecExternRef<T> {}
|
|
|
|
impl<T> PartialEq<Self> for VecExternRef<T> {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
u64::eq(&self.v, &other.v)
|
|
}
|
|
}
|
|
|
|
impl<T> PartialOrd<Self> for VecExternRef<T> {
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
u64::partial_cmp(&self.v, &other.v)
|
|
}
|
|
}
|
|
|
|
impl<T> Ord for VecExternRef<T> {
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
u64::cmp(&self.v, &other.v)
|
|
}
|
|
}
|
|
|
|
pub trait ExternalReferenceType {
|
|
fn from_extern_value(reference: ExternRef<Self>) -> Self
|
|
where
|
|
Self: Sized;
|
|
|
|
fn instantiate_from_extern_value(reference: ExternRef<Self>) -> Option<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
if reference.is_null() {
|
|
None
|
|
} else {
|
|
Some(Self::from_extern_value(reference))
|
|
}
|
|
}
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! impl_extern_ctor {
|
|
($name:ty) => {
|
|
impl $name {
|
|
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
|
Self { ptr }
|
|
}
|
|
pub(crate) fn ptr(&self) -> &ExternRef<Self> {
|
|
&self.ptr
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
extern "wasm" {
|
|
fn _vec_extern_ref_get_value(extern_ref: u32, index: u32) -> u32;
|
|
}
|