wasmtime/runtime/component/
store.rs1#[cfg(feature = "component-model-async")]
2use crate::runtime::vm::VMStore;
3use crate::runtime::vm::component::{ComponentInstance, OwnedComponentInstance};
4use crate::store::{StoreData, StoreId, StoreOpaque};
5use crate::{AsContext, AsContextMut, Store, StoreContextMut};
6#[cfg(feature = "component-model-async")]
7use alloc::vec::Vec;
8use core::pin::Pin;
9use wasmtime_environ::PrimaryMap;
10
11const DEFAULT_HOSTCALL_FUEL: usize = 2 << 30;
18
19pub struct ComponentStoreData {
20 instances: PrimaryMap<ComponentInstanceId, Option<OwnedComponentInstance>>,
21
22 hostcall_fuel: usize,
28}
29
30impl Default for ComponentStoreData {
31 fn default() -> Self {
32 Self {
33 instances: PrimaryMap::default(),
34 hostcall_fuel: DEFAULT_HOSTCALL_FUEL,
35 }
36 }
37}
38
39#[derive(Copy, Clone, Debug, PartialEq, Eq)]
40pub struct ComponentInstanceId(u32);
41wasmtime_environ::entity_impl!(ComponentInstanceId);
42
43impl StoreData {
44 pub(crate) fn push_component_instance(
45 &mut self,
46 data: OwnedComponentInstance,
47 ) -> ComponentInstanceId {
48 let expected = data.get().id();
49 let ret = self.components.instances.push(Some(data));
50 assert_eq!(expected, ret);
51 ret
52 }
53}
54
55impl ComponentStoreData {
56 pub fn next_component_instance_id(&self) -> ComponentInstanceId {
57 self.instances.next_key()
58 }
59
60 #[cfg(feature = "component-model-async")]
61 pub(crate) fn drop_fibers_and_futures(store: &mut dyn VMStore) {
62 let mut fibers = Vec::new();
63 let mut futures = Vec::new();
64 store
65 .concurrent_state_mut()
66 .take_fibers_and_futures(&mut fibers, &mut futures);
67
68 for mut fiber in fibers {
69 fiber.dispose(store);
70 }
71
72 crate::component::concurrent::tls::set(store, move || drop(futures));
73 }
74
75 #[cfg(feature = "component-model-async")]
76 pub(crate) fn assert_instance_states_empty(&mut self) {
77 for (_, instance) in self.instances.iter_mut() {
78 let Some(instance) = instance.as_mut() else {
79 continue;
80 };
81
82 assert!(
83 instance
84 .get_mut()
85 .instance_states()
86 .0
87 .iter_mut()
88 .all(|(_, state)| state.handle_table().is_empty()
89 && state.concurrent_state().pending_is_empty())
90 );
91 }
92 }
93}
94
95impl StoreData {
96 pub(crate) fn component_instance(&self, id: ComponentInstanceId) -> &ComponentInstance {
97 self.components.instances[id].as_ref().unwrap().get()
98 }
99
100 pub(crate) fn component_instance_mut(
101 &mut self,
102 id: ComponentInstanceId,
103 ) -> Pin<&mut ComponentInstance> {
104 self.components.instances[id].as_mut().unwrap().get_mut()
105 }
106}
107
108impl StoreOpaque {
109 pub(crate) fn component_instance(&self, id: ComponentInstanceId) -> &ComponentInstance {
110 self.store_data().component_instance(id)
111 }
112
113 pub(crate) fn hostcall_fuel(&self) -> usize {
114 self.store_data().components.hostcall_fuel
115 }
116
117 pub(crate) fn set_hostcall_fuel(&mut self, fuel: usize) {
118 self.store_data_mut().components.hostcall_fuel = fuel;
119 }
120}
121
122#[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
133pub struct StoreComponentInstanceId {
134 store_id: StoreId,
135 instance: ComponentInstanceId,
136}
137
138impl StoreComponentInstanceId {
139 pub(crate) fn new(
140 store_id: StoreId,
141 instance: ComponentInstanceId,
142 ) -> StoreComponentInstanceId {
143 StoreComponentInstanceId { store_id, instance }
144 }
145
146 #[inline]
147 pub fn assert_belongs_to(&self, store: StoreId) {
148 self.store_id.assert_belongs_to(store)
149 }
150
151 #[inline]
152 pub(crate) fn store_id(&self) -> StoreId {
153 self.store_id
154 }
155
156 #[inline]
157 pub(crate) fn instance(&self) -> ComponentInstanceId {
158 self.instance
159 }
160
161 pub(crate) fn get<'a>(&self, store: &'a StoreOpaque) -> &'a ComponentInstance {
168 self.assert_belongs_to(store.id());
169 store.component_instance(self.instance)
170 }
171
172 pub(crate) fn get_mut<'a>(&self, store: &'a mut StoreOpaque) -> Pin<&'a mut ComponentInstance> {
178 self.from_data_get_mut(store.store_data_mut())
179 }
180
181 #[cfg(feature = "component-model-async")]
188 pub(crate) fn get_mut_and_registry<'a>(
189 &self,
190 store: &'a mut StoreOpaque,
191 ) -> (
192 Pin<&'a mut ComponentInstance>,
193 &'a crate::module::ModuleRegistry,
194 ) {
195 let (store_data, registry) = store.store_data_mut_and_registry();
196 let instance = self.from_data_get_mut(store_data);
197 (instance, registry)
198 }
199
200 pub(crate) fn from_data_get_mut<'a>(
202 &self,
203 store: &'a mut StoreData,
204 ) -> Pin<&'a mut ComponentInstance> {
205 self.assert_belongs_to(store.id());
206 store.component_instance_mut(self.instance)
207 }
208}
209
210impl<T> Store<T> {
211 pub fn hostcall_fuel(&self) -> usize {
219 self.as_context().0.hostcall_fuel()
220 }
221
222 pub fn set_hostcall_fuel(&mut self, fuel: usize) {
246 self.as_context_mut().set_hostcall_fuel(fuel)
247 }
248}
249
250impl<T> StoreContextMut<'_, T> {
251 pub fn hostcall_fuel(&self) -> usize {
253 self.0.hostcall_fuel()
254 }
255
256 pub fn set_hostcall_fuel(&mut self, fuel: usize) {
258 self.0.set_hostcall_fuel(fuel)
259 }
260}