use crate::sys::store::AsStoreRef;
use crate::MemoryAccessError;
use std::convert::TryInto;
use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::slice;
use wasmer_types::Pages;
use wasmer_vm::LinearMemory;
use super::memory::MemoryBuffer;
use super::Memory;
#[derive(Debug)]
pub struct MemoryView<'a> {
pub(crate) buffer: MemoryBuffer<'a>,
pub(crate) size: Pages,
}
impl<'a> MemoryView<'a> {
pub(crate) fn new(memory: &'a Memory, store: &impl AsStoreRef) -> Self {
let size = memory.handle.get(store.as_store_ref().objects()).size();
let definition = memory.handle.get(store.as_store_ref().objects()).vmmemory();
let def = unsafe { definition.as_ref() };
Self {
buffer: MemoryBuffer {
base: def.base,
len: def.current_length,
marker: PhantomData,
},
size,
}
}
#[doc(hidden)]
pub fn data_ptr(&self) -> *mut u8 {
self.buffer.base
}
pub fn data_size(&self) -> u64 {
self.buffer.len.try_into().unwrap()
}
#[doc(hidden)]
pub unsafe fn data_unchecked(&self) -> &[u8] {
self.data_unchecked_mut()
}
#[allow(clippy::mut_from_ref)]
#[doc(hidden)]
pub unsafe fn data_unchecked_mut(&self) -> &mut [u8] {
slice::from_raw_parts_mut(self.buffer.base, self.buffer.len)
}
pub fn size(&self) -> Pages {
self.size
}
pub(crate) fn buffer(&'a self) -> MemoryBuffer<'a> {
self.buffer
}
pub fn read(&self, offset: u64, buf: &mut [u8]) -> Result<(), MemoryAccessError> {
self.buffer.read(offset, buf)
}
pub fn read_u8(&self, offset: u64) -> Result<u8, MemoryAccessError> {
let mut buf = [0u8; 1];
self.read(offset, &mut buf)?;
Ok(buf[0])
}
pub fn read_uninit<'b>(
&self,
offset: u64,
buf: &'b mut [MaybeUninit<u8>],
) -> Result<&'b mut [u8], MemoryAccessError> {
self.buffer.read_uninit(offset, buf)
}
pub fn write(&self, offset: u64, data: &[u8]) -> Result<(), MemoryAccessError> {
self.buffer.write(offset, data)
}
pub fn write_u8(&self, offset: u64, val: u8) -> Result<(), MemoryAccessError> {
let buf = [val];
self.write(offset, &buf)?;
Ok(())
}
}