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