wasmtime/runtime/component/
store.rs

1use crate::runtime::vm::component::{ComponentInstance, OwnedComponentInstance};
2use crate::store::{StoreData, StoreId, StoreOpaque};
3use core::pin::Pin;
4use wasmtime_environ::PrimaryMap;
5
6#[derive(Default)]
7pub struct ComponentStoreData {
8    instances: PrimaryMap<ComponentInstanceId, Option<OwnedComponentInstance>>,
9}
10
11#[derive(Copy, Clone, Debug, PartialEq, Eq)]
12pub struct ComponentInstanceId(u32);
13wasmtime_environ::entity_impl!(ComponentInstanceId);
14
15impl StoreData {
16    pub(crate) fn push_component_instance(
17        &mut self,
18        data: OwnedComponentInstance,
19    ) -> ComponentInstanceId {
20        let expected = data.get().id();
21        let ret = self.components.instances.push(Some(data));
22        assert_eq!(expected, ret);
23        ret
24    }
25}
26
27impl ComponentStoreData {
28    pub fn next_component_instance_id(&self) -> ComponentInstanceId {
29        self.instances.next_key()
30    }
31
32    #[cfg(feature = "component-model-async")]
33    pub(crate) fn drop_fibers(store: &mut StoreOpaque) {
34        _ = store;
35        // This function will actually do something when runtime support for
36        // `component-model-async` is merged.
37    }
38}
39
40impl StoreData {
41    pub(crate) fn component_instance(&self, id: ComponentInstanceId) -> &ComponentInstance {
42        self.components.instances[id].as_ref().unwrap().get()
43    }
44
45    pub(crate) fn component_instance_mut(
46        &mut self,
47        id: ComponentInstanceId,
48    ) -> Pin<&mut ComponentInstance> {
49        self.components.instances[id].as_mut().unwrap().get_mut()
50    }
51}
52
53impl StoreOpaque {
54    pub(crate) fn component_instance(&self, id: ComponentInstanceId) -> &ComponentInstance {
55        self.store_data().component_instance(id)
56    }
57}
58
59/// A type used to represent an allocated `ComponentInstance` located within a
60/// store.
61///
62/// This type is held in various locations as a "safe index" into a store. This
63/// encapsulates a `StoreId` which owns the instance as well as the index within
64/// the store's list of which instance it's pointing to.
65///
66/// This type can notably be used to index into a `StoreOpaque` to project out
67/// the `ComponentInstance` that is associated with this id.
68#[repr(C)] // used by reference in the C API
69#[derive(Copy, Clone, Debug, PartialEq, Eq)]
70pub struct StoreComponentInstanceId {
71    store_id: StoreId,
72    instance: ComponentInstanceId,
73}
74
75impl StoreComponentInstanceId {
76    pub(crate) fn new(
77        store_id: StoreId,
78        instance: ComponentInstanceId,
79    ) -> StoreComponentInstanceId {
80        StoreComponentInstanceId { store_id, instance }
81    }
82
83    #[inline]
84    pub fn assert_belongs_to(&self, store: StoreId) {
85        self.store_id.assert_belongs_to(store)
86    }
87
88    #[inline]
89    pub(crate) fn instance(&self) -> ComponentInstanceId {
90        self.instance
91    }
92
93    /// Looks up the `vm::ComponentInstance` within `store` that this id points
94    /// to.
95    ///
96    /// # Panics
97    ///
98    /// Panics if `self` does not belong to `store`.
99    pub(crate) fn get<'a>(&self, store: &'a StoreOpaque) -> &'a ComponentInstance {
100        self.assert_belongs_to(store.id());
101        store.component_instance(self.instance)
102    }
103
104    /// Mutable version of `get` above.
105    ///
106    /// # Panics
107    ///
108    /// Panics if `self` does not belong to `store`.
109    pub(crate) fn get_mut<'a>(&self, store: &'a mut StoreOpaque) -> Pin<&'a mut ComponentInstance> {
110        self.from_data_get_mut(store.store_data_mut())
111    }
112
113    /// Same as `get_mut`, but borrows less of a store.
114    pub(crate) fn from_data_get_mut<'a>(
115        &self,
116        store: &'a mut StoreData,
117    ) -> Pin<&'a mut ComponentInstance> {
118        self.assert_belongs_to(store.id());
119        store.component_instance_mut(self.instance)
120    }
121}