JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

MOre pre vtable changes

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨9cfa135

⁨giterated-plugin/src/lib.rs⁩ - ⁨4065⁩ bytes
Raw
1 #![allow(improper_ctypes_definitions)]
2
3 pub mod callback;
4 pub mod future;
5 pub mod handle;
6 pub mod new_stack;
7 pub mod vtable;
8
9 #[macro_use]
10 extern crate tracing;
11
12 use std::{marker::PhantomData, mem::forget};
13
14 use callback::RuntimeState;
15 use dlopen2::wrapper::WrapperApi;
16
17 use handle::PluginInitializationState;
18 use new_stack::{FFIPluginMeta, PluginState};
19
20 pub use vtable::{AnyFailure, AnyObject, AnyOperation, AnySuccess, NewAnySetting, NewAnyValue};
21 use vtable::{HostVTable, InitializationVTable};
22
23 #[derive(WrapperApi)]
24 pub struct GiteratedPluginApi {
25 plugin_meta: unsafe extern "C" fn() -> FFIPluginMeta,
26 load_host_vtable: unsafe extern "C" fn(vtable: &HostVTable),
27 load_initialization_vtable: unsafe extern "C" fn(vtable: &InitializationVTable),
28 initialize: unsafe extern "C" fn(runtime_state: *const RuntimeState) -> PluginState,
29 initialize_registration: unsafe extern "C" fn(
30 init_state: *mut PluginInitializationState,
31 ) -> *mut PluginInitializationState,
32 load_type_metadata: unsafe extern "C" fn(metadata: *mut ()),
33 }
34
35 #[repr(C)]
36 pub struct FFIBox<T: ?Sized>(*mut T);
37
38 impl<T: ?Sized> FFIBox<T> {
39 pub fn from_box(src: Box<T>) -> Self {
40 Self(Box::into_raw(src))
41 }
42
43 pub fn untyped(self) -> FFIBox<()> {
44 FFIBox(self.0 as *mut ())
45 }
46
47 pub unsafe fn retype<N>(self) -> FFIBox<N> {
48 FFIBox(self.0 as *mut N)
49 }
50
51 pub unsafe fn into_box(self) -> Box<T> {
52 Box::from_raw(self.0)
53 }
54
55 pub unsafe fn transmute_ref<N>(&self) -> &N {
56 unsafe { (self.0 as *const N).as_ref() }.unwrap()
57 }
58 }
59
60 impl ToString for FFIBox<str> {
61 fn to_string(&self) -> String {
62 let slice: Box<[u8]> = unsafe { Box::from_raw(self.0.clone() as *mut _) };
63
64 let string = unsafe { std::str::from_boxed_utf8_unchecked(slice) };
65
66 String::from(string)
67 }
68 }
69
70 impl<T: ?Sized> AsRef<T> for FFIBox<T> {
71 fn as_ref(&self) -> &T {
72 unsafe { self.0.as_ref() }.unwrap()
73 }
74 }
75
76 impl<T: ?Sized> std::ops::Deref for FFIBox<T> {
77 type Target = T;
78
79 fn deref(&self) -> &Self::Target {
80 unsafe { self.0.as_ref() }.unwrap()
81 }
82 }
83
84 #[repr(transparent)]
85 pub struct FFI<T, Ownership: FfiOwnershipDrop> {
86 /// Can either be a pointer to `FFIData<T>` or to `T`
87 /// depending on the ownership of the FFI reference.
88 inner: *const (),
89 _marker: PhantomData<(T, Ownership)>,
90 }
91
92 #[repr(C)]
93 pub struct FFIData<T> {
94 /// SAFETY: THIS VALUE COULD BE NULL.
95 drop_fn: *const extern "C" fn(*const FFIData<T>),
96 drop_state: *const (),
97
98 allocation: T,
99 }
100
101 pub struct Owned;
102
103 impl FfiOwnershipDrop for Owned {}
104
105 pub struct StackOwned;
106
107 impl FfiOwnershipDrop for StackOwned {}
108
109 trait FfiOwnershipDrop {}
110
111 pub struct PinnedRef;
112
113 impl FfiOwnershipDrop for PinnedRef {}
114
115 pub struct PinnedMut;
116
117 impl FfiOwnershipDrop for PinnedMut {}
118
119 impl<T> FFI<T, Owned> {
120 pub fn place_heap(value: T) -> FFI<T, Owned> {
121 todo!()
122 }
123
124 pub fn ref_guard<'a>(&'a self) -> StackPinnedGuard<'a, T> {
125 todo!()
126 }
127 }
128
129 impl<T> FFI<T, StackOwned> {
130 pub fn place_stack<'a>(value: T) -> StackPinned<'a, T> {
131 todo!()
132 }
133 }
134
135 pub struct StackPinned<'a, T> {
136 descriptor: FFIData<T>,
137 _lifetime: PhantomData<&'a ()>,
138 }
139
140 impl<'a, T> StackPinned<'a, T> {
141 pub unsafe fn grant_ref(&self) -> FFI<T, PinnedRef> {
142 todo!()
143 }
144 }
145
146 pub struct StackPinnedGuard<'a, T> {
147 pinned_owned: &'a FFI<T, Owned>,
148 }
149
150 impl<'a, T> StackPinnedGuard<'a, T> {
151 pub unsafe fn grant_ref(&self) -> FFI<T, PinnedRef> {
152 todo!()
153 }
154 }
155
156 impl<T, O: FfiOwnershipDrop> Drop for FFI<T, O> {
157 fn drop(&mut self) {
158 todo!()
159 }
160 }
161
162 pub struct FFISlice<T: ?Sized> {
163 len: usize,
164 slice: T,
165 }
166
167 fn example() {
168 let stack_ffi_value = FFI::place_stack(());
169
170 let stack_ffi_ref = unsafe { stack_ffi_value.grant_ref() };
171
172 let foo = stack_ffi_ref;
173
174 let heap_ffi_value = FFI::place_heap(());
175
176 let heap_ffi_ref_guard = heap_ffi_value.ref_guard();
177
178 let heap_ffi_ref = unsafe { heap_ffi_ref_guard.grant_ref() };
179 }
180