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