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 #[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 40 impl 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 53 impl 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)] 70 pub struct StoreComponentInstanceId { 71 store_id: StoreId, 72 instance: ComponentInstanceId, 73 } 74 75 impl 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 } 122