Skip to content

Commit 1a9e623

Browse files
authored
wasmtime component: get InstancePre from Instance (#10621)
* component::InstancePre contains the types::Component with imported resource types types::Component can be used to create an InstanceType (also added as a hidden method). The construction of InstancePre in the Linker calculates this information already, and the types::Compoonent is just storing Arcs to this information. * Add hidden Instance::instance_pre method which retrieves an InstancePre corresponding to an Instance. All of the information needed to compute the InstancePre is already present in the Store under the Instances's index. This method is pub but doc(hidden) because it is just for typechecking (to be used in the bindings generator), so like other accessors of InstanceType or typecheck methods, it is not exposed in the public API. * InstancePre: rather than keep a ComponentType, just keep the resource type table construct InstanceType right from the contents of InstancePre instead of using the intermediate ComponentType. The net is that InstancePre is just one word larger & one arc clone more expensive than before.
1 parent 0467d6f commit 1a9e623

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

crates/wasmtime/src/runtime/component/instance.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::prelude::*;
1010
use crate::runtime::vm::component::{ComponentInstance, OwnedComponentInstance};
1111
use crate::runtime::vm::{CompiledModuleId, VMFuncRef};
1212
use crate::store::{StoreOpaque, Stored};
13-
use crate::{AsContextMut, Engine, Module, StoreContextMut};
13+
use crate::{AsContext, AsContextMut, Engine, Module, StoreContextMut};
1414
use alloc::sync::Arc;
1515
use core::marker;
1616
use core::ptr::NonNull;
@@ -362,6 +362,20 @@ impl Instance {
362362
index,
363363
))
364364
}
365+
366+
#[doc(hidden)]
367+
pub fn instance_pre<T>(&self, store: &impl AsContext<Data = T>) -> InstancePre<T> {
368+
// This indexing operation asserts the Store owns the Instance.
369+
// Therefore, the InstancePre<T> must match the Store<T>.
370+
let data = store.as_context().0[self.0].as_ref().unwrap();
371+
unsafe {
372+
InstancePre::new_unchecked(
373+
data.component.clone(),
374+
data.imports.clone(),
375+
data.instance().resource_types().clone(),
376+
)
377+
}
378+
}
365379
}
366380

367381
/// Trait used to lookup the export of a component instance.
@@ -815,6 +829,7 @@ impl<'a> Instantiator<'a> {
815829
pub struct InstancePre<T> {
816830
component: Component,
817831
imports: Arc<PrimaryMap<RuntimeImportIndex, RuntimeImport>>,
832+
resource_types: Arc<PrimaryMap<ResourceIndex, ResourceType>>,
818833
_marker: marker::PhantomData<fn() -> T>,
819834
}
820835

@@ -824,6 +839,7 @@ impl<T> Clone for InstancePre<T> {
824839
Self {
825840
component: self.component.clone(),
826841
imports: self.imports.clone(),
842+
resource_types: self.resource_types.clone(),
827843
_marker: self._marker,
828844
}
829845
}
@@ -838,11 +854,13 @@ impl<T> InstancePre<T> {
838854
/// satisfy the imports of the `component` provided.
839855
pub(crate) unsafe fn new_unchecked(
840856
component: Component,
841-
imports: PrimaryMap<RuntimeImportIndex, RuntimeImport>,
857+
imports: Arc<PrimaryMap<RuntimeImportIndex, RuntimeImport>>,
858+
resource_types: Arc<PrimaryMap<ResourceIndex, ResourceType>>,
842859
) -> InstancePre<T> {
843860
InstancePre {
844861
component,
845-
imports: Arc::new(imports),
862+
imports,
863+
resource_types,
846864
_marker: marker::PhantomData,
847865
}
848866
}
@@ -852,6 +870,17 @@ impl<T> InstancePre<T> {
852870
&self.component
853871
}
854872

873+
#[doc(hidden)]
874+
/// Returns the type at which the underlying component will be
875+
/// instantiated. This contains the instantiated type information which
876+
/// was determined by the Linker.
877+
pub fn instance_type(&self) -> InstanceType<'_> {
878+
InstanceType {
879+
types: &self.component.types(),
880+
resources: &self.resource_types,
881+
}
882+
}
883+
855884
/// Returns the underlying engine.
856885
pub fn engine(&self) -> &Engine {
857886
self.component.engine()

crates/wasmtime/src/runtime/component/linker.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,12 @@ impl<T> Linker<T> {
210210
/// `component` imports or if a name defined doesn't match the type of the
211211
/// item imported by the `component` provided.
212212
pub fn instantiate_pre(&self, component: &Component) -> Result<InstancePre<T>> {
213-
self.typecheck(&component)?;
213+
let cx = self.typecheck(&component)?;
214+
215+
// A successful typecheck resolves all of the imported resources used by
216+
// this InstancePre. We keep a clone of this table in the InstancePre
217+
// so that we can construct an InstanceType for typechecking.
218+
let imported_resources = cx.imported_resources.clone();
214219

215220
// Now that all imports are known to be defined and satisfied by this
216221
// linker a list of "flat" import items (aka no instances) is created
@@ -247,7 +252,9 @@ impl<T> Linker<T> {
247252
let i = imports.push(import);
248253
assert_eq!(i, idx);
249254
}
250-
Ok(unsafe { InstancePre::new_unchecked(component.clone(), imports) })
255+
Ok(unsafe {
256+
InstancePre::new_unchecked(component.clone(), Arc::new(imports), imported_resources)
257+
})
251258
}
252259

253260
/// Instantiates the [`Component`] provided into the `store` specified.

crates/wasmtime/src/runtime/component/types.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,14 @@ impl Component {
816816
)
817817
})
818818
}
819+
820+
#[doc(hidden)]
821+
pub fn instance_type(&self) -> InstanceType<'_> {
822+
InstanceType {
823+
types: &self.0.types,
824+
resources: &self.0.resources,
825+
}
826+
}
819827
}
820828

821829
/// Component instance type

0 commit comments

Comments
 (0)