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