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