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