xref: /wasmtime-44.0.1/crates/c-api/src/vec.rs (revision d3e7548e)
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 pub(crate) use declare_vecs;
143 
144 declare_vecs! {
145     (
146         name: wasm_byte_vec_t,
147         ty: u8,
148         new: wasm_byte_vec_new,
149         empty: wasm_byte_vec_new_empty,
150         uninit: wasm_byte_vec_new_uninitialized,
151         copy: wasm_byte_vec_copy,
152         delete: wasm_byte_vec_delete,
153     )
154     (
155         name: wasm_valtype_vec_t,
156         ty: Option<Box<wasm_valtype_t>>,
157         new: wasm_valtype_vec_new,
158         empty: wasm_valtype_vec_new_empty,
159         uninit: wasm_valtype_vec_new_uninitialized,
160         copy: wasm_valtype_vec_copy,
161         delete: wasm_valtype_vec_delete,
162     )
163     (
164         name: wasm_functype_vec_t,
165         ty: Option<Box<wasm_functype_t>>,
166         new: wasm_functype_vec_new,
167         empty: wasm_functype_vec_new_empty,
168         uninit: wasm_functype_vec_new_uninitialized,
169         copy: wasm_functype_vec_copy,
170         delete: wasm_functype_vec_delete,
171     )
172     (
173         name: wasm_globaltype_vec_t,
174         ty: Option<Box<wasm_globaltype_t>>,
175         new: wasm_globaltype_vec_new,
176         empty: wasm_globaltype_vec_new_empty,
177         uninit: wasm_globaltype_vec_new_uninitialized,
178         copy: wasm_globaltype_vec_copy,
179         delete: wasm_globaltype_vec_delete,
180     )
181     (
182         name: wasm_tabletype_vec_t,
183         ty: Option<Box<wasm_tabletype_t>>,
184         new: wasm_tabletype_vec_new,
185         empty: wasm_tabletype_vec_new_empty,
186         uninit: wasm_tabletype_vec_new_uninitialized,
187         copy: wasm_tabletype_vec_copy,
188         delete: wasm_tabletype_vec_delete,
189     )
190     (
191         name: wasm_memorytype_vec_t,
192         ty: Option<Box<wasm_memorytype_t>>,
193         new: wasm_memorytype_vec_new,
194         empty: wasm_memorytype_vec_new_empty,
195         uninit: wasm_memorytype_vec_new_uninitialized,
196         copy: wasm_memorytype_vec_copy,
197         delete: wasm_memorytype_vec_delete,
198     )
199     (
200         name: wasm_externtype_vec_t,
201         ty: Option<Box<wasm_externtype_t>>,
202         new: wasm_externtype_vec_new,
203         empty: wasm_externtype_vec_new_empty,
204         uninit: wasm_externtype_vec_new_uninitialized,
205         copy: wasm_externtype_vec_copy,
206         delete: wasm_externtype_vec_delete,
207     )
208     (
209         name: wasm_importtype_vec_t,
210         ty: Option<Box<wasm_importtype_t>>,
211         new: wasm_importtype_vec_new,
212         empty: wasm_importtype_vec_new_empty,
213         uninit: wasm_importtype_vec_new_uninitialized,
214         copy: wasm_importtype_vec_copy,
215         delete: wasm_importtype_vec_delete,
216     )
217     (
218         name: wasm_exporttype_vec_t,
219         ty: Option<Box<wasm_exporttype_t>>,
220         new: wasm_exporttype_vec_new,
221         empty: wasm_exporttype_vec_new_empty,
222         uninit: wasm_exporttype_vec_new_uninitialized,
223         copy: wasm_exporttype_vec_copy,
224         delete: wasm_exporttype_vec_delete,
225     )
226     (
227         name: wasm_val_vec_t,
228         ty: wasm_val_t,
229         new: wasm_val_vec_new,
230         empty: wasm_val_vec_new_empty,
231         uninit: wasm_val_vec_new_uninitialized,
232         copy: wasm_val_vec_copy,
233         delete: wasm_val_vec_delete,
234     )
235     (
236         name: wasm_frame_vec_t<'a>,
237         ty: Option<Box<wasm_frame_t<'a>>>,
238         new: wasm_frame_vec_new,
239         empty: wasm_frame_vec_new_empty,
240         uninit: wasm_frame_vec_new_uninitialized,
241         copy: wasm_frame_vec_copy,
242         delete: wasm_frame_vec_delete,
243     )
244     (
245         name: wasm_extern_vec_t,
246         ty: Option<Box<wasm_extern_t>>,
247         new: wasm_extern_vec_new,
248         empty: wasm_extern_vec_new_empty,
249         uninit: wasm_extern_vec_new_uninitialized,
250         copy: wasm_extern_vec_copy,
251         delete: wasm_extern_vec_delete,
252     )
253 }
254