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