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