wasmtime_c_api/
vec.rs

1use 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};
6use std::mem;
7use std::mem::MaybeUninit;
8use std::ptr;
9use std::slice;
10
11pub type wasm_name_t = wasm_byte_vec_t;
12
13impl wasm_name_t {
14    pub(crate) fn from_name(name: String) -> wasm_name_t {
15        name.into_bytes().into()
16    }
17}
18
19macro_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")]
152pub(crate) use declare_vecs;
153
154declare_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}