use crate::{ForeignData, wasm_engine_t, wasmi_error_t};
use alloc::{boxed::Box, sync::Arc};
use core::{cell::UnsafeCell, ffi};
use wasmi::{AsContext, AsContextMut, Store, StoreContext, StoreContextMut};
#[derive(Clone)]
pub struct WasmStoreRef {
inner: Arc<UnsafeCell<Store<()>>>,
}
impl WasmStoreRef {
pub unsafe fn context(&self) -> StoreContext<'_, ()> {
unsafe { (*self.inner.get()).as_context() }
}
pub unsafe fn context_mut(&mut self) -> StoreContextMut<'_, ()> {
unsafe { (*self.inner.get()).as_context_mut() }
}
}
#[repr(C)]
#[derive(Clone)]
pub struct wasm_store_t {
pub(crate) inner: WasmStoreRef,
}
wasmi_c_api_macros::declare_own!(wasm_store_t);
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[allow(clippy::arc_with_non_send_sync)]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub extern "C" fn wasm_store_new(engine: &wasm_engine_t) -> Box<wasm_store_t> {
let engine = &engine.inner;
let store = Store::new(engine, ());
Box::new(wasm_store_t {
inner: WasmStoreRef {
inner: Arc::new(UnsafeCell::new(store)),
},
})
}
#[repr(C)]
pub struct wasmi_store_t {
pub(crate) store: Store<WasmiStoreData>,
}
wasmi_c_api_macros::declare_own!(wasmi_store_t);
pub struct WasmiStoreData {
foreign: ForeignData,
}
#[unsafe(no_mangle)]
pub extern "C" fn wasmi_store_new(
engine: &wasm_engine_t,
data: *mut ffi::c_void,
finalizer: Option<extern "C" fn(*mut ffi::c_void)>,
) -> Box<wasmi_store_t> {
Box::new(wasmi_store_t {
store: Store::new(
&engine.inner,
WasmiStoreData {
foreign: ForeignData { data, finalizer },
},
),
})
}
#[unsafe(no_mangle)]
pub extern "C" fn wasmi_store_context(
store: &mut wasmi_store_t,
) -> StoreContextMut<'_, WasmiStoreData> {
store.store.as_context_mut()
}
#[unsafe(no_mangle)]
pub extern "C" fn wasmi_context_get_data(
store: StoreContext<'_, WasmiStoreData>,
) -> *mut ffi::c_void {
store.data().foreign.data
}
#[unsafe(no_mangle)]
pub extern "C" fn wasmi_context_set_data(
mut store: StoreContextMut<'_, WasmiStoreData>,
data: *mut ffi::c_void,
) {
store.data_mut().foreign.data = data;
}
#[unsafe(no_mangle)]
pub extern "C" fn wasmi_context_get_fuel(
store: StoreContext<'_, WasmiStoreData>,
fuel: &mut u64,
) -> Option<Box<wasmi_error_t>> {
crate::handle_result(store.get_fuel(), |amt| {
*fuel = amt;
})
}
#[unsafe(no_mangle)]
pub extern "C" fn wasmi_context_set_fuel(
mut store: StoreContextMut<'_, WasmiStoreData>,
fuel: u64,
) -> Option<Box<wasmi_error_t>> {
crate::handle_result(store.set_fuel(fuel), |()| {})
}