1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use super::{
    error::Errno,
    types::{__wasi_ciovec_t, __wasi_iovec_t, __wasi_size_t},
};
use std::{
    io::{IoSlice, IoSliceMut},
    ops::{Add, Deref, DerefMut, Sub},
};

pub trait Memory {
    fn get_data<T: Sized>(&self, offset: WasmPtr<T>) -> Result<&T, Errno>;

    fn get_slice<T: Sized>(&self, offset: WasmPtr<T>, len: usize) -> Result<&[T], Errno>;

    fn get_iovec<'a>(
        &self,
        iovec_ptr: WasmPtr<__wasi_ciovec_t>,
        iovec_len: __wasi_size_t,
    ) -> Result<Vec<IoSlice<'a>>, Errno>;

    fn mut_data<T: Sized>(&mut self, offset: WasmPtr<T>) -> Result<&mut T, Errno>;

    fn mut_slice<T: Sized>(&mut self, offset: WasmPtr<T>, len: usize) -> Result<&mut [T], Errno>;

    fn mut_iovec(
        &mut self,
        iovec_ptr: WasmPtr<__wasi_iovec_t>,
        iovec_len: __wasi_size_t,
    ) -> Result<Vec<IoSliceMut<'_>>, Errno>;

    fn write_data<T: Sized>(&mut self, offset: WasmPtr<T>, data: T) -> Result<(), Errno>;
}

#[derive(Debug, Clone, Copy)]
pub struct WasmPtr<T: Sized>(pub usize, std::marker::PhantomData<T>);
impl<T: Sized> WasmPtr<T> {
    pub fn is_null(&self) -> bool {
        self.0 == 0
    }
}
impl<T: Sized> From<usize> for WasmPtr<T> {
    fn from(i: usize) -> Self {
        WasmPtr(i, Default::default())
    }
}
impl<T: Sized> From<WasmPtr<T>> for usize {
    fn from(val: WasmPtr<T>) -> Self {
        val.0
    }
}
impl<T: Sized> Add<usize> for WasmPtr<T> {
    type Output = Self;
    fn add(mut self, rhs: usize) -> Self::Output {
        self.0 += rhs * std::mem::size_of::<T>();
        self
    }
}
impl<T: Sized> Sub<usize> for WasmPtr<T> {
    type Output = Self;
    fn sub(mut self, rhs: usize) -> Self::Output {
        self.0 -= rhs * std::mem::size_of::<T>();
        self
    }
}