use crate::collections::{ConstSpan, NonNullConst, Result};
use crate::module::{Error, Interface, InterfaceDescriptor, ModuleHandle, ModuleInfo};
use crate::sys::api::{GetFunctionFn, HasFunctionFn};
use crate::{CBase, TypeWrapper};
use std::ptr::NonNull;
#[repr(C)]
pub struct NativeModule {
_dummy: [u8; 0],
}
pub type LoadFn = TypeWrapper<
unsafe extern "C-unwind" fn(
handle: ModuleHandle,
base_module: Option<NonNull<CBase>>,
has_function_fn: HasFunctionFn,
get_function_fn: GetFunctionFn,
) -> Result<Option<NonNull<NativeModule>>, Error>,
>;
pub type UnloadFn = TypeWrapper<
unsafe extern "C-unwind" fn(module: Option<NonNull<NativeModule>>) -> Result<i8, Error>,
>;
pub type InitializeFn = TypeWrapper<
unsafe extern "C-unwind" fn(module: Option<NonNull<NativeModule>>) -> Result<i8, Error>,
>;
pub type TerminateFn = TypeWrapper<
unsafe extern "C-unwind" fn(module: Option<NonNull<NativeModule>>) -> Result<i8, Error>,
>;
pub type GetInterfaceFn = TypeWrapper<
unsafe extern "C-unwind" fn(
module: Option<NonNull<NativeModule>>,
interface: NonNullConst<InterfaceDescriptor>,
) -> Result<Interface, Error>,
>;
pub type GetModuleInfoFn = TypeWrapper<
unsafe extern "C-unwind" fn(
module: Option<NonNull<NativeModule>>,
) -> Result<NonNullConst<ModuleInfo>, Error>,
>;
pub type GetLoadDependenciesFn =
TypeWrapper<unsafe extern "C-unwind" fn() -> ConstSpan<InterfaceDescriptor>>;
pub type GetRuntimeDependenciesFn = TypeWrapper<
unsafe extern "C-unwind" fn(
module: Option<NonNull<NativeModule>>,
) -> Result<ConstSpan<InterfaceDescriptor>, Error>,
>;
pub type GetExportableInterfacesFn = TypeWrapper<
unsafe extern "C-unwind" fn(
module: Option<NonNull<NativeModule>>,
) -> Result<ConstSpan<InterfaceDescriptor>, Error>,
>;
#[repr(C)]
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct NativeModuleInterface {
pub load_fn: LoadFn,
pub unload_fn: UnloadFn,
pub initialize_fn: InitializeFn,
pub terminate_fn: TerminateFn,
pub get_interface_fn: GetInterfaceFn,
pub get_module_info_fn: GetModuleInfoFn,
pub get_load_dependencies_fn: GetLoadDependenciesFn,
pub get_runtime_dependencies_fn: GetRuntimeDependenciesFn,
pub get_exportable_interfaces_fn: GetExportableInterfacesFn,
}
unsafe impl Send for NativeModuleInterface {}
unsafe impl Sync for NativeModuleInterface {}
pub trait NativeModuleBinding {
unsafe fn load(
&mut self,
handle: ModuleHandle,
base_module: Option<NonNull<CBase>>,
has_function_fn: HasFunctionFn,
get_function_fn: GetFunctionFn,
) -> Result<Option<NonNull<NativeModule>>, Error>;
unsafe fn unload(&mut self, module: Option<NonNull<NativeModule>>) -> Result<i8, Error>;
unsafe fn initialize(&mut self, module: Option<NonNull<NativeModule>>) -> Result<i8, Error>;
unsafe fn terminate(&mut self, module: Option<NonNull<NativeModule>>) -> Result<i8, Error>;
unsafe fn get_interface(
&self,
module: Option<NonNull<NativeModule>>,
interface: NonNullConst<InterfaceDescriptor>,
) -> Result<Interface, Error>;
unsafe fn get_module_info(
&self,
module: Option<NonNull<NativeModule>>,
) -> Result<NonNullConst<ModuleInfo>, Error>;
unsafe fn get_load_dependencies(&self) -> ConstSpan<InterfaceDescriptor>;
unsafe fn get_runtime_dependencies(
&self,
module: Option<NonNull<NativeModule>>,
) -> Result<ConstSpan<InterfaceDescriptor>, Error>;
unsafe fn get_exportable_interfaces(
&self,
module: Option<NonNull<NativeModule>>,
) -> Result<ConstSpan<InterfaceDescriptor>, Error>;
}
impl NativeModuleBinding for NativeModuleInterface {
#[inline]
unsafe fn load(
&mut self,
handle: ModuleHandle,
base_module: Option<NonNull<CBase>>,
has_function_fn: HasFunctionFn,
get_function_fn: GetFunctionFn,
) -> Result<Option<NonNull<NativeModule>>, Error> {
(self.load_fn)(handle, base_module, has_function_fn, get_function_fn)
}
#[inline]
unsafe fn unload(&mut self, module: Option<NonNull<NativeModule>>) -> Result<i8, Error> {
(self.unload_fn)(module)
}
#[inline]
unsafe fn initialize(&mut self, module: Option<NonNull<NativeModule>>) -> Result<i8, Error> {
(self.initialize_fn)(module)
}
#[inline]
unsafe fn terminate(&mut self, module: Option<NonNull<NativeModule>>) -> Result<i8, Error> {
(self.terminate_fn)(module)
}
#[inline]
unsafe fn get_interface(
&self,
module: Option<NonNull<NativeModule>>,
interface: NonNullConst<InterfaceDescriptor>,
) -> Result<Interface, Error> {
(self.get_interface_fn)(module, interface)
}
#[inline]
unsafe fn get_module_info(
&self,
module: Option<NonNull<NativeModule>>,
) -> Result<NonNullConst<ModuleInfo>, Error> {
(self.get_module_info_fn)(module)
}
#[inline]
unsafe fn get_load_dependencies(&self) -> ConstSpan<InterfaceDescriptor> {
(self.get_load_dependencies_fn)()
}
#[inline]
unsafe fn get_runtime_dependencies(
&self,
module: Option<NonNull<NativeModule>>,
) -> Result<ConstSpan<InterfaceDescriptor>, Error> {
(self.get_runtime_dependencies_fn)(module)
}
#[inline]
unsafe fn get_exportable_interfaces(
&self,
module: Option<NonNull<NativeModule>>,
) -> Result<ConstSpan<InterfaceDescriptor>, Error> {
(self.get_exportable_interfaces_fn)(module)
}
}