wasmtime/runtime/store/
data.rs1use crate::runtime::vm::{self, VMStore};
2use crate::store::StoreOpaque;
3use crate::{StoreContext, StoreContextMut};
4use core::num::NonZeroU64;
5use core::ops::{Index, IndexMut};
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq)]
12pub struct InstanceId(u32);
13wasmtime_environ::entity_impl!(InstanceId);
14
15pub struct StoreData {
16 id: StoreId,
17 #[cfg(feature = "component-model")]
18 pub(crate) components: crate::component::ComponentStoreData,
19}
20
21impl StoreData {
22 pub fn new() -> StoreData {
23 StoreData {
24 id: StoreId::allocate(),
25 #[cfg(feature = "component-model")]
26 components: Default::default(),
27 }
28 }
29
30 pub fn id(&self) -> StoreId {
31 self.id
32 }
33}
34
35impl<I> Index<I> for StoreOpaque
37where
38 StoreData: Index<I>,
39{
40 type Output = <StoreData as Index<I>>::Output;
41
42 #[inline]
43 fn index(&self, index: I) -> &Self::Output {
44 self.store_data.index(index)
45 }
46}
47
48impl<I> IndexMut<I> for StoreOpaque
49where
50 StoreData: IndexMut<I>,
51{
52 #[inline]
53 fn index_mut(&mut self, index: I) -> &mut Self::Output {
54 self.store_data.index_mut(index)
55 }
56}
57
58impl<I, T> Index<I> for StoreContext<'_, T>
60where
61 StoreOpaque: Index<I>,
62{
63 type Output = <StoreOpaque as Index<I>>::Output;
64
65 #[inline]
66 fn index(&self, index: I) -> &Self::Output {
67 self.0.index(index)
68 }
69}
70
71impl<I, T> Index<I> for StoreContextMut<'_, T>
73where
74 StoreOpaque: Index<I>,
75{
76 type Output = <StoreOpaque as Index<I>>::Output;
77
78 #[inline]
79 fn index(&self, index: I) -> &Self::Output {
80 self.0.index(index)
81 }
82}
83
84impl<I, T> IndexMut<I> for StoreContextMut<'_, T>
85where
86 StoreOpaque: IndexMut<I>,
87{
88 #[inline]
89 fn index_mut(&mut self, index: I) -> &mut Self::Output {
90 self.0.index_mut(index)
91 }
92}
93
94impl<I> Index<I> for dyn VMStore + '_
96where
97 StoreOpaque: Index<I>,
98{
99 type Output = <StoreOpaque as Index<I>>::Output;
100
101 fn index(&self, index: I) -> &Self::Output {
102 self.store_opaque().index(index)
103 }
104}
105
106impl<I> IndexMut<I> for dyn VMStore + '_
107where
108 StoreOpaque: IndexMut<I>,
109{
110 fn index_mut(&mut self, index: I) -> &mut Self::Output {
111 self.store_opaque_mut().index_mut(index)
112 }
113}
114
115#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
123#[repr(transparent)] pub struct StoreId(NonZeroU64);
125
126impl StoreId {
127 pub fn allocate() -> StoreId {
130 const OVERFLOW_THRESHOLD: u64 = 1 << 63;
136
137 #[cfg(target_has_atomic = "64")]
138 let id = {
139 use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
140
141 static NEXT_ID: AtomicU64 = AtomicU64::new(0);
145 let id = NEXT_ID.fetch_add(1, Relaxed);
146 if id > OVERFLOW_THRESHOLD {
147 NEXT_ID.store(OVERFLOW_THRESHOLD, Relaxed);
148 panic!("store id allocator overflow");
149 }
150 id
151 };
152
153 #[cfg(not(target_has_atomic = "64"))]
158 let id = {
159 use crate::sync::RwLock;
160 static NEXT_ID: RwLock<u64> = RwLock::new(0);
161
162 let mut lock = NEXT_ID.write();
163 if *lock > OVERFLOW_THRESHOLD {
164 panic!("store id allocator overflow");
165 }
166 let ret = *lock;
167 *lock += 1;
168 ret
169 };
170
171 StoreId(NonZeroU64::new(id + 1).unwrap())
172 }
173
174 #[inline]
175 pub fn assert_belongs_to(&self, store: StoreId) {
176 if *self == store {
177 return;
178 }
179 store_id_mismatch();
180 }
181
182 pub fn as_raw(&self) -> NonZeroU64 {
184 self.0
185 }
186
187 pub fn from_raw(id: NonZeroU64) -> StoreId {
189 StoreId(id)
190 }
191}
192
193#[cold]
194fn store_id_mismatch() {
195 panic!("object used with the wrong store");
196}
197
198#[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
208pub struct StoreInstanceId {
209 store_id: StoreId,
210 instance: InstanceId,
211}
212
213impl StoreInstanceId {
214 pub(crate) fn new(store_id: StoreId, instance: InstanceId) -> StoreInstanceId {
215 StoreInstanceId { store_id, instance }
216 }
217
218 #[inline]
219 pub fn assert_belongs_to(&self, store: StoreId) {
220 self.store_id.assert_belongs_to(store)
221 }
222
223 #[inline]
224 pub fn store_id(&self) -> StoreId {
225 self.store_id
226 }
227
228 #[inline]
229 pub(crate) fn instance(&self) -> InstanceId {
230 self.instance
231 }
232}
233
234impl Index<StoreInstanceId> for StoreOpaque {
235 type Output = vm::Instance;
236
237 #[inline]
238 fn index(&self, id: StoreInstanceId) -> &Self::Output {
239 id.assert_belongs_to(self.id());
240 self.instance(id.instance).instance()
241 }
242}
243
244impl IndexMut<StoreInstanceId> for StoreOpaque {
245 #[inline]
246 fn index_mut(&mut self, id: StoreInstanceId) -> &mut Self::Output {
247 id.assert_belongs_to(self.id());
248 self.instance_mut(id.instance).instance_mut()
249 }
250}