1#![allow(non_upper_case_globals)]
2
3pub mod extension_data;
4pub mod virtual_thread;
5pub mod shared_memory;
6pub mod shutdown_type;
7pub mod block_info;
8pub mod extensions;
9pub mod vm_config;
10pub mod executor;
11pub mod register;
12pub mod vm_value;
13pub mod archive;
14pub mod runtime;
15pub mod string;
16pub mod stack;
17pub mod event;
18pub mod ffi;
19
20mod thread_counter;
21
22pub mod ffi_primitive;
23
24mod macros;
25
26use std::{sync::{Arc, atomic::{AtomicU32, Ordering}}, collections::{hash_map::{Values, Iter}, HashSet, HashMap}};
27use extension_data::ExtensionData;
28use fast_async_mutex::mutex::Mutex as SpinMutex;
29use async_ffi::{BorrowingFfiFuture, FfiFuture};
30use tokio::sync::{Mutex, MutexGuard, OwnedMutexGuard};
31
32use executor::{ExecutorLock, Lock, ExecutorBehaviour};
33use virtual_thread::{VThread, VirtualThread};
34use block_info::{UnlockInfo, BlockInfo};
35use extensions::{Extension, Extensions};
36use shutdown_type::ShutdownType;
37use shared_memory::Memory;
38use vm_value::VMValue;
39use event::EventType;
40use runtime::Runtime;
41use string::VMStr;
42use stack::Stack;
43
44use macros::{gen_bindings, load_bindings, async_binding};
45
46gen_bindings![
47 fn_bind![fn(&Arc<Runtime>, EventType), Runtime::dispatch_extension_event];
48 fn_bind![fn(&Arc<Runtime>, u32, EventType), Runtime::send_extension_event];
49 fn_bind![fn(&Runtime, VThread), Runtime::dispose_thread];
50 fn_bind![fn(&Runtime, ShutdownType), Runtime::shutdown];
51
52 fn_bind![fn(&Memory) -> *const u8, Memory::ptr];
53
54 fn_bind![fn(&Extensions) -> Values<'_, u32, Arc<Extension>>, Extensions::iter];
55 fn_bind![fn(&Extensions) -> Iter<'_, u32, Arc<Extension>>, Extensions::all];
56 fn_bind![fn(&Extensions, u32) -> Arc<Extension>, Extensions::get];
57
58 fn_bind![fn(&Extension, VThread, Lock, u32, bool) -> (Lock, ExecutorBehaviour), Extension::function_call];
59 fn_bind![fn(&Extension, VThread, Lock, u32, bool) -> (Lock, ExecutorBehaviour), Extension::interrupt_call];
60 fn_bind![fn(&Extension, Arc<Runtime>, EventType), Extension::dispatch_event];
61 fn_bind![fn(&Extension, Arc<Runtime>, u32), Extension::init];
62
63 fn_bind![fn(&BlockInfo, u64) -> Option<&UnlockInfo>, BlockInfo::get];
64 fn_bind![fn(&Stack, usize), Stack::dispose];
65 fn_bind![fn(&Stack) -> u64, Stack::ptr];
66
67 fn_bind![fn(&ExecutorLock) -> &Arc<Mutex<()>>, ExecutorLock::sys];
68 fn_bind![fn(&ExecutorLock) -> &Arc<SpinMutex<()>>, ExecutorLock::spin];
69
70 fn_bind![fn(&VirtualThread, u32) -> Arc<Extension>, VirtualThread::get_extension];
71 fn_bind![fn(&VirtualThread) -> Arc<BlockInfo>, VirtualThread::get_block_info];
72 fn_bind![fn(&VirtualThread) -> bool, VirtualThread::should_stop];
73 fn_bind![fn(&VirtualThread, u64, bool), VirtualThread::set_flag];
74 fn_bind![fn(&VirtualThread, u64) -> bool, VirtualThread::get_flag];
75 fn_bind![fn(&VirtualThread, u8, u32), VirtualThread::sub32];
76 fn_bind![fn(&VirtualThread, u8, u32), VirtualThread::add32];
77 fn_bind![fn(&VirtualThread, u64), VirtualThread::inc_inst];
78 fn_bind![fn(&VirtualThread, u64), VirtualThread::push];
79 fn_bind![fn(&VirtualThread) -> u64, VirtualThread::pop];
80 fn_bind![fn(VThread, ShutdownType), VirtualThread::shutdown];
81 fn_bind![fn(VThread), VirtualThread::dispose];
82 fn_bind![fn(&VirtualThread, usize) -> u64, VirtualThread::get_mem_u64];
83 fn_bind![fn(&VirtualThread, usize) -> u32, VirtualThread::get_mem_u32];
84 fn_bind![fn(&VirtualThread, usize) -> u16, VirtualThread::get_mem_u16];
85 fn_bind![fn(&VirtualThread, usize) -> u8, VirtualThread::get_mem_u8];
86 fn_bind![fn(&VirtualThread, usize) -> u64, VirtualThread::get_mem_absolute_u64];
87 fn_bind![fn(&VirtualThread, usize) -> u32, VirtualThread::get_mem_absolute_u32];
88 fn_bind![fn(&VirtualThread, usize) -> u16, VirtualThread::get_mem_absolute_u16];
89 fn_bind![fn(&VirtualThread, usize) -> u8, VirtualThread::get_mem_absolute_u8];
90 fn_bind![fn(&VirtualThread, usize, u64), VirtualThread::set_mem_absolute_u64];
91 fn_bind![fn(&VirtualThread, usize, u32), VirtualThread::set_mem_absolute_u32];
92 fn_bind![fn(&VirtualThread, usize, u16), VirtualThread::set_mem_absolute_u16];
93 fn_bind![fn(&VirtualThread, usize, u8), VirtualThread::set_mem_absolute_u8];
94 fn_bind![fn(&VirtualThread, u8, u64), VirtualThread::set_reg_u64];
95 fn_bind![fn(&VirtualThread, u8, u32), VirtualThread::set_reg_u32];
96 fn_bind![fn(&VirtualThread, u8, u16), VirtualThread::set_reg_u16];
97 fn_bind![fn(&VirtualThread, u8, u8), VirtualThread::set_reg_u8];
98 fn_bind![fn(&VirtualThread, u8) -> u64, VirtualThread::get_reg_u64];
99 fn_bind![fn(&VirtualThread, u8) -> u32, VirtualThread::get_reg_u32];
100 fn_bind![fn(&VirtualThread, u8) -> u16, VirtualThread::get_reg_u16];
101 fn_bind![fn(&VirtualThread, u8) -> u8, VirtualThread::get_reg_u8];
102
103 fn_bind![fn(u64, VThread) -> VMValue, VMValue::from];
104 fn_bind![fn(&mut VMValue) -> Option<(&mut VMStr, bool)>, VMValue::as_str];
105 fn_bind![fn(&VMValue) -> Option<f64>, VMValue::as_f64];
106
107 fn_bind![fn(&VMStr, &VMStr) -> bool, VMStr::str_eq];
108 fn_bind![fn(&VMStr) -> Option<f64>, VMStr::parse];
109 fn_bind![fn(u64, VThread) -> VMStr, VMStr::from];
110 fn_bind![fn(&VMStr) -> u64, VMStr::as_vm_value];
111 fn_bind![fn(&VMStr) -> *const u8, VMStr::ptr];
112 fn_bind![fn(&VMStr) -> &str, VMStr::as_str];
113 fn_bind![fn(&VMStr) -> u64, VMStr::len];
114];
115
116pub(crate) static mut Runtime__set_error_data: Option<fn(&Runtime, String) -> BorrowingFfiFuture<'static, ()>> = None;
117pub(crate) static mut Runtime__spawn: Option<fn(&Arc<Runtime>, u64) -> BorrowingFfiFuture<'static, ()>> = None;
118
119pub(crate) static mut VirtualThread__get_temp_vmstrs: Option<fn(&VirtualThread) -> BorrowingFfiFuture<'static, MutexGuard<'_, HashSet<(u64, usize)>>>> = None;
120pub(crate) static mut VirtualThread__set_error_data: Option<fn(&VirtualThread, String) -> BorrowingFfiFuture<'static, ()>> = None;
121pub(crate) static mut VirtualThread__spawn: Option<fn(&VirtualThread, u64) -> BorrowingFfiFuture<'static, ()>> = None;
122
123pub(crate) static mut VMStr__cloned_push: Option<fn(&VMStr, VMStr) -> BorrowingFfiFuture<'static, VMStr>> = None;
124pub(crate) static mut VMStr__push: Option<fn(&mut VMStr, VMStr) -> BorrowingFfiFuture<'static, ()>> = None;
125pub(crate) static mut VMStr__from_str: Option<fn(String, VThread) -> FfiFuture<VMStr>> = None;
126pub(crate) static mut VMStr__drop: Option<fn(&VMStr) -> BorrowingFfiFuture<'static, ()>> = None;
127
128pub(crate) static mut ExtensionData__lock: Option<fn(&ExtensionData) -> FfiFuture<OwnedMutexGuard<HashMap<u32, usize>>>> = None;
129
130#[cfg(target_pointer_width = "32")]
131compile_error!("OpenEntry is only for 64-bit or higher operating system.");
132
133#[cfg(all(not(unix), not(windows)))]
134compile_error!("Unsupported Operating System");
135
136static EXTENSION_ID: AtomicU32 = AtomicU32::new(0);
137
138pub fn init(runtime: &Arc<Runtime>, id: u32) {
139 if std::mem::size_of::<usize>() < 8 { panic!("OpenEntry is only for 64-bit or higher operating system.") }
140
141 EXTENSION_ID.store(id, Ordering::Relaxed);
142
143 #[allow(unused_assignments)] let mut idx: usize = 0;
145
146 load_bindings![
147 idx,
148 runtime,
149
150 fn_bind![fn(&Arc<Runtime>, EventType), Runtime::dispatch_extension_event];
151 fn_bind![fn(&Arc<Runtime>, u32, EventType), Runtime::send_extension_event];
152 fn_bind![fn(&Runtime, VThread), Runtime::dispose_thread];
153 fn_bind![fn(&Runtime, ShutdownType), Runtime::shutdown];
154
155 fn_bind![fn(&Memory) -> *const u8, Memory::ptr];
156
157 fn_bind![fn(&Extensions) -> Values<'_, u32, Arc<Extension>>, Extensions::iter];
158 fn_bind![fn(&Extensions) -> Iter<'_, u32, Arc<Extension>>, Extensions::all];
159 fn_bind![fn(&Extensions, u32) -> Arc<Extension>, Extensions::get];
160
161 fn_bind![fn(&Extension, VThread, Lock, u32, bool) -> (Lock, ExecutorBehaviour), Extension::function_call];
162 fn_bind![fn(&Extension, VThread, Lock, u32, bool) -> (Lock, ExecutorBehaviour), Extension::interrupt_call];
163 fn_bind![fn(&Extension, Arc<Runtime>, EventType), Extension::dispatch_event];
164 fn_bind![fn(&Extension, Arc<Runtime>, u32), Extension::init];
165
166 fn_bind![fn(&BlockInfo, u64) -> Option<&UnlockInfo>, BlockInfo::get];
167 fn_bind![fn(&Stack, usize), Stack::dispose];
168 fn_bind![fn(&Stack) -> u64, Stack::ptr];
169
170 fn_bind![fn(&ExecutorLock) -> &Arc<Mutex<()>>, ExecutorLock::sys];
171 fn_bind![fn(&ExecutorLock) -> &Arc<SpinMutex<()>>, ExecutorLock::spin];
172
173 fn_bind![fn(&VirtualThread, u32) -> Arc<Extension>, VirtualThread::get_extension];
174 fn_bind![fn(&VirtualThread) -> Arc<BlockInfo>, VirtualThread::get_block_info];
175 fn_bind![fn(&VirtualThread) -> bool, VirtualThread::should_stop];
176 fn_bind![fn(&VirtualThread, u64, bool), VirtualThread::set_flag];
177 fn_bind![fn(&VirtualThread, u64) -> bool, VirtualThread::get_flag];
178 fn_bind![fn(&VirtualThread, u8, u32), VirtualThread::sub32];
179 fn_bind![fn(&VirtualThread, u8, u32), VirtualThread::add32];
180 fn_bind![fn(&VirtualThread, u64), VirtualThread::inc_inst];
181 fn_bind![fn(&VirtualThread, u64), VirtualThread::push];
182 fn_bind![fn(&VirtualThread) -> u64, VirtualThread::pop];
183 fn_bind![fn(VThread, ShutdownType), VirtualThread::shutdown];
184 fn_bind![fn(VThread), VirtualThread::dispose];
185
186 fn_bind![fn(u64, VThread) -> VMValue, VMValue::from];
187 fn_bind![fn(&mut VMValue) -> Option<(&mut VMStr, bool)>, VMValue::as_str];
188 fn_bind![fn(&VMValue) -> Option<f64>, VMValue::as_f64];
189
190 fn_bind![fn(&VMStr, &VMStr) -> bool, VMStr::str_eq];
191 fn_bind![fn(&VMStr) -> Option<f64>, VMStr::parse];
192 fn_bind![fn(u64, VThread) -> VMStr, VMStr::from];
193 fn_bind![fn(&VMStr) -> u64, VMStr::as_vm_value];
194 fn_bind![fn(&VMStr) -> *const u8, VMStr::ptr];
195 fn_bind![fn(&VMStr) -> &str, VMStr::as_str];
196 fn_bind![fn(&VMStr) -> u64, VMStr::len];
197 ];
198
199 println!("{idx}");
200
201 unsafe {
202 async_binding!(idx, runtime, Runtime::set_error_data, (), [data: String]);
203 async_binding!(idx, runtime, &Arc, Runtime::spawn, (), [addr: u64]);
204
205 async_binding![idx, runtime, VirtualThread::get_temp_vmstrs, MutexGuard<'_, HashSet<(u64, usize)>>, []];
206 async_binding![idx, runtime, VirtualThread::set_error_data, (), [data: String]];
207
208 async_binding![idx, runtime, VirtualThread::spawn, (), [addr: u64]];
209
210 async_binding![idx, runtime, noself, VMStr::from_str, VMStr, [value: String, thread: VThread]];
211
212 async_binding![idx, runtime, VMStr::drop, (), []];
213 }
214
215 println!("{idx}");
216
217 unsafe {
218 VirtualThread__get_mem_u64 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx] as *const ()));
219 VirtualThread__get_mem_u32 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 1] as *const ()));
220 VirtualThread__get_mem_u16 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 2] as *const ()));
221 VirtualThread__get_mem_u8 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 3] as *const ()));
222 VirtualThread__get_mem_absolute_u64 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 4] as *const ()));
223 VirtualThread__get_mem_absolute_u32 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 5] as *const ()));
224 VirtualThread__get_mem_absolute_u16 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 6] as *const ()));
225 VirtualThread__get_mem_absolute_u8 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 7] as *const ()));
226 VirtualThread__set_mem_absolute_u64 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 8] as *const ()));
227 VirtualThread__set_mem_absolute_u32 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 9] as *const ()));
228 VirtualThread__set_mem_absolute_u16 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 10] as *const ()));
229 VirtualThread__set_mem_absolute_u8 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 11] as *const ()));
230 VirtualThread__set_reg_u64 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 12] as *const ()));
231 VirtualThread__set_reg_u32 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 13] as *const ()));
232 VirtualThread__set_reg_u16 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 14] as *const ()));
233 VirtualThread__set_reg_u8 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 15] as *const ()));
234 VirtualThread__get_reg_u64 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 16] as *const ()));
235 VirtualThread__get_reg_u32 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 17] as *const ()));
236 VirtualThread__get_reg_u16 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 18] as *const ()));
237 VirtualThread__get_reg_u8 = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 19] as *const ()));
238
239 VMStr__push = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 20] as *const ()));
240 VMStr__cloned_push = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 21] as *const ()));
241 ExtensionData__lock = Some(std::mem::transmute::<*const (), _>(runtime.ffi.0[idx + 22] as *const ()));
242 }
243}
244
245pub fn id() -> u32 {
246 EXTENSION_ID.load(Ordering::Relaxed)
247}
248
249pub use tokio;