#![allow(improper_ctypes_definitions)] pub mod callback; pub mod future; pub mod handle; pub mod new_stack; pub mod vtable; #[macro_use] extern crate tracing; use std::{marker::PhantomData, mem::forget}; use callback::RuntimeState; use dlopen2::wrapper::WrapperApi; use handle::PluginInitializationState; use new_stack::{FFIPluginMeta, PluginState}; pub use vtable::{AnyFailure, AnyObject, AnyOperation, AnySuccess, NewAnySetting, NewAnyValue}; use vtable::{HostVTable, InitializationVTable}; #[derive(WrapperApi)] pub struct GiteratedPluginApi { plugin_meta: unsafe extern "C" fn() -> FFIPluginMeta, load_host_vtable: unsafe extern "C" fn(vtable: &HostVTable), load_initialization_vtable: unsafe extern "C" fn(vtable: &InitializationVTable), initialize: unsafe extern "C" fn(runtime_state: *const RuntimeState) -> PluginState, initialize_registration: unsafe extern "C" fn( init_state: *mut PluginInitializationState, ) -> *mut PluginInitializationState, load_type_metadata: unsafe extern "C" fn(metadata: *mut ()), } #[repr(C)] pub struct FFIBox(*mut T); impl FFIBox { pub fn from_box(src: Box) -> Self { Self(Box::into_raw(src)) } pub fn untyped(self) -> FFIBox<()> { FFIBox(self.0 as *mut ()) } pub unsafe fn retype(self) -> FFIBox { FFIBox(self.0 as *mut N) } pub unsafe fn into_box(self) -> Box { Box::from_raw(self.0) } pub unsafe fn transmute_ref(&self) -> &N { unsafe { (self.0 as *const N).as_ref() }.unwrap() } } impl ToString for FFIBox { fn to_string(&self) -> String { let slice: Box<[u8]> = unsafe { Box::from_raw(self.0.clone() as *mut _) }; let string = unsafe { std::str::from_boxed_utf8_unchecked(slice) }; String::from(string) } } impl AsRef for FFIBox { fn as_ref(&self) -> &T { unsafe { self.0.as_ref() }.unwrap() } } impl std::ops::Deref for FFIBox { type Target = T; fn deref(&self) -> &Self::Target { unsafe { self.0.as_ref() }.unwrap() } } #[repr(transparent)] pub struct FFI { /// Can either be a pointer to `FFIData` or to `T` /// depending on the ownership of the FFI reference. inner: *const (), _marker: PhantomData<(T, Ownership)>, } #[repr(C)] pub struct FFIData { /// SAFETY: THIS VALUE COULD BE NULL. drop_fn: *const extern "C" fn(*const FFIData), drop_state: *const (), allocation: T, } pub struct Owned; impl FfiOwnershipDrop for Owned {} pub struct StackOwned; impl FfiOwnershipDrop for StackOwned {} trait FfiOwnershipDrop {} pub struct PinnedRef; impl FfiOwnershipDrop for PinnedRef {} pub struct PinnedMut; impl FfiOwnershipDrop for PinnedMut {} impl FFI { pub fn place_heap(value: T) -> FFI { todo!() } pub fn ref_guard<'a>(&'a self) -> StackPinnedGuard<'a, T> { todo!() } } impl FFI { pub fn place_stack<'a>(value: T) -> StackPinned<'a, T> { todo!() } } pub struct StackPinned<'a, T> { descriptor: FFIData, _lifetime: PhantomData<&'a ()>, } impl<'a, T> StackPinned<'a, T> { pub unsafe fn grant_ref(&self) -> FFI { todo!() } } pub struct StackPinnedGuard<'a, T> { pinned_owned: &'a FFI, } impl<'a, T> StackPinnedGuard<'a, T> { pub unsafe fn grant_ref(&self) -> FFI { todo!() } } impl Drop for FFI { fn drop(&mut self) { todo!() } } pub struct FFISlice { len: usize, slice: T, } fn example() { let stack_ffi_value = FFI::place_stack(()); let stack_ffi_ref = unsafe { stack_ffi_value.grant_ref() }; let foo = stack_ffi_ref; let heap_ffi_value = FFI::place_heap(()); let heap_ffi_ref_guard = heap_ffi_value.ref_guard(); let heap_ffi_ref = unsafe { heap_ffi_ref_guard.grant_ref() }; }