use crate::{
CExternType,
wasm_byte_vec_t,
wasm_exporttype_t,
wasm_exporttype_vec_t,
wasm_importtype_t,
wasm_importtype_vec_t,
wasm_store_t,
};
use alloc::{boxed::Box, string::String};
use wasmi::{Engine, Module};
#[derive(Clone)]
pub struct wasm_module_t {
pub(crate) inner: Module,
}
wasmi_c_api_macros::declare_ref!(wasm_module_t);
impl wasm_module_t {
pub(crate) fn new(module: Module) -> wasm_module_t {
wasm_module_t { inner: module }
}
}
#[repr(C)]
#[derive(Clone)]
pub struct wasm_shared_module_t {
inner: Module,
}
wasmi_c_api_macros::declare_own!(wasm_shared_module_t);
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub unsafe extern "C" fn wasm_module_new(
store: &mut wasm_store_t,
binary: &wasm_byte_vec_t,
) -> Option<Box<wasm_module_t>> {
unsafe {
match Module::new(store.inner.context().engine(), binary.as_slice()) {
Ok(module) => Some(Box::new(wasm_module_t::new(module))),
Err(_) => None,
}
}
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub unsafe extern "C" fn wasm_module_validate(
store: &mut wasm_store_t,
binary: &wasm_byte_vec_t,
) -> bool {
unsafe { Module::validate(store.inner.context().engine(), binary.as_slice()).is_ok() }
}
fn fill_exports(module: &Module, out: &mut wasm_exporttype_vec_t) {
let exports = module
.exports()
.map(|e| {
Some(Box::new(wasm_exporttype_t::new(
String::from(e.name()),
CExternType::new(e.ty().clone()),
)))
})
.collect::<Box<[_]>>();
out.set_buffer(exports);
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
fill_exports(&module.inner, out);
}
fn fill_imports(module: &Module, out: &mut wasm_importtype_vec_t) {
let imports = module
.imports()
.map(|i| {
Some(Box::new(wasm_importtype_t::new(
String::from(i.module()),
String::from(i.name()),
CExternType::new(i.ty().clone()),
)))
})
.collect::<Box<[_]>>();
out.set_buffer(imports);
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
fill_imports(&module.inner, out);
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
Box::new(wasm_shared_module_t {
inner: module.inner.clone(),
})
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub unsafe extern "C" fn wasm_module_obtain(
store: &mut wasm_store_t,
shared_module: &wasm_shared_module_t,
) -> Option<Box<wasm_module_t>> {
unsafe {
let module = shared_module.inner.clone();
if Engine::same(store.inner.context().engine(), module.engine()) {
Some(Box::new(wasm_module_t::new(module)))
} else {
None
}
}
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub extern "C" fn wasm_module_serialize(_module: &wasm_module_t, _ret: &mut wasm_byte_vec_t) {
unimplemented!("wasm_module_serialize")
}
#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
pub unsafe extern "C" fn wasm_module_deserialize(
_store: &mut wasm_store_t,
_binary: &wasm_byte_vec_t,
) -> Option<Box<wasm_module_t>> {
unimplemented!("wasm_module_deserialize")
}