1mod alloc;
2mod fns;
3mod heap;
4mod heap_wrap;
5use std::{
6 collections::HashMap,
7 fmt::Debug,
8 ops::{Deref, DerefMut},
9 sync::{Arc, Mutex},
10 thread::JoinHandle,
11};
12pub use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
13
14pub use alloc::*;
15pub use fns::*;
16pub use heap::*;
17pub use heap_wrap::*;
18
19use crate::runtime::RuntimeValue;
20
21pub struct RetBufValue(pub BufValue);
22
23impl From<BufValue> for RetBufValue {
24 fn from(item: BufValue) -> Self {
25 Self(item)
26 }
27}
28
29pub struct Options {
30 pub pre: *const str,
31 pub r_val: Option<RetBufValue>,
32 r_runtime: Option<Box<dyn RuntimeValue>>,
33}
34
35unsafe impl Send for Options {}
36unsafe impl Sync for Options {}
37
38impl Debug for Options {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 f.write_fmt(format_args!("Options {{ <inner> }}"))
41 }
42}
43
44impl Options {
45 pub fn new() -> Self {
46 Self {
47 pre: "" as _,
48 r_val: None,
49 r_runtime: None,
50 }
51 }
52
53 pub fn set_return_val(&mut self, val: BufValue) {
54 self.r_val = Some(RetBufValue(val));
55 }
56
57 pub(crate) fn r_val(self) -> BufValue {
58 let val = self.r_val;
59
60 val.expect("Error").0
61 }
62
63 pub(crate) fn rem_r_runtime(&mut self) -> Option<Box<dyn RuntimeValue>> {
64 self.r_runtime.take()
65 }
66
67 pub fn set_r_runtime(&mut self, val: Box<dyn RuntimeValue>) {
68 self.r_runtime = Some(val);
69 }
70}
71
72#[derive(PartialEq, Debug)]
73pub struct StrPointer(pub *const str);
74
75impl ToString for StrPointer {
76 fn to_string(&self) -> String {
77 unsafe { (*self.0).to_string() }
78 }
79}
80
81macro_rules! extends {
82 (
83 $(
84 $good:ident $x:ident => $y:ty
85 ),*
86 ) => {
87 #[derive(Default, Clone, Debug)]
88 pub(crate) struct ExtendsInternal {
89 $(
90 pub(crate) $x: HashMap<&'static str, fn(*mut $y, Args, HeapWrapper, &str, &mut Options) -> ()>
91 ),*
92 }
93
94 #[derive(Default)]
95 pub struct Extends {
96 $(
97 pub $x: &'static [(&'static str, fn(*mut $y, Args, HeapWrapper, &str, &mut Options) -> ())]
98 ),*
99 }
100
101 #[derive(Default)]
102 pub struct PrototypeDocs {
103 $(
104 pub $x: HashMap<&'static str, &'static [&'static str; 3]>
105 ),*
106 }
107
108 pub(crate) fn get_handle_runtime_ptr<'a>(
109 heap: &mut Heap,
110 val: &BufValue,
111 caller: &'a str,
112 ) -> Option<*const ()> {
113 let (ext, ar) = heap.get_extends();
114
115 crate::paste! {
116 match val {
117 $(
118 BufValue::[<$good>](_) => {
119 let scope1 = &ext.$x;
120 let scope2 = &ar.$x;
121
122 let f = match scope1.get(caller) {
124 Some(v) => v,
125 None => match scope2.get(caller) {
126 Some(v) => v,
127 None => { return None }
128 },
129 };
130
131 return Some(f as *const _ as *const ());
132 }
133 )*
134 _ => return None
135 }
136 }
137 }
138
139 pub(crate) fn handle_runtime<'a>(
140 heap: &mut Heap,
141 val: &mut BufValue,
142 caller: &'a str,
143 v: &'a [&'static str],
144 a: HeapWrapper,
145 c: &str,
146 o: &'a mut Options,
147 ) -> Option<()> {
148 let (ext, ar) = heap.get_extends();
149
150 crate::paste! {
151 match val {
152 $(
153 BufValue::[<$good>](data) => {
154 let scope1 = &ext.$x;
155 let scope2 = &ar.$x;
156
157 let f = match scope1.get(caller) {
159 Some(v) => v,
160 None => match scope2.get(caller) {
161 Some(v) => v,
162 None => { return None }
163 },
164 };
165
166 f(data as _, v, a, c, o);
167 }
168 )*
169 _ => return None
170 }
171 }
172
173 Some(())
174 }
175
176 pub(crate) fn set_into_extends(extends: Extends, extends_internal: &mut ExtendsInternal) {
177 $(
178 for (k, v) in extends.$x.into_iter() {
179 if let Some(_) = extends_internal.$x.insert(k, *v) {
180 panic!("{} already exists. Please ensure that you do not have two prototypes with the same name FOR THE WHOLE APPLICATION", k);
181 }
182 }
183 )*
184 }
185 };
186}
187
188extends! {
189 Int int => i64,
190 U_Int uint => u64,
191 Float float => f64,
192 Str str_slice => String,
193 Bool boolean => bool,
194 Array array => Vec<BufValue>,
195 Object object => HashMap<String, Box<BufValue>>,
196 Faillable faillable => Result<Box<BufValue>, String>,
197 StrPointer str_ptr => StrPointer,
198 Pointer ptr => *const BufValue,
199 PointerMut mut_ptr => *mut BufValue,
200 AsyncTask async_task => AppliesEq<JoinHandle<BufValue>>,
201 Sender sender => AppliesEq<UnboundedSender<BufValue>>,
202 Listener listener => AppliesEq<UnboundedReceiver<BufValue>>,
203 ArcPointer arc_ptr => Arc<Box<BufValue>>,
204 ArcMutexPointer arc_mut_ptr => AppliesEq<Arc<Mutex<Box<BufValue>>>>
205}
206
207#[allow(non_camel_case_types)]
208#[derive(PartialEq, Debug)]
209pub enum BufValue {
210 Int(i64),
211 U_Int(u64),
212 Float(f64),
213 Str(String),
214 Bool(bool),
215 Array(Vec<Self>),
216 Object(HashMap<String, Box<Self>>),
217 Faillable(Result<Box<Self>, String>),
218 StrPointer(StrPointer),
219 Pointer(*const Self),
220 PointerMut(*mut Self),
221 ArcPointer(Arc<Box<Self>>),
222 ArcMutexPointer(AppliesEq<Arc<Mutex<Box<Self>>>>),
223 AsyncTask(AppliesEq<JoinHandle<Self>>),
224 Sender(AppliesEq<UnboundedSender<Self>>),
225 Listener(AppliesEq<UnboundedReceiver<Self>>),
226 RuntimeRaw(AppliesEq<RawRTValue>),
227}
228
229unsafe impl Send for BufValue {}
230unsafe impl Sync for BufValue {}
231
232macro_rules! implement_buf {
233 ($($i:ident => $x:ty),*) => {
234 $(
235 impl From<$x> for BufValue {
236 fn from(item: $x) -> Self {
237 Self::$i(item)
238 }
239 }
240 )*
241 };
242}
243
244implement_buf! {
245 Str => String,
246 Int => i64,
247 U_Int => u64,
248 Float => f64,
249 Bool => bool,
250 StrPointer => StrPointer,
251 AsyncTask => AppliesEq<JoinHandle<Self>>
252}
253
254#[derive(Debug)]
255pub struct AppliesEq<T>(pub T);
256
257unsafe impl<T> Send for AppliesEq<T> {}
258unsafe impl<T> Sync for AppliesEq<T> {}
259
260impl<T> PartialEq for AppliesEq<T> {
261 fn eq(&self, _: &Self) -> bool {
262 false
263 }
264}
265
266impl<T> Deref for AppliesEq<T> {
267 type Target = T;
268
269 fn deref(&self) -> &Self::Target {
270 &self.0
271 }
272}
273
274impl<T> DerefMut for AppliesEq<T> {
275 fn deref_mut(&mut self) -> &mut Self::Target {
276 &mut self.0
277 }
278}
279
280impl BufValue {
281 pub fn type_of(&self) -> String {
282 match &self {
283 BufValue::Array(_) => "array".to_string(),
284 BufValue::Bool(_) => "bool".to_string(),
285 BufValue::Float(_) => "float".to_string(),
286 BufValue::Int(_) => "int".to_string(),
287 BufValue::U_Int(_) => "u_int".to_string(),
288 BufValue::Object(_) => "object".to_string(),
289 BufValue::StrPointer(_) | BufValue::Str(_) => "string".to_string(),
290 BufValue::Faillable(res) => match res {
291 Ok(t) => format!("<success {}>", t.type_of()),
292 Err(t) => format!("<err {}>", &t),
293 },
294 BufValue::Pointer(ptr) => {
295 if ptr.is_null() {
296 return "<ptr *ref NULL>".into();
297 }
298
299 unsafe { &**ptr }.type_of()
300 }
301 BufValue::PointerMut(ptr) => {
302 if ptr.is_null() {
303 return "<ptr *mut NULL>".into();
304 }
305
306 unsafe { &**ptr }.type_of()
307 }
308 BufValue::Sender(_) => "<sender ?event>".into(),
309 BufValue::Listener(_) => "<listener ?event>".into(),
310 BufValue::AsyncTask(t) => {
311 if t.is_finished() {
312 "<async recv...\\0>".into()
313 } else {
314 "<async pending...>".into()
315 }
316 }
317 BufValue::RuntimeRaw(_) => "<runtime rt>".into(),
318 BufValue::ArcPointer(a) => a.type_of(),
319 BufValue::ArcMutexPointer(_) => format!("<mutex *>"),
320 }
321 }
322
323 pub fn display(&self) -> String {
324 match &self {
325 BufValue::Array(c) => c.iter().map(|x| x.display()).collect::<Vec<_>>().join(", "),
326 BufValue::Bool(a) => a.to_string(),
327 BufValue::Float(f) => f.to_string(),
328 BufValue::Int(i) => i.to_string(),
329 BufValue::U_Int(u) => u.to_string(),
330 BufValue::Object(c) => format!("{c:#?}"),
331 BufValue::Str(c) => c.to_string(),
332 BufValue::StrPointer(c) => c.to_string(),
333 e => e.type_of(),
334 }
335 }
336
337 pub fn get_vec_mut(&mut self) -> Option<&mut Vec<BufValue>> {
338 match self {
339 BufValue::Array(a) => Some(a),
340 _ => None,
341 }
342 }
343
344 pub fn gt(&self, other: &BufValue) -> bool {
345 match (self, other) {
346 (BufValue::Int(a), BufValue::Int(b)) => a > b,
347 (BufValue::Int(a), BufValue::U_Int(b)) => (*a as i128) > (*b as i128),
348 (BufValue::U_Int(a), BufValue::U_Int(b)) => a > b,
349 (BufValue::U_Int(a), BufValue::Int(b)) => (*a as i128) > (*b as i128),
350 (BufValue::Float(a), BufValue::Float(b)) => a > b,
351 _ => false,
352 }
353 }
354
355 pub fn lt(&self, other: &BufValue) -> bool {
356 match (self, other) {
357 (BufValue::Int(a), BufValue::Int(b)) => a < b,
358 (BufValue::Int(a), BufValue::U_Int(b)) => (*a as i128) < (*b as i128),
359 (BufValue::U_Int(a), BufValue::U_Int(b)) => a < b,
360 (BufValue::U_Int(a), BufValue::Int(b)) => (*a as i128) < (*b as i128),
361 (BufValue::Float(a), BufValue::Float(b)) => a < b,
362 _ => false,
363 }
364 }
365
366 pub fn eq(&self, other: &BufValue) -> bool {
367 match (self, other) {
368 (BufValue::Int(a), BufValue::U_Int(b)) => (*a as i128) == (*b as i128),
369 (BufValue::U_Int(a), BufValue::Int(b)) => (*a as i128) == (*b as i128),
370 _ => self == other,
371 }
372 }
373}