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