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