use std::ffi::CString;
use wasm3x_sys as ffi;
use crate::error::{Error, Result};
use crate::func::{Func, TypedFunc, WasmParams, WasmResults};
use crate::global::Global;
use crate::memory::Memory;
use crate::store::{AsContext, StoreId, assert_same_store};
#[derive(Debug, Clone, Copy)]
pub struct Instance {
module: ffi::IM3Module,
store_id: StoreId,
}
impl Instance {
pub(crate) fn new(module: ffi::IM3Module, store_id: StoreId) -> Self {
Self { module, store_id }
}
pub(crate) fn raw(&self) -> ffi::IM3Module {
self.module
}
pub fn get_func(&self, store: impl AsContext, name: &str) -> Option<Func> {
let ctx = store.as_context();
assert_same_store(ctx.store_id(), self.store_id);
Func::find_raw(ctx.runtime(), self.store_id, name)
}
pub fn get_typed_func<Params, Results>(
&self,
store: impl AsContext,
name: &str,
) -> Result<TypedFunc<Params, Results>>
where
Params: WasmParams,
Results: WasmResults,
{
let ctx = store.as_context();
assert_same_store(ctx.store_id(), self.store_id);
let func = Func::find_raw(ctx.runtime(), self.store_id, name)
.ok_or_else(|| Error::new(format!("exported function `{name}` not found")))?;
func.typed_checked(self.store_id)
}
pub fn get_global(&self, store: impl AsContext, name: &str) -> Option<Global> {
assert_same_store(store.as_context().store_id(), self.store_id);
let cname = CString::new(name).ok()?;
let raw = unsafe { ffi::m3_FindGlobal(self.module, cname.as_ptr()) };
if raw.is_null() {
return None;
}
Some(Global::from_raw(raw, self.store_id))
}
pub fn get_memory(&self, store: impl AsContext) -> Option<Memory> {
let ctx = store.as_context();
assert_same_store(ctx.store_id(), self.store_id);
let mut size = 0u32;
let ptr = unsafe { ffi::m3_GetMemory(ctx.runtime(), &mut size, 0) };
if ptr.is_null() {
return None;
}
Some(Memory::new(self.store_id, 0))
}
}