Skip to content

Commit fe90768

Browse files
authored
Add a fallible-allocations-only version of SecondaryMap (#12454)
* Add some fallible allocation methods to `cranelift_entity::SecondaryMap` We will use these in the fallible-allocations-only version of this type that we will add to Wasmtime. In the cases where there wasn't already an infallible version of the method (e.g. `try_insert`, because we have just used mutable indexing up till now instead of `insert`) I still defined the infallible version, since it seemed weird to have one but not the other. Part of #12069 * Add a fallible-allocations-only version of `SecondaryMap` Part of #12069
1 parent 63ecb81 commit fe90768

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed

crates/environ/src/collections.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
33
mod entity_set;
44
mod primary_map;
5+
mod secondary_map;
56

67
pub use entity_set::EntitySet;
78
pub use primary_map::PrimaryMap;
9+
pub use secondary_map::SecondaryMap;
810
pub use wasmtime_core::alloc::{TryNew, Vec, try_new};
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use crate::error::OutOfMemory;
2+
use core::ops::Index;
3+
use cranelift_entity::{EntityRef, SecondaryMap as Inner};
4+
5+
/// Like [`cranelift_entity::SecondaryMap`] but all allocation is fallible.
6+
pub struct SecondaryMap<K, V>
7+
where
8+
K: EntityRef,
9+
V: Clone,
10+
{
11+
inner: Inner<K, V>,
12+
}
13+
14+
impl<K, V> SecondaryMap<K, V>
15+
where
16+
K: EntityRef,
17+
V: Clone,
18+
{
19+
/// Same as [`cranelift_entity::SecondaryMap::new`].
20+
pub fn new() -> Self
21+
where
22+
V: Default,
23+
{
24+
Self {
25+
inner: Inner::new(),
26+
}
27+
}
28+
29+
/// Same as [`cranelift_entity::SecondaryMap::try_with_capacity`].
30+
pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory>
31+
where
32+
V: Default,
33+
{
34+
Ok(Self {
35+
inner: Inner::try_with_capacity(capacity)?,
36+
})
37+
}
38+
39+
/// Same as [`cranelift_entity::SecondaryMap::with_default`].
40+
pub fn with_default(default: V) -> Self {
41+
Self {
42+
inner: Inner::with_default(default),
43+
}
44+
}
45+
46+
/// Same as [`cranelift_entity::SecondaryMap::capacity`].
47+
pub fn capacity(&self) -> usize {
48+
self.inner.capacity()
49+
}
50+
51+
/// Same as [`cranelift_entity::SecondaryMap::get`].
52+
pub fn get(&self, k: K) -> Option<&V> {
53+
self.inner.get(k)
54+
}
55+
56+
/// Same as [`cranelift_entity::SecondaryMap::get_mut`].
57+
pub fn get_mut(&mut self, k: K) -> Option<&mut V> {
58+
self.inner.get_mut(k)
59+
}
60+
61+
/// Same as [`cranelift_entity::SecondaryMap::try_insert`].
62+
pub fn insert(&mut self, k: K, v: V) -> Result<Option<V>, OutOfMemory> {
63+
self.inner.try_insert(k, v)
64+
}
65+
66+
/// Same as [`cranelift_entity::SecondaryMap::is_empty`].
67+
pub fn is_empty(&self) -> bool {
68+
self.inner.is_empty()
69+
}
70+
71+
/// Same as [`cranelift_entity::SecondaryMap::clear`].
72+
pub fn clear(&mut self) {
73+
self.inner.clear()
74+
}
75+
76+
/// Same as [`cranelift_entity::SecondaryMap::iter`].
77+
pub fn iter(&self) -> cranelift_entity::Iter<'_, K, V> {
78+
self.inner.iter()
79+
}
80+
81+
/// Same as [`cranelift_entity::SecondaryMap::iter_mut`].
82+
pub fn iter_mut(&mut self) -> cranelift_entity::IterMut<'_, K, V> {
83+
self.inner.iter_mut()
84+
}
85+
86+
/// Same as [`cranelift_entity::SecondaryMap::keys`].
87+
pub fn keys(&self) -> cranelift_entity::Keys<K> {
88+
self.inner.keys()
89+
}
90+
91+
/// Same as [`cranelift_entity::SecondaryMap::values`].
92+
pub fn values(&self) -> core::slice::Iter<'_, V> {
93+
self.inner.values()
94+
}
95+
96+
/// Same as [`cranelift_entity::SecondaryMap::values_mut`].
97+
pub fn values_mut(&mut self) -> core::slice::IterMut<'_, V> {
98+
self.inner.values_mut()
99+
}
100+
101+
/// Resize the map to have `n` entries by adding default entries as needed.
102+
pub fn resize(&mut self, n: usize) -> Result<(), OutOfMemory> {
103+
self.inner.try_resize(n)
104+
}
105+
}
106+
107+
impl<K, V> Default for SecondaryMap<K, V>
108+
where
109+
K: EntityRef,
110+
V: Clone + Default,
111+
{
112+
fn default() -> SecondaryMap<K, V> {
113+
SecondaryMap::new()
114+
}
115+
}
116+
117+
// NB: no `IndexMut` implementation because it requires allocation but the trait
118+
// doesn't allow for fallibility.
119+
impl<K, V> Index<K> for SecondaryMap<K, V>
120+
where
121+
K: EntityRef,
122+
V: Clone,
123+
{
124+
type Output = V;
125+
126+
fn index(&self, k: K) -> &V {
127+
&self.inner[k]
128+
}
129+
}

0 commit comments

Comments
 (0)