xref: /wasmtime-44.0.1/crates/core/src/alloc/vec.rs (revision 8a8a9237)
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(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