#![allow(dead_code)]
use std::fmt;
use crossbeam_utils::atomic::AtomicCell;
pub use wasmer::{Array, FromToNativeWasmType, Memory, ValueType};
#[repr(transparent)]
pub struct WasmPtr<T: Copy, Ty = wasmer::Item>(wasmer::WasmPtr<T, Ty>);
unsafe impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> Copy for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
unsafe impl<T: Copy, Ty> FromToNativeWasmType for WasmPtr<T, Ty> {
type Native = <wasmer::WasmPtr<T, Ty> as FromToNativeWasmType>::Native;
fn to_native(self) -> Self::Native {
self.0.to_native()
}
fn from_native(n: Self::Native) -> Self {
Self(wasmer::WasmPtr::from_native(n))
}
}
impl<T: Copy, Ty> PartialEq for WasmPtr<T, Ty> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T: Copy, Ty> Eq for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> WasmPtr<T, Ty> {
#[inline(always)]
pub fn new(offset: u32) -> Self {
Self(wasmer::WasmPtr::new(offset))
}
#[inline(always)]
pub fn offset(self) -> u32 {
self.0.offset()
}
}
impl<T: Copy + ValueType> WasmPtr<T, wasmer::Item> {
#[inline(always)]
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a AtomicCell<T>> {
if self.0.offset() == 0 {
None
} else {
self.0.deref(memory)
}
}
#[inline(always)]
pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut AtomicCell<T>> {
if self.0.offset() == 0 {
None
} else {
self.0.deref_mut(memory)
}
}
}
impl<T: Copy + ValueType> WasmPtr<T, wasmer::Array> {
#[inline(always)]
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [AtomicCell<T>]> {
if self.0.offset() == 0 {
None
} else {
self.0.deref(memory, index, length)
}
}
#[inline]
pub unsafe fn deref_mut<'a>(
self,
memory: &'a Memory,
index: u32,
length: u32,
) -> Option<&'a mut [AtomicCell<T>]> {
if self.0.offset() == 0 {
None
} else {
self.0.deref_mut(memory, index, length)
}
}
#[inline(always)]
pub unsafe fn get_utf8_str<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
if self.0.offset() == 0 {
None
} else {
self.0.get_utf8_str(memory, str_len)
}
}
#[inline(always)]
pub fn get_utf8_string(self, memory: &Memory, str_len: u32) -> Option<String> {
if self.0.offset() == 0 {
None
} else {
self.0.get_utf8_string(memory, str_len)
}
}
}