use core::marker::PhantomData;
use wasm3x_sys as ffi;
use crate::memory::Memory;
use crate::store::{AsContext, AsContextMut, StoreContext, StoreContextMut, StoreId};
use crate::trampoline::RawCaller;
pub struct Caller<'a, T> {
runtime: ffi::IM3Runtime,
store_id: StoreId,
data: *mut T,
_marker: PhantomData<&'a mut T>,
}
impl<'a, T> Caller<'a, T> {
pub(crate) fn from_raw(raw: RawCaller) -> Self {
Self {
runtime: raw.runtime,
store_id: raw.store_id,
data: raw.data as *mut T,
_marker: PhantomData,
}
}
pub fn data(&self) -> &T {
unsafe { &*self.data }
}
pub fn data_mut(&mut self) -> &mut T {
unsafe { &mut *self.data }
}
pub fn get_memory(&self) -> Option<Memory> {
let mut size = 0u32;
let ptr = unsafe { ffi::m3_GetMemory(self.runtime, &mut size, 0) };
if ptr.is_null() {
return None;
}
Some(Memory::new(self.store_id, 0))
}
}
impl<'a, T> AsContext for Caller<'a, T> {
type Data = T;
fn as_context(&self) -> StoreContext<'_, T> {
StoreContext::new(self.runtime, self.store_id, unsafe { &*self.data })
}
}
impl<'a, T> AsContextMut for Caller<'a, T> {
fn as_context_mut(&mut self) -> StoreContextMut<'_, T> {
StoreContextMut::new(self.runtime, self.store_id, unsafe { &mut *self.data })
}
}