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