1use crate::{
2 wasm_exporttype_t,
3 wasm_extern_t,
4 wasm_externtype_t,
5 wasm_frame_t,
6 wasm_functype_t,
7 wasm_globaltype_t,
8 wasm_importtype_t,
9 wasm_memorytype_t,
10 wasm_tabletype_t,
11 wasm_val_t,
12 wasm_valtype_t,
13};
14use alloc::{boxed::Box, string::String, vec, vec::Vec};
15use core::{mem::MaybeUninit, ptr, slice};
16
17pub type wasm_name_t = wasm_byte_vec_t;
19
20impl wasm_name_t {
21 pub(crate) fn from_name(name: String) -> wasm_name_t {
22 name.into_bytes().into()
23 }
24}
25
26macro_rules! declare_vecs {
27 (
28 $(
29 struct $name:ident $(<$lt:tt>)? {
30 type element = $elem_ty:ty;
31 fn new: $new:ident;
32 fn empty: $empty:ident;
33 fn uninit: $uninit:ident;
34 fn copy: $copy:ident;
35 fn delete: $delete:ident;
36 }
37 )*
38 ) => {$(
39 #[doc = concat!("A Wasm compatible vector with element type [`", stringify!($elem_ty), "`].")]
40 #[doc = ""]
41 #[doc = "# Note"]
42 #[doc = ""]
43 #[doc = concat!("This is similar to `Box<[", stringify!($elem_ty), "]>`.")]
44 #[repr(C)]
45 pub struct $name $(<$lt>)? {
46 size: usize,
47 data: *mut $elem_ty,
48 }
49
50 impl$(<$lt>)? $name $(<$lt>)? {
51 pub fn set_buffer(&mut self, buffer: Box<[$elem_ty]>) {
53 let slice = Box::leak(buffer);
54 self.size = slice.len();
55 self.data = slice.as_mut_ptr();
56 }
57
58 pub fn as_slice(&self) -> &[$elem_ty] {
60 match self.size {
63 0 => &[],
64 _ => {
65 assert!(!self.data.is_null());
66 unsafe { slice::from_raw_parts(self.data, self.size) }
67 }
68 }
69 }
70
71 pub fn as_uninit_slice(&mut self) -> &mut [MaybeUninit<$elem_ty>] {
73 match self.size {
76 0 => &mut [],
77 _ => {
78 assert!(!self.data.is_null());
79 unsafe { slice::from_raw_parts_mut(self.data as _, self.size) }
80 }
81 }
82 }
83
84 pub fn take(&mut self) -> Box<[$elem_ty]> {
90 if self.data.is_null() {
91 return [].into();
92 }
93 let vec = unsafe {
94 Vec::from_raw_parts(self.data, self.size, self.size).into_boxed_slice()
95 };
96 self.size = 0;
97 self.data = ptr::null_mut();
98 return vec;
99 }
100 }
101
102 impl$(<$lt>)? Clone for $name $(<$lt>)? {
103 fn clone(&self) -> Self {
104 let slice: Box<[$elem_ty]> = self.as_slice().into();
105 Self::from(slice)
106 }
107 }
108
109 impl$(<$lt>)? From<Box<[$elem_ty]>> for $name $(<$lt>)? {
110 fn from(slice: Box<[$elem_ty]>) -> Self {
111 let slice = Box::leak(slice);
112 let result = $name {
113 size: slice.len(),
114 data: slice.as_mut_ptr(),
115 };
116 result
117 }
118 }
119
120 impl$(<$lt>)? From<Vec<$elem_ty>> for $name $(<$lt>)? {
121 fn from(vec: Vec<$elem_ty>) -> Self {
122 Self::from(vec.into_boxed_slice())
123 }
124 }
125
126 impl$(<$lt>)? Drop for $name $(<$lt>)? {
127 fn drop(&mut self) {
128 drop(self.take());
129 }
130 }
131
132 #[doc = concat!("Creates an empty [`", stringify!($name),"`]")]
133 #[doc = ""]
134 #[doc = "# Note"]
135 #[doc = ""]
136 #[doc = concat!("Returns the resulting [`", stringify!($name), "`] in `out`.")]
137 #[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
138 #[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
139 pub extern "C" fn $empty(out: &mut $name) {
140 out.size = 0;
141 out.data = ptr::null_mut();
142 }
143
144 #[doc = concat!("Creates an uninitialized [`", stringify!($name),"`] with the given `size`.")]
145 #[doc = ""]
146 #[doc = "# Note"]
147 #[doc = ""]
148 #[doc = concat!("Returns the resulting [`", stringify!($name), "`] in `out`.")]
149 #[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
150 #[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
151 pub extern "C" fn $uninit(out: &mut $name, size: usize) {
152 out.set_buffer(vec![Default::default(); size].into());
153 }
154
155 #[doc = concat!("Creates an new [`", stringify!($name),"`] with the given `size` and `ptr` data.")]
156 #[doc = ""]
157 #[doc = "# Note"]
158 #[doc = ""]
159 #[doc = "- The `ptr` must point to a buffer of length `size` or larger."]
160 #[doc = concat!("- Returns the resulting [`", stringify!($name), "`] in `out`.")]
161 #[doc = ""]
162 #[doc = "# Safety"]
163 #[doc = ""]
164 #[doc = "It is the callers responsibility to provide a valid pair of `ptr` and `size`."]
165 #[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
166 #[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
167 pub unsafe extern "C" fn $new $(<$lt>)? (
168 out: &mut $name $(<$lt>)?,
169 size: usize,
170 ptr: *const $elem_ty,
171 ) {
172 let vec = (0..size).map(|i| ptr.add(i).read()).collect();
173 out.set_buffer(vec);
174 }
175
176 #[doc = concat!("Copies the [`", stringify!($name),"`] in `src`.")]
177 #[doc = ""]
178 #[doc = "# Note"]
179 #[doc = ""]
180 #[doc = concat!("- Returns the resulting [`", stringify!($name), "`] in `out`.")]
181 #[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
182 #[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
183 pub extern "C" fn $copy $(<$lt>)? (
184 out: &mut $name $(<$lt>)?,
185 src: &$name $(<$lt>)?,
186 ) {
187 out.set_buffer(src.as_slice().into());
188 }
189
190 #[doc = concat!("Frees memory associated to the [`", stringify!($name),"`].")]
191 #[cfg_attr(not(feature = "prefix-symbols"), no_mangle)]
192 #[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
193 pub extern "C" fn $delete $(<$lt>)? (out: &mut $name $(<$lt>)?) {
194 out.take();
195 }
196 )*};
197}
198
199declare_vecs! {
200 struct wasm_byte_vec_t {
201 type element = u8;
202 fn new: wasm_byte_vec_new;
203 fn empty: wasm_byte_vec_new_empty;
204 fn uninit: wasm_byte_vec_new_uninitialized;
205 fn copy: wasm_byte_vec_copy;
206 fn delete: wasm_byte_vec_delete;
207 }
208 struct wasm_valtype_vec_t {
209 type element = Option<Box<wasm_valtype_t>>;
210 fn new: wasm_valtype_vec_new;
211 fn empty: wasm_valtype_vec_new_empty;
212 fn uninit: wasm_valtype_vec_new_uninitialized;
213 fn copy: wasm_valtype_vec_copy;
214 fn delete: wasm_valtype_vec_delete;
215 }
216 struct wasm_functype_vec_t {
217 type element = Option<Box<wasm_functype_t>>;
218 fn new: wasm_functype_vec_new;
219 fn empty: wasm_functype_vec_new_empty;
220 fn uninit: wasm_functype_vec_new_uninitialized;
221 fn copy: wasm_functype_vec_copy;
222 fn delete: wasm_functype_vec_delete;
223 }
224 struct wasm_globaltype_vec_t {
225 type element = Option<Box<wasm_globaltype_t>>;
226 fn new: wasm_globaltype_vec_new;
227 fn empty: wasm_globaltype_vec_new_empty;
228 fn uninit: wasm_globaltype_vec_new_uninitialized;
229 fn copy: wasm_globaltype_vec_copy;
230 fn delete: wasm_globaltype_vec_delete;
231 }
232 struct wasm_tabletype_vec_t {
233 type element = Option<Box<wasm_tabletype_t>>;
234 fn new: wasm_tabletype_vec_new;
235 fn empty: wasm_tabletype_vec_new_empty;
236 fn uninit: wasm_tabletype_vec_new_uninitialized;
237 fn copy: wasm_tabletype_vec_copy;
238 fn delete: wasm_tabletype_vec_delete;
239 }
240 struct wasm_memorytype_vec_t {
241 type element = Option<Box<wasm_memorytype_t>>;
242 fn new: wasm_memorytype_vec_new;
243 fn empty: wasm_memorytype_vec_new_empty;
244 fn uninit: wasm_memorytype_vec_new_uninitialized;
245 fn copy: wasm_memorytype_vec_copy;
246 fn delete: wasm_memorytype_vec_delete;
247 }
248 struct wasm_externtype_vec_t {
249 type element = Option<Box<wasm_externtype_t>>;
250 fn new: wasm_externtype_vec_new;
251 fn empty: wasm_externtype_vec_new_empty;
252 fn uninit: wasm_externtype_vec_new_uninitialized;
253 fn copy: wasm_externtype_vec_copy;
254 fn delete: wasm_externtype_vec_delete;
255 }
256 struct wasm_importtype_vec_t {
257 type element = Option<Box<wasm_importtype_t>>;
258 fn new: wasm_importtype_vec_new;
259 fn empty: wasm_importtype_vec_new_empty;
260 fn uninit: wasm_importtype_vec_new_uninitialized;
261 fn copy: wasm_importtype_vec_copy;
262 fn delete: wasm_importtype_vec_delete;
263 }
264 struct wasm_exporttype_vec_t {
265 type element = Option<Box<wasm_exporttype_t>>;
266 fn new: wasm_exporttype_vec_new;
267 fn empty: wasm_exporttype_vec_new_empty;
268 fn uninit: wasm_exporttype_vec_new_uninitialized;
269 fn copy: wasm_exporttype_vec_copy;
270 fn delete: wasm_exporttype_vec_delete;
271 }
272 struct wasm_val_vec_t {
273 type element = wasm_val_t;
274 fn new: wasm_val_vec_new;
275 fn empty: wasm_val_vec_new_empty;
276 fn uninit: wasm_val_vec_new_uninitialized;
277 fn copy: wasm_val_vec_copy;
278 fn delete: wasm_val_vec_delete;
279 }
280 struct wasm_frame_vec_t<'a> {
281 type element = Option<Box<wasm_frame_t<'a>>>;
282 fn new: wasm_frame_vec_new;
283 fn empty: wasm_frame_vec_new_empty;
284 fn uninit: wasm_frame_vec_new_uninitialized;
285 fn copy: wasm_frame_vec_copy;
286 fn delete: wasm_frame_vec_delete;
287 }
288 struct wasm_extern_vec_t {
289 type element = Option<Box<wasm_extern_t>>;
290 fn new: wasm_extern_vec_new;
291 fn empty: wasm_extern_vec_new_empty;
292 fn uninit: wasm_extern_vec_new_uninitialized;
293 fn copy: wasm_extern_vec_copy;
294 fn delete: wasm_extern_vec_delete;
295 }
296}