xref: /wasmtime-44.0.1/crates/c-api/src/vec.rs (revision 08b7c877)
1 use crate::{
2     wasm_exporttype_t, wasm_extern_t, wasm_externtype_t, wasm_frame_t, wasm_functype_t,
3     wasm_globaltype_t, wasm_importtype_t, wasm_memorytype_t, wasm_tabletype_t, wasm_val_t,
4     wasm_valtype_t,
5 };
6 use std::mem;
7 use std::mem::MaybeUninit;
8 use std::ptr;
9 use std::slice;
10 
11 pub type wasm_name_t = wasm_byte_vec_t;
12 
13 impl wasm_name_t {
14     pub(crate) fn from_name(name: String) -> wasm_name_t {
15         name.into_bytes().into()
16     }
17 }
18 
19 macro_rules! declare_vecs {
20     (
21         $((
22             name: $name:ident,
23             ty: $elem_ty:ty,
24             new: $new:ident,
25             empty: $empty:ident,
26             uninit: $uninit:ident,
27             copy: $copy:ident,
28             delete: $delete:ident,
29         ))*
30     ) => {$(
31         #[repr(C)]
32         pub struct $name {
33             size: usize,
34             data: *mut $elem_ty,
35         }
36 
37         impl $name {
38             pub fn set_buffer(&mut self, buffer: Vec<$elem_ty>) {
39                 let mut vec = buffer.into_boxed_slice();
40                 self.size = vec.len();
41                 self.data = vec.as_mut_ptr();
42                 mem::forget(vec);
43             }
44 
45             pub fn as_slice(&self) -> &[$elem_ty] {
46                 // Note that we're careful to not create a slice with a null
47                 // pointer as the data pointer, since that isn't defined
48                 // behavior in Rust.
49                 if self.size == 0 {
50                     &[]
51                 } else {
52                     assert!(!self.data.is_null());
53                     unsafe { slice::from_raw_parts(self.data, self.size) }
54                 }
55             }
56 
57             pub fn as_uninit_slice(&mut self) -> &mut [MaybeUninit<$elem_ty>] {
58                 // Note that we're careful to not create a slice with a null
59                 // pointer as the data pointer, since that isn't defined
60                 // behavior in Rust.
61                 if self.size == 0 {
62                     &mut []
63                 } else {
64                     assert!(!self.data.is_null());
65                     unsafe { slice::from_raw_parts_mut(self.data as _, self.size) }
66                 }
67             }
68 
69             pub fn take(&mut self) -> Vec<$elem_ty> {
70                 if self.data.is_null() {
71                     return Vec::new();
72                 }
73                 let vec = unsafe {
74                     Vec::from_raw_parts(self.data, self.size, self.size)
75                 };
76                 self.data = ptr::null_mut();
77                 self.size = 0;
78                 return vec;
79             }
80         }
81 
82         impl Clone for $name {
83             fn clone(&self) -> Self {
84                 self.as_slice().to_vec().into()
85             }
86         }
87 
88         impl From<Vec<$elem_ty>> for $name {
89             fn from(vec: Vec<$elem_ty>) -> Self {
90                 let mut vec = vec.into_boxed_slice();
91                 let result = $name {
92                     size: vec.len(),
93                     data: vec.as_mut_ptr(),
94                 };
95                 mem::forget(vec);
96                 result
97             }
98         }
99 
100         impl Drop for $name {
101             fn drop(&mut self) {
102                 drop(self.take());
103             }
104         }
105 
106         #[no_mangle]
107         pub extern "C" fn $empty(out: &mut $name) {
108             out.size = 0;
109             out.data = ptr::null_mut();
110         }
111 
112         #[no_mangle]
113         pub extern "C" fn $uninit(out: &mut $name, size: usize) {
114             out.set_buffer(vec![Default::default(); size]);
115         }
116 
117         #[no_mangle]
118         pub unsafe extern "C" fn $new(
119             out: &mut $name,
120             size: usize,
121             ptr: *const $elem_ty,
122         ) {
123             let vec = (0..size).map(|i| ptr.add(i).read()).collect();
124             out.set_buffer(vec);
125         }
126 
127         #[no_mangle]
128         pub extern "C" fn $copy(out: &mut $name, src: &$name) {
129             out.set_buffer(src.as_slice().to_vec());
130         }
131 
132         #[no_mangle]
133         pub extern "C" fn $delete(out: &mut $name) {
134             out.take();
135         }
136     )*};
137 }
138 
139 declare_vecs! {
140     (
141         name: wasm_byte_vec_t,
142         ty: u8,
143         new: wasm_byte_vec_new,
144         empty: wasm_byte_vec_new_empty,
145         uninit: wasm_byte_vec_new_uninitialized,
146         copy: wasm_byte_vec_copy,
147         delete: wasm_byte_vec_delete,
148     )
149     (
150         name: wasm_valtype_vec_t,
151         ty: Option<Box<wasm_valtype_t>>,
152         new: wasm_valtype_vec_new,
153         empty: wasm_valtype_vec_new_empty,
154         uninit: wasm_valtype_vec_new_uninitialized,
155         copy: wasm_valtype_vec_copy,
156         delete: wasm_valtype_vec_delete,
157     )
158     (
159         name: wasm_functype_vec_t,
160         ty: Option<Box<wasm_functype_t>>,
161         new: wasm_functype_vec_new,
162         empty: wasm_functype_vec_new_empty,
163         uninit: wasm_functype_vec_new_uninitialized,
164         copy: wasm_functype_vec_copy,
165         delete: wasm_functype_vec_delete,
166     )
167     (
168         name: wasm_globaltype_vec_t,
169         ty: Option<Box<wasm_globaltype_t>>,
170         new: wasm_globaltype_vec_new,
171         empty: wasm_globaltype_vec_new_empty,
172         uninit: wasm_globaltype_vec_new_uninitialized,
173         copy: wasm_globaltype_vec_copy,
174         delete: wasm_globaltype_vec_delete,
175     )
176     (
177         name: wasm_tabletype_vec_t,
178         ty: Option<Box<wasm_tabletype_t>>,
179         new: wasm_tabletype_vec_new,
180         empty: wasm_tabletype_vec_new_empty,
181         uninit: wasm_tabletype_vec_new_uninitialized,
182         copy: wasm_tabletype_vec_copy,
183         delete: wasm_tabletype_vec_delete,
184     )
185     (
186         name: wasm_memorytype_vec_t,
187         ty: Option<Box<wasm_memorytype_t>>,
188         new: wasm_memorytype_vec_new,
189         empty: wasm_memorytype_vec_new_empty,
190         uninit: wasm_memorytype_vec_new_uninitialized,
191         copy: wasm_memorytype_vec_copy,
192         delete: wasm_memorytype_vec_delete,
193     )
194     (
195         name: wasm_externtype_vec_t,
196         ty: Option<Box<wasm_externtype_t>>,
197         new: wasm_externtype_vec_new,
198         empty: wasm_externtype_vec_new_empty,
199         uninit: wasm_externtype_vec_new_uninitialized,
200         copy: wasm_externtype_vec_copy,
201         delete: wasm_externtype_vec_delete,
202     )
203     (
204         name: wasm_importtype_vec_t,
205         ty: Option<Box<wasm_importtype_t>>,
206         new: wasm_importtype_vec_new,
207         empty: wasm_importtype_vec_new_empty,
208         uninit: wasm_importtype_vec_new_uninitialized,
209         copy: wasm_importtype_vec_copy,
210         delete: wasm_importtype_vec_delete,
211     )
212     (
213         name: wasm_exporttype_vec_t,
214         ty: Option<Box<wasm_exporttype_t>>,
215         new: wasm_exporttype_vec_new,
216         empty: wasm_exporttype_vec_new_empty,
217         uninit: wasm_exporttype_vec_new_uninitialized,
218         copy: wasm_exporttype_vec_copy,
219         delete: wasm_exporttype_vec_delete,
220     )
221     (
222         name: wasm_val_vec_t,
223         ty: wasm_val_t,
224         new: wasm_val_vec_new,
225         empty: wasm_val_vec_new_empty,
226         uninit: wasm_val_vec_new_uninitialized,
227         copy: wasm_val_vec_copy,
228         delete: wasm_val_vec_delete,
229     )
230     (
231         name: wasm_frame_vec_t,
232         ty: Option<Box<wasm_frame_t>>,
233         new: wasm_frame_vec_new,
234         empty: wasm_frame_vec_new_empty,
235         uninit: wasm_frame_vec_new_uninitialized,
236         copy: wasm_frame_vec_copy,
237         delete: wasm_frame_vec_delete,
238     )
239     (
240         name: wasm_extern_vec_t,
241         ty: Option<Box<wasm_extern_t>>,
242         new: wasm_extern_vec_new,
243         empty: wasm_extern_vec_new_empty,
244         uninit: wasm_extern_vec_new_uninitialized,
245         copy: wasm_extern_vec_copy,
246         delete: wasm_extern_vec_delete,
247     )
248 }
249