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