macchiato_rhai_mini/
lib.rs1use std::mem::ManuallyDrop;
2
3use getrandom::register_custom_getrandom;
4use getrandom::Error;
5
6fn host_getrandom(_buf: &mut [u8]) -> Result<(), Error> {
8 Ok(())
9}
10
11register_custom_getrandom!(host_getrandom);
12
13use rhai::{Engine};
14use rhai::packages::Package;
15use rhai::packages::StandardPackage;
16
17#[no_mangle]
24pub extern "C" fn new_vec(capacity: u32) -> u32 {
25 let vec: Vec<u8> = Vec::with_capacity(capacity.try_into().unwrap());
26 let mut vec_md = ManuallyDrop::new(vec);
27 let vec_contents_ptr = vec_md.as_mut_ptr() as u32;
28 let vec_box: Box<[u32; 3]> = Box::new([
29 vec_contents_ptr,
30 vec_md.len().try_into().unwrap(),
31 vec_md.capacity().try_into().unwrap()
32 ]);
33 let vec_ptr = Box::into_raw(vec_box) as *const () as u32;
34 return vec_ptr
35}
36
37#[no_mangle]
40pub extern "C" fn delete_vec(vec: u32) {
41 let vec_ptr = vec as *mut [u32; 3];
42 let vec_box = unsafe { Box::from_raw(vec_ptr) };
43 let vec_arr = *vec_box;
44 let mut _vec: Vec<u8> = unsafe {
45 Vec::from_raw_parts(
46 vec_arr[0] as *mut u8,
47 vec_arr[1] as usize,
48 vec_arr[2] as usize
49 )
50 };
51 }
59
60#[no_mangle]
62pub extern "C" fn resize_vec(vec: i32, capacity: i32) {
63 let vec_ptr = vec as *mut [u32; 3];
64 let mut vec_box = unsafe { Box::from_raw(vec_ptr) };
65 let mut vec_val: Vec<u8> = unsafe {
66 Vec::from_raw_parts(
67 vec_box[0] as *mut u8,
68 vec_box[1] as usize,
69 vec_box[2] as usize
70 )
71 };
72 let capacity_usize: usize = capacity.try_into().unwrap();
73 if capacity_usize < vec_val.len() {
74 vec_val.shrink_to(capacity_usize - vec_val.len());
75 } else {
76 vec_val.reserve(capacity_usize - vec_val.len());
77 }
78 let vec_contents_ptr = vec_val.as_mut_ptr() as u32;
79 vec_box[0] = vec_contents_ptr.try_into().unwrap();
80 vec_box[2] = vec_val.capacity().try_into().unwrap();
81
82 let _vec_val_md = ManuallyDrop::new(vec_val);
83 let _vec_ptr_out = Box::into_raw(vec_box) as *const () as u32;
84}
85
86#[no_mangle]
91pub extern "C" fn run(input_vec: i32, output_vec: i32) {
92 let input_vec_ptr = input_vec as *mut [u32; 3];
94 let input_vec_box = unsafe { Box::from_raw(input_vec_ptr) };
95 let input_vec_val: Vec<u8> = unsafe {
96 Vec::from_raw_parts(
97 input_vec_box[0] as *mut u8,
98 input_vec_box[1] as usize,
99 input_vec_box[2] as usize
100 )
101 };
102
103 let mut engine = Engine::new_raw();
104 let package = StandardPackage::new();
105 package.register_into_engine(&mut engine);
106 let input = unsafe { std::str::from_utf8_unchecked(&input_vec_val) };
107 let eval_result = engine.eval::<String>(input);
108 let result = match eval_result {
109 Ok(result) => result,
110 Err(err) => ["Error".to_string(), err.to_string()].join(": "),
111 };
112
113 let output_vec_ptr = output_vec as *mut [u32; 3];
114 let mut output_vec_box = unsafe { Box::from_raw(output_vec_ptr) };
115 if output_vec_box[2] < result.len().try_into().unwrap() {
116 resize_vec(output_vec, result.len().try_into().unwrap());
117 }
118 let mut output_vec_val: Vec<u8> = unsafe {
119 Vec::from_raw_parts(
120 output_vec_box[0] as *mut u8,
121 output_vec_box[1] as usize,
122 output_vec_box[2] as usize
123 )
124 };
125 output_vec_val.resize(result.len().try_into().unwrap(), 0);
126 output_vec_val.copy_from_slice(result.as_bytes());
127 output_vec_box[1] = result.len().try_into().unwrap();
128
129 let _input_vec_ptr_out = Box::into_raw(input_vec_box) as *const () as u32;
131 let _output_vec_ptr_out = Box::into_raw(output_vec_box) as *const () as u32;
132 let _input_vec_val_md = ManuallyDrop::new(input_vec_val);
133 let _output_vec_val_md = ManuallyDrop::new(output_vec_val);
134}