use std::error::Error;
use wasi_common::WasiCtx;
use wasmtime::{AsContext, AsContextMut, Caller, Extern};
pub fn read_mem(
caller: &mut Caller<'_, WasiCtx>,
ptr: i32,
buf: &mut [u8],
) -> Result<(), Box<dyn Error>> {
let Some(Extern::Memory(mem)) = caller.get_export("memory") else {
return Err("no mem".into());
};
mem.read(caller.as_context_mut(), ptr as usize, buf)?;
Ok(())
}
pub fn write_mem(caller: &mut Caller<'_, WasiCtx>, bytes: &[u8]) -> Option<i64> {
let alloc = match caller.get_export("alloc") {
Some(Extern::Func(malloc)) => match malloc.typed::<i32, i32>(caller.as_context()) {
Ok(malloc) => malloc,
Err(_) => return None,
},
_ => return None,
};
let len = bytes.len();
let Ok(params) = i32::try_from(len) else {
return None;
};
let Ok(ptr) = alloc.call(caller.as_context_mut(), params) else {
return None;
};
let Some(Extern::Memory(mem)) = caller.get_export("memory") else {
return None;
};
match mem.write(caller.as_context_mut(), ptr as usize, bytes) {
Ok(()) => {}
Err(_) => return None,
}
let ptr64 = i64::from(ptr) << 32;
let Ok(len64) = i64::try_from(len) else {
return None;
};
Some(ptr64 | len64)
}