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