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