xref: /wasmtime-44.0.1/crates/c-api/src/vec.rs (revision cccc4e64)
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 $(<$lt:tt>)?,
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 $(<$lt>)? {
33             size: usize,
34             data: *mut $elem_ty,
35         }
36 
37         impl$(<$lt>)? $name $(<$lt>)? {
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$(<$lt>)? Clone for $name $(<$lt>)? {
83             fn clone(&self) -> Self {
84                 self.as_slice().to_vec().into()
85             }
86         }
87 
88         impl$(<$lt>)? From<Vec<$elem_ty>> for $name $(<$lt>)? {
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$(<$lt>)? Drop for $name $(<$lt>)? {
101             fn drop(&mut self) {
102                 drop(self.take());
103             }
104         }
105 
106         #[unsafe(no_mangle)]
107         pub extern "C" fn $empty(out: &mut $name) {
108             out.size = 0;
109             out.data = ptr::null_mut();
110         }
111 
112         #[unsafe(no_mangle)]
113         pub extern "C" fn $uninit(out: &mut $name, size: usize) {
114             out.set_buffer(vec![Default::default(); size]);
115         }
116 
117         #[unsafe(no_mangle)]
118         pub unsafe extern "C" fn $new $(<$lt>)? (
119             out: &mut $name $(<$lt>)?,
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         #[unsafe(no_mangle)]
128         pub extern "C" fn $copy $(<$lt>)? (
129             out: &mut $name $(<$lt>)?,
130             src: &$name $(<$lt>)?,
131         ) {
132             out.set_buffer(src.as_slice().to_vec());
133         }
134 
135         #[unsafe(no_mangle)]
136         pub extern "C" fn $delete $(<$lt>)? (out: &mut $name $(<$lt>)?) {
137             out.take();
138         }
139     )*};
140 }
141 
142 declare_vecs! {
143     (
144         name: wasm_byte_vec_t,
145         ty: u8,
146         new: wasm_byte_vec_new,
147         empty: wasm_byte_vec_new_empty,
148         uninit: wasm_byte_vec_new_uninitialized,
149         copy: wasm_byte_vec_copy,
150         delete: wasm_byte_vec_delete,
151     )
152     (
153         name: wasm_valtype_vec_t,
154         ty: Option<Box<wasm_valtype_t>>,
155         new: wasm_valtype_vec_new,
156         empty: wasm_valtype_vec_new_empty,
157         uninit: wasm_valtype_vec_new_uninitialized,
158         copy: wasm_valtype_vec_copy,
159         delete: wasm_valtype_vec_delete,
160     )
161     (
162         name: wasm_functype_vec_t,
163         ty: Option<Box<wasm_functype_t>>,
164         new: wasm_functype_vec_new,
165         empty: wasm_functype_vec_new_empty,
166         uninit: wasm_functype_vec_new_uninitialized,
167         copy: wasm_functype_vec_copy,
168         delete: wasm_functype_vec_delete,
169     )
170     (
171         name: wasm_globaltype_vec_t,
172         ty: Option<Box<wasm_globaltype_t>>,
173         new: wasm_globaltype_vec_new,
174         empty: wasm_globaltype_vec_new_empty,
175         uninit: wasm_globaltype_vec_new_uninitialized,
176         copy: wasm_globaltype_vec_copy,
177         delete: wasm_globaltype_vec_delete,
178     )
179     (
180         name: wasm_tabletype_vec_t,
181         ty: Option<Box<wasm_tabletype_t>>,
182         new: wasm_tabletype_vec_new,
183         empty: wasm_tabletype_vec_new_empty,
184         uninit: wasm_tabletype_vec_new_uninitialized,
185         copy: wasm_tabletype_vec_copy,
186         delete: wasm_tabletype_vec_delete,
187     )
188     (
189         name: wasm_memorytype_vec_t,
190         ty: Option<Box<wasm_memorytype_t>>,
191         new: wasm_memorytype_vec_new,
192         empty: wasm_memorytype_vec_new_empty,
193         uninit: wasm_memorytype_vec_new_uninitialized,
194         copy: wasm_memorytype_vec_copy,
195         delete: wasm_memorytype_vec_delete,
196     )
197     (
198         name: wasm_externtype_vec_t,
199         ty: Option<Box<wasm_externtype_t>>,
200         new: wasm_externtype_vec_new,
201         empty: wasm_externtype_vec_new_empty,
202         uninit: wasm_externtype_vec_new_uninitialized,
203         copy: wasm_externtype_vec_copy,
204         delete: wasm_externtype_vec_delete,
205     )
206     (
207         name: wasm_importtype_vec_t,
208         ty: Option<Box<wasm_importtype_t>>,
209         new: wasm_importtype_vec_new,
210         empty: wasm_importtype_vec_new_empty,
211         uninit: wasm_importtype_vec_new_uninitialized,
212         copy: wasm_importtype_vec_copy,
213         delete: wasm_importtype_vec_delete,
214     )
215     (
216         name: wasm_exporttype_vec_t,
217         ty: Option<Box<wasm_exporttype_t>>,
218         new: wasm_exporttype_vec_new,
219         empty: wasm_exporttype_vec_new_empty,
220         uninit: wasm_exporttype_vec_new_uninitialized,
221         copy: wasm_exporttype_vec_copy,
222         delete: wasm_exporttype_vec_delete,
223     )
224     (
225         name: wasm_val_vec_t,
226         ty: wasm_val_t,
227         new: wasm_val_vec_new,
228         empty: wasm_val_vec_new_empty,
229         uninit: wasm_val_vec_new_uninitialized,
230         copy: wasm_val_vec_copy,
231         delete: wasm_val_vec_delete,
232     )
233     (
234         name: wasm_frame_vec_t<'a>,
235         ty: Option<Box<wasm_frame_t<'a>>>,
236         new: wasm_frame_vec_new,
237         empty: wasm_frame_vec_new_empty,
238         uninit: wasm_frame_vec_new_uninitialized,
239         copy: wasm_frame_vec_copy,
240         delete: wasm_frame_vec_delete,
241     )
242     (
243         name: wasm_extern_vec_t,
244         ty: Option<Box<wasm_extern_t>>,
245         new: wasm_extern_vec_new,
246         empty: wasm_extern_vec_new_empty,
247         uninit: wasm_extern_vec_new_uninitialized,
248         copy: wasm_extern_vec_copy,
249         delete: wasm_extern_vec_delete,
250     )
251 }
252