use loupe::MemoryUsage;
use std::sync::Arc;
use wasmer_vm::{ImportInitializerFuncPtr, VMExtern, VMFunction, VMGlobal, VMMemory, VMTable};
#[derive(Debug, Clone)]
pub enum Export {
Function(ExportFunction),
Table(VMTable),
Memory(VMMemory),
Global(VMGlobal),
}
impl From<Export> for VMExtern {
fn from(other: Export) -> Self {
match other {
Export::Function(ExportFunction { vm_function, .. }) => Self::Function(vm_function),
Export::Memory(vm_memory) => Self::Memory(vm_memory),
Export::Table(vm_table) => Self::Table(vm_table),
Export::Global(vm_global) => Self::Global(vm_global),
}
}
}
impl From<VMExtern> for Export {
fn from(other: VMExtern) -> Self {
match other {
VMExtern::Function(vm_function) => Self::Function(ExportFunction {
vm_function,
metadata: None,
}),
VMExtern::Memory(vm_memory) => Self::Memory(vm_memory),
VMExtern::Table(vm_table) => Self::Table(vm_table),
VMExtern::Global(vm_global) => Self::Global(vm_global),
}
}
}
#[derive(Debug, PartialEq, MemoryUsage)]
pub struct ExportFunctionMetadata {
pub(crate) host_env: *mut std::ffi::c_void,
#[loupe(skip)]
pub(crate) import_init_function_ptr: Option<ImportInitializerFuncPtr>,
#[loupe(skip)]
pub(crate) host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void,
#[loupe(skip)]
pub(crate) host_env_drop_fn: unsafe fn(*mut std::ffi::c_void),
}
unsafe impl Send for ExportFunctionMetadata {}
unsafe impl Sync for ExportFunctionMetadata {}
impl ExportFunctionMetadata {
pub unsafe fn new(
host_env: *mut std::ffi::c_void,
import_init_function_ptr: Option<ImportInitializerFuncPtr>,
host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void,
host_env_drop_fn: fn(*mut std::ffi::c_void),
) -> Self {
Self {
host_env,
import_init_function_ptr,
host_env_clone_fn,
host_env_drop_fn,
}
}
}
impl Drop for ExportFunctionMetadata {
fn drop(&mut self) {
if !self.host_env.is_null() {
unsafe {
(self.host_env_drop_fn)(self.host_env);
}
}
}
}
#[derive(Debug, Clone, PartialEq, MemoryUsage)]
pub struct ExportFunction {
pub vm_function: VMFunction,
pub metadata: Option<Arc<ExportFunctionMetadata>>,
}
impl From<ExportFunction> for Export {
fn from(func: ExportFunction) -> Self {
Self::Function(func)
}
}
impl From<VMTable> for Export {
fn from(table: VMTable) -> Self {
Self::Table(table)
}
}
impl From<VMMemory> for Export {
fn from(memory: VMMemory) -> Self {
Self::Memory(memory)
}
}
impl From<VMGlobal> for Export {
fn from(global: VMGlobal) -> Self {
Self::Global(global)
}
}