use crate::syscalls::types::{__wasi_errno_t, __WASI_EFAULT}; use std::{cell::Cell, fmt, marker::PhantomData, mem}; use wasmer_runtime_core::{ memory::Memory, types::{Type, ValueType, WasmExternType}, }; pub struct Array; pub struct Item; #[repr(transparent)] pub struct WasmPtr { offset: u32, _phantom: PhantomData<(T, Ty)>, } impl WasmPtr { #[inline] pub fn new(offset: u32) -> Self { Self { offset, _phantom: PhantomData, } } #[inline] pub fn offset(self) -> u32 { self.offset } } impl WasmPtr { #[inline] pub fn deref<'a>(self, memory: &'a Memory) -> Result<&'a Cell, __wasi_errno_t> { if (self.offset as usize) + mem::size_of::() >= memory.size().bytes().0 { return Err(__WASI_EFAULT); } unsafe { let aligner = |ptr: usize, align: usize| ptr & !(align - 1); let cell_ptr = aligner( memory.view::().as_ptr().add(self.offset as usize) as usize, mem::align_of::(), ) as *const Cell; Ok(&*cell_ptr) } } } impl WasmPtr { #[inline] pub fn deref<'a>( self, memory: &'a Memory, index: u32, length: u32, ) -> Result<&'a [Cell], __wasi_errno_t> { if (self.offset as usize) + (mem::size_of::() * ((index + length) as usize)) >= memory.size().bytes().0 { return Err(__WASI_EFAULT); } unsafe { let cell_ptrs = memory.view::().get_unchecked( ((self.offset as usize) / mem::size_of::()) + (index as usize) ..((self.offset() as usize) / mem::size_of::()) + ((index + length) as usize), ) as *const _; Ok(&*cell_ptrs) } } } unsafe impl WasmExternType for WasmPtr { const TYPE: Type = Type::I32; fn to_bits(self) -> u64 { self.offset as u64 } fn from_bits(n: u64) -> Self { Self { offset: n as u32, _phantom: PhantomData, } } } unsafe impl ValueType for WasmPtr {} impl Clone for WasmPtr { fn clone(&self) -> Self { Self { offset: self.offset, _phantom: PhantomData, } } } impl Copy for WasmPtr {} impl PartialEq for WasmPtr { fn eq(&self, other: &Self) -> bool { self.offset == other.offset } } impl Eq for WasmPtr {} impl fmt::Debug for WasmPtr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "WasmPtr({:#x})", self.offset) } }