//! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0 //! This is a common assumption in Emscripten code // this is a wrapper with extra logic around the runtime-core `WasmPtr`, so we // don't want to warn about unusued code here #![allow(dead_code)] use std::{cell::Cell, fmt}; pub use wasmer_runtime_core::memory::ptr::Array; use wasmer_runtime_core::{ memory::{ptr, Memory}, types::{ValueType, WasmExternType}, }; #[repr(transparent)] pub struct WasmPtr(ptr::WasmPtr); unsafe impl ValueType for WasmPtr {} impl Copy for WasmPtr {} impl Clone for WasmPtr { fn clone(&self) -> Self { Self(self.0.clone()) } } impl fmt::Debug for WasmPtr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } unsafe impl WasmExternType for WasmPtr { type Native = as WasmExternType>::Native; fn to_native(self) -> Self::Native { self.0.to_native() } fn from_native(n: Self::Native) -> Self { Self(ptr::WasmPtr::from_native(n)) } } impl PartialEq for WasmPtr { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl Eq for WasmPtr {} impl WasmPtr { #[inline(always)] pub fn new(offset: u32) -> Self { Self(ptr::WasmPtr::new(offset)) } #[inline(always)] pub fn offset(self) -> u32 { self.0.offset() } } impl WasmPtr { #[inline(always)] pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell> { 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 Cell> { if self.0.offset() == 0 { None } else { self.0.deref_mut(memory) } } } impl WasmPtr { #[inline(always)] pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell]> { 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 [Cell]> { if self.0.offset() == 0 { None } else { self.0.deref_mut(memory, index, length) } } #[inline(always)] pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> { if self.0.offset() == 0 { None } else { self.0.get_utf8_string(memory, str_len) } } }