wasmtime/runtime/store/
data.rs1use crate::module::ModuleRegistry;
2use crate::runtime::vm::{self, GcStore, VMStore};
3use crate::store::StoreOpaque;
4use crate::{StoreContext, StoreContextMut};
5use core::num::NonZeroU64;
6use core::ops::{Index, IndexMut};
7use core::pin::Pin;
8
9#[derive(Copy, Clone, Debug, PartialEq, Eq)]
14pub struct InstanceId(u32);
15wasmtime_environ::entity_impl!(InstanceId);
16
17pub struct StoreData {
18 id: StoreId,
19 #[cfg(feature = "component-model")]
20 pub(crate) components: crate::component::ComponentStoreData,
21}
22
23impl StoreData {
24 pub fn new() -> StoreData {
25 StoreData {
26 id: StoreId::allocate(),
27 #[cfg(feature = "component-model")]
28 components: Default::default(),
29 }
30 }
31
32 pub fn id(&self) -> StoreId {
33 self.id
34 }
35}
36
37impl<I> Index<I> for StoreOpaque
39where
40 StoreData: Index<I>,
41{
42 type Output = <StoreData as Index<I>>::Output;
43
44 #[inline]
45 fn index(&self, index: I) -> &Self::Output {
46 self.store_data.index(index)
47 }
48}
49
50impl<I> IndexMut<I> for StoreOpaque
51where
52 StoreData: IndexMut<I>,
53{
54 #[inline]
55 fn index_mut(&mut self, index: I) -> &mut Self::Output {
56 self.store_data.index_mut(index)
57 }
58}
59
60impl<I, T> Index<I> for StoreContext<'_, T>
62where
63 StoreOpaque: Index<I>,
64{
65 type Output = <StoreOpaque as Index<I>>::Output;
66
67 #[inline]
68 fn index(&self, index: I) -> &Self::Output {
69 self.0.index(index)
70 }
71}
72
73impl<I, T> Index<I> for StoreContextMut<'_, T>
75where
76 StoreOpaque: Index<I>,
77{
78 type Output = <StoreOpaque as Index<I>>::Output;
79
80 #[inline]
81 fn index(&self, index: I) -> &Self::Output {
82 self.0.index(index)
83 }
84}
85
86impl<I, T> IndexMut<I> for StoreContextMut<'_, T>
87where
88 StoreOpaque: IndexMut<I>,
89{
90 #[inline]
91 fn index_mut(&mut self, index: I) -> &mut Self::Output {
92 self.0.index_mut(index)
93 }
94}
95
96impl<I> Index<I> for dyn VMStore + '_
98where
99 StoreOpaque: Index<I>,
100{
101 type Output = <StoreOpaque as Index<I>>::Output;
102
103 fn index(&self, index: I) -> &Self::Output {
104 self.store_opaque().index(index)
105 }
106}
107
108impl<I> IndexMut<I> for dyn VMStore + '_
109where
110 StoreOpaque: IndexMut<I>,
111{
112 fn index_mut(&mut self, index: I) -> &mut Self::Output {
113 self.store_opaque_mut().index_mut(index)
114 }
115}
116
117#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
125#[repr(transparent)] pub struct StoreId(NonZeroU64);
127
128impl StoreId {
129 pub fn allocate() -> StoreId {
132 const OVERFLOW_THRESHOLD: u64 = 1 << 63;
138
139 #[cfg(target_has_atomic = "64")]
140 let id = {
141 use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
142
143 static NEXT_ID: AtomicU64 = AtomicU64::new(0);
147 let id = NEXT_ID.fetch_add(1, Relaxed);
148 if id > OVERFLOW_THRESHOLD {
149 NEXT_ID.store(OVERFLOW_THRESHOLD, Relaxed);
150 panic!("store id allocator overflow");
151 }
152 id
153 };
154
155 #[cfg(not(target_has_atomic = "64"))]
160 let id = {
161 use crate::sync::RwLock;
162 static NEXT_ID: RwLock<u64> = RwLock::new(0);
163
164 let mut lock = NEXT_ID.write();
165 if *lock > OVERFLOW_THRESHOLD {
166 panic!("store id allocator overflow");
167 }
168 let ret = *lock;
169 *lock += 1;
170 ret
171 };
172
173 StoreId(NonZeroU64::new(id + 1).unwrap())
174 }
175
176 #[inline]
177 pub fn assert_belongs_to(&self, store: StoreId) {
178 if *self == store {
179 return;
180 }
181 store_id_mismatch();
182 }
183
184 pub fn as_raw(&self) -> NonZeroU64 {
186 self.0
187 }
188
189 pub fn from_raw(id: NonZeroU64) -> StoreId {
191 StoreId(id)
192 }
193}
194
195#[cold]
196fn store_id_mismatch() {
197 panic!("object used with the wrong store");
198}
199
200#[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
210pub struct StoreInstanceId {
211 store_id: StoreId,
212 instance: InstanceId,
213}
214
215impl StoreInstanceId {
216 pub(crate) fn new(store_id: StoreId, instance: InstanceId) -> StoreInstanceId {
217 StoreInstanceId { store_id, instance }
218 }
219
220 #[inline]
221 pub fn assert_belongs_to(&self, store: StoreId) {
222 self.store_id.assert_belongs_to(store)
223 }
224
225 #[inline]
226 pub fn store_id(&self) -> StoreId {
227 self.store_id
228 }
229
230 #[inline]
231 pub(crate) fn instance(&self) -> InstanceId {
232 self.instance
233 }
234
235 #[inline]
241 pub(crate) fn get<'a>(&self, store: &'a StoreOpaque) -> &'a vm::Instance {
242 self.assert_belongs_to(store.id());
243 store.instance(self.instance)
244 }
245
246 #[inline]
252 pub(crate) fn get_mut<'a>(&self, store: &'a mut StoreOpaque) -> Pin<&'a mut vm::Instance> {
253 self.assert_belongs_to(store.id());
254 store.instance_mut(self.instance)
255 }
256
257 #[inline]
264 pub(crate) fn get_mut_and_module_registry<'a>(
265 &self,
266 store: &'a mut StoreOpaque,
267 ) -> (Pin<&'a mut vm::Instance>, &'a ModuleRegistry) {
268 self.assert_belongs_to(store.id());
269 store.instance_and_module_registry_mut(self.instance)
270 }
271
272 #[inline]
274 pub(crate) fn get_with_gc_store_mut<'a>(
275 &self,
276 store: &'a mut StoreOpaque,
277 ) -> (Option<&'a mut GcStore>, Pin<&'a mut vm::Instance>) {
278 self.assert_belongs_to(store.id());
279 store.optional_gc_store_and_instance_mut(self.instance)
280 }
281}
282
283impl Index<StoreInstanceId> for StoreOpaque {
284 type Output = vm::Instance;
285
286 #[inline]
287 fn index(&self, id: StoreInstanceId) -> &Self::Output {
288 id.get(self)
289 }
290}