wasmtime/runtime/component/
store.rs

1#[cfg(feature = "component-model-async")]
2use crate::runtime::vm::VMStore;
3use crate::runtime::vm::component::{ComponentInstance, OwnedComponentInstance};
4use crate::store::{StoreData, StoreId, StoreOpaque};
5#[cfg(feature = "component-model-async")]
6use alloc::vec::Vec;
7use core::pin::Pin;
8use wasmtime_environ::PrimaryMap;
9
10#[derive(Default)]
11pub struct ComponentStoreData {
12    instances: PrimaryMap<ComponentInstanceId, Option<OwnedComponentInstance>>,
13}
14
15#[derive(Copy, Clone, Debug, PartialEq, Eq)]
16pub struct ComponentInstanceId(u32);
17wasmtime_environ::entity_impl!(ComponentInstanceId);
18
19impl StoreData {
20    pub(crate) fn push_component_instance(
21        &mut self,
22        data: OwnedComponentInstance,
23    ) -> ComponentInstanceId {
24        let expected = data.get().id();
25        let ret = self.components.instances.push(Some(data));
26        assert_eq!(expected, ret);
27        ret
28    }
29}
30
31impl ComponentStoreData {
32    pub fn next_component_instance_id(&self) -> ComponentInstanceId {
33        self.instances.next_key()
34    }
35
36    #[cfg(feature = "component-model-async")]
37    pub(crate) fn drop_fibers_and_futures(store: &mut dyn VMStore) {
38        let mut fibers = Vec::new();
39        let mut futures = Vec::new();
40        store
41            .concurrent_state_mut()
42            .take_fibers_and_futures(&mut fibers, &mut futures);
43
44        for mut fiber in fibers {
45            fiber.dispose(store);
46        }
47
48        crate::component::concurrent::tls::set(store, move || drop(futures));
49    }
50
51    #[cfg(feature = "component-model-async")]
52    pub(crate) fn assert_guest_tables_empty(&mut self) {
53        for (_, instance) in self.instances.iter_mut() {
54            let Some(instance) = instance.as_mut() else {
55                continue;
56            };
57
58            assert!(
59                instance
60                    .get_mut()
61                    .guest_tables()
62                    .0
63                    .iter()
64                    .all(|(_, table)| table.is_empty())
65            );
66        }
67    }
68}
69
70impl StoreData {
71    pub(crate) fn component_instance(&self, id: ComponentInstanceId) -> &ComponentInstance {
72        self.components.instances[id].as_ref().unwrap().get()
73    }
74
75    pub(crate) fn component_instance_mut(
76        &mut self,
77        id: ComponentInstanceId,
78    ) -> Pin<&mut ComponentInstance> {
79        self.components.instances[id].as_mut().unwrap().get_mut()
80    }
81}
82
83impl StoreOpaque {
84    pub(crate) fn component_instance(&self, id: ComponentInstanceId) -> &ComponentInstance {
85        self.store_data().component_instance(id)
86    }
87}
88
89/// A type used to represent an allocated `ComponentInstance` located within a
90/// store.
91///
92/// This type is held in various locations as a "safe index" into a store. This
93/// encapsulates a `StoreId` which owns the instance as well as the index within
94/// the store's list of which instance it's pointing to.
95///
96/// This type can notably be used to index into a `StoreOpaque` to project out
97/// the `ComponentInstance` that is associated with this id.
98#[repr(C)] // used by reference in the C API
99#[derive(Copy, Clone, Debug, PartialEq, Eq)]
100pub struct StoreComponentInstanceId {
101    store_id: StoreId,
102    instance: ComponentInstanceId,
103}
104
105impl StoreComponentInstanceId {
106    pub(crate) fn new(
107        store_id: StoreId,
108        instance: ComponentInstanceId,
109    ) -> StoreComponentInstanceId {
110        StoreComponentInstanceId { store_id, instance }
111    }
112
113    #[inline]
114    pub fn assert_belongs_to(&self, store: StoreId) {
115        self.store_id.assert_belongs_to(store)
116    }
117
118    #[inline]
119    pub(crate) fn store_id(&self) -> StoreId {
120        self.store_id
121    }
122
123    #[inline]
124    pub(crate) fn instance(&self) -> ComponentInstanceId {
125        self.instance
126    }
127
128    /// Looks up the `vm::ComponentInstance` within `store` that this id points
129    /// to.
130    ///
131    /// # Panics
132    ///
133    /// Panics if `self` does not belong to `store`.
134    pub(crate) fn get<'a>(&self, store: &'a StoreOpaque) -> &'a ComponentInstance {
135        self.assert_belongs_to(store.id());
136        store.component_instance(self.instance)
137    }
138
139    /// Mutable version of `get` above.
140    ///
141    /// # Panics
142    ///
143    /// Panics if `self` does not belong to `store`.
144    pub(crate) fn get_mut<'a>(&self, store: &'a mut StoreOpaque) -> Pin<&'a mut ComponentInstance> {
145        self.from_data_get_mut(store.store_data_mut())
146    }
147
148    /// Same as `get_mut`, but borrows less of a store.
149    pub(crate) fn from_data_get_mut<'a>(
150        &self,
151        store: &'a mut StoreData,
152    ) -> Pin<&'a mut ComponentInstance> {
153        self.assert_belongs_to(store.id());
154        store.component_instance_mut(self.instance)
155    }
156}