1 use crate::alloc::{TryClone, try_realloc}; 2 use crate::error::OutOfMemory; 3 use core::marker::PhantomData; 4 use core::{ 5 fmt, mem, 6 ops::{Deref, DerefMut, Index, IndexMut}, 7 }; 8 use serde::ser::SerializeSeq; 9 use std_alloc::alloc::Layout; 10 use std_alloc::boxed::Box; 11 use std_alloc::vec::Vec as StdVec; 12 13 /// Like `std::vec::Vec` but all methods that allocate force handling allocation 14 /// failure. 15 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 16 pub struct Vec<T> { 17 inner: StdVec<T>, 18 } 19 20 impl<T> Default for Vec<T> { 21 fn default() -> Self { 22 Self { 23 inner: Default::default(), 24 } 25 } 26 } 27 28 impl<T: fmt::Debug> fmt::Debug for Vec<T> { 29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 30 fmt::Debug::fmt(&self.inner, f) 31 } 32 } 33 34 impl<T> TryClone for Vec<T> 35 where 36 T: TryClone, 37 { 38 fn try_clone(&self) -> Result<Self, OutOfMemory> { 39 let mut v = Vec::with_capacity(self.len())?; 40 for x in self { 41 v.push(x.try_clone()?).expect("reserved capacity"); 42 } 43 Ok(v) 44 } 45 } 46 47 impl<T> Vec<T> { 48 /// Same as [`std::vec::Vec::new`]. 49 pub const fn new() -> Self { 50 Self { 51 inner: StdVec::new(), 52 } 53 } 54 55 /// Same as [`std::vec::Vec::with_capacity`] but returns an error on 56 /// allocation failure. 57 pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory> { 58 let mut v = Self::new(); 59 v.reserve(capacity)?; 60 Ok(v) 61 } 62 63 /// Same as [`std::vec::Vec::reserve`] but returns an error on allocation 64 /// failure. 65 pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> { 66 self.inner.try_reserve(additional).map_err(|_| { 67 OutOfMemory::new( 68 self.len() 69 .saturating_add(additional) 70 .saturating_mul(mem::size_of::<T>()), 71 ) 72 }) 73 } 74 75 /// Same as [`std::vec::Vec::reserve_exact`] but returns an error on allocation 76 /// failure. 77 pub fn reserve_exact(&mut self, additional: usize) -> Result<(), OutOfMemory> { 78 self.inner 79 .try_reserve_exact(additional) 80 .map_err(|_| OutOfMemory::new(self.len().saturating_add(additional))) 81 } 82 83 /// Same as [`std::vec::Vec::len`]. 84 pub fn len(&self) -> usize { 85 self.inner.len() 86 } 87 88 /// Same as [`std::vec::Vec::capacity`]. 89 pub fn capacity(&self) -> usize { 90 self.inner.capacity() 91 } 92 93 /// Same as [`std::vec::Vec::is_empty`]. 94 pub fn is_empty(&self) -> bool { 95 self.inner.is_empty() 96 } 97 98 /// Same as [`std::vec::Vec::push`] but returns an error on allocation 99 /// failure. 100 pub fn push(&mut self, value: T) -> Result<(), OutOfMemory> { 101 self.reserve(1)?; 102 self.inner.push(value); 103 Ok(()) 104 } 105 106 /// Same as [`std::vec::Vec::pop`]. 107 pub fn pop(&mut self) -> Option<T> { 108 self.inner.pop() 109 } 110 111 /// Same as [`std::vec::Vec::into_raw_parts`]. 112 pub fn into_raw_parts(mut self) -> (*mut T, usize, usize) { 113 // NB: Can't use `Vec::into_raw_parts` until our MSRV is >= 1.93. 114 #[cfg(not(miri))] 115 { 116 let ptr = self.as_mut_ptr(); 117 let len = self.len(); 118 let cap = self.capacity(); 119 mem::forget(self); 120 (ptr, len, cap) 121 } 122 // NB: Miri requires using `into_raw_parts`, but always run on nightly, 123 // so it's fine to use there. 124 #[cfg(miri)] 125 { 126 let _ = &mut self; 127 self.inner.into_raw_parts() 128 } 129 } 130 131 /// Same as [`std::vec::Vec::from_raw_parts`]. 132 pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { 133 Vec { 134 // Safety: Same as our unsafe contract. 135 inner: unsafe { StdVec::from_raw_parts(ptr, length, capacity) }, 136 } 137 } 138 139 /// Same as [`std::vec::Vec::drain`]. 140 pub fn drain<R>(&mut self, range: R) -> std_alloc::vec::Drain<'_, T> 141 where 142 R: core::ops::RangeBounds<usize>, 143 { 144 self.inner.drain(range) 145 } 146 147 /// Same as [`std::vec::Vec::shrink_to_fit`] but returns an error on 148 /// allocation failure. 149 pub fn shrink_to_fit(&mut self) -> Result<(), OutOfMemory> { 150 // If our length is already equal to our capacity, then there is nothing 151 // to shrink. 152 if self.len() == self.capacity() { 153 return Ok(()); 154 } 155 156 // `realloc` requires a non-zero original layout as well as a non-zero 157 // destination layout, so this guard ensures that the sizes below are 158 // all nonzero. This handles a few cases: 159 // 160 // * If `len == cap == 0` then no allocation has ever been made. 161 // * If `len == 0` and `cap != 0` then this function effectively frees 162 // the memory. 163 // * If `T` is a zero-sized type then nothing's been allocated either. 164 // 165 // In all of these cases delegate to the standard library's 166 // `shrink_to_fit` which is guaranteed to not perform a `realloc`. 167 if self.is_empty() || mem::size_of::<T>() == 0 { 168 self.inner.shrink_to_fit(); 169 return Ok(()); 170 } 171 172 let (ptr, len, cap) = mem::take(self).into_raw_parts(); 173 let layout = Layout::array::<T>(cap).unwrap(); 174 let new_size = Layout::array::<T>(len).unwrap().size(); 175 176 // SAFETY: `ptr` was previously allocated in the global allocator, 177 // `layout` has a nonzero size and matches the current allocation of 178 // `ptr`, `new_size` is nonzero, and `new_size` is a valid array size 179 // for `len` elements given its constructor. 180 let result = unsafe { try_realloc(ptr.cast(), layout, new_size) }; 181 182 match result { 183 Ok(ptr) => { 184 // SAFETY: `result` is allocated with the global allocator and 185 // has room for exactly `[T; len]`. 186 *self = unsafe { Self::from_raw_parts(ptr.cast::<T>().as_ptr(), len, len) }; 187 Ok(()) 188 } 189 Err(oom) => { 190 // SAFETY: If reallocation fails then it's guaranteed that the 191 // original allocation is not tampered with, so it's safe to 192 // reassemble the original vector. 193 *self = unsafe { Vec::from_raw_parts(ptr, len, cap) }; 194 Err(oom) 195 } 196 } 197 } 198 199 /// Same as [`std::vec::Vec::into_boxed_slice`] but returns an error on 200 /// allocation failure. 201 pub fn into_boxed_slice(mut self) -> Result<Box<[T]>, OutOfMemory> { 202 self.shrink_to_fit()?; 203 204 // Once we've shrunken the allocation to just the actual length, we can 205 // use `std`'s `into_boxed_slice` without fear of `realloc`. 206 Ok(self.inner.into_boxed_slice()) 207 } 208 } 209 210 impl<T> Deref for Vec<T> { 211 type Target = [T]; 212 213 fn deref(&self) -> &Self::Target { 214 &self.inner 215 } 216 } 217 218 impl<T> DerefMut for Vec<T> { 219 fn deref_mut(&mut self) -> &mut Self::Target { 220 &mut self.inner 221 } 222 } 223 224 impl<T> Index<usize> for Vec<T> { 225 type Output = T; 226 227 fn index(&self, index: usize) -> &Self::Output { 228 &self.inner[index] 229 } 230 } 231 232 impl<T> IndexMut<usize> for Vec<T> { 233 fn index_mut(&mut self, index: usize) -> &mut Self::Output { 234 &mut self.inner[index] 235 } 236 } 237 238 impl<T> IntoIterator for Vec<T> { 239 type Item = T; 240 type IntoIter = std_alloc::vec::IntoIter<T>; 241 242 fn into_iter(self) -> Self::IntoIter { 243 self.inner.into_iter() 244 } 245 } 246 247 impl<'a, T> IntoIterator for &'a Vec<T> { 248 type Item = &'a T; 249 250 type IntoIter = core::slice::Iter<'a, T>; 251 252 fn into_iter(self) -> Self::IntoIter { 253 (**self).iter() 254 } 255 } 256 257 impl<'a, T> IntoIterator for &'a mut Vec<T> { 258 type Item = &'a mut T; 259 260 type IntoIter = core::slice::IterMut<'a, T>; 261 262 fn into_iter(self) -> Self::IntoIter { 263 (**self).iter_mut() 264 } 265 } 266 267 impl<T> From<Vec<T>> for StdVec<T> { 268 fn from(v: Vec<T>) -> Self { 269 v.inner 270 } 271 } 272 273 impl<T> From<StdVec<T>> for Vec<T> { 274 fn from(inner: StdVec<T>) -> Self { 275 Self { inner } 276 } 277 } 278 279 impl<T> From<Box<[T]>> for Vec<T> { 280 fn from(boxed_slice: Box<[T]>) -> Self { 281 Self::from(StdVec::from(boxed_slice)) 282 } 283 } 284 285 impl<T> serde::ser::Serialize for Vec<T> 286 where 287 T: serde::ser::Serialize, 288 { 289 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 290 where 291 S: serde::Serializer, 292 { 293 let mut seq = serializer.serialize_seq(Some(self.len()))?; 294 for elem in self { 295 seq.serialize_element(elem)?; 296 } 297 seq.end() 298 } 299 } 300 301 impl<'de, T> serde::de::Deserialize<'de> for Vec<T> 302 where 303 T: serde::de::Deserialize<'de>, 304 { 305 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 306 where 307 D: serde::Deserializer<'de>, 308 { 309 struct Visitor<T>(PhantomData<fn() -> Vec<T>>); 310 311 impl<'de, T> serde::de::Visitor<'de> for Visitor<T> 312 where 313 T: serde::de::Deserialize<'de>, 314 { 315 type Value = Vec<T>; 316 317 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { 318 f.write_str("a `wasmtime_core::alloc::Vec` sequence") 319 } 320 321 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> 322 where 323 A: serde::de::SeqAccess<'de>, 324 { 325 use serde::de::Error as _; 326 327 let mut v = Vec::new(); 328 329 if let Some(len) = seq.size_hint() { 330 v.reserve_exact(len).map_err(|oom| A::Error::custom(oom))?; 331 } 332 333 while let Some(elem) = seq.next_element()? { 334 v.push(elem).map_err(|oom| A::Error::custom(oom))?; 335 } 336 337 Ok(v) 338 } 339 } 340 341 deserializer.deserialize_seq(Visitor(PhantomData)) 342 } 343 } 344 345 #[cfg(test)] 346 mod tests { 347 use super::Vec; 348 use crate::error::OutOfMemory; 349 350 #[test] 351 fn test_into_boxed_slice() -> Result<(), OutOfMemory> { 352 assert_eq!(*Vec::<i32>::new().into_boxed_slice()?, []); 353 354 let mut vec = Vec::new(); 355 vec.push(1)?; 356 assert_eq!(*vec.into_boxed_slice()?, [1]); 357 358 let mut vec = Vec::with_capacity(2)?; 359 vec.push(1)?; 360 assert_eq!(*vec.into_boxed_slice()?, [1]); 361 362 let mut vec = Vec::with_capacity(2)?; 363 vec.push(1_u128)?; 364 assert_eq!(*vec.into_boxed_slice()?, [1]); 365 366 assert_eq!(*Vec::<()>::new().into_boxed_slice()?, []); 367 368 let mut vec = Vec::new(); 369 vec.push(())?; 370 assert_eq!(*vec.into_boxed_slice()?, [()]); 371 372 let vec = Vec::<i32>::with_capacity(2)?; 373 assert_eq!(*vec.into_boxed_slice()?, []); 374 Ok(()) 375 } 376 } 377