diff --git a/crates/wasmtime/src/component/instance.rs b/crates/wasmtime/src/component/instance.rs index 63f70dbab4f4..2bd1ce10753b 100644 --- a/crates/wasmtime/src/component/instance.rs +++ b/crates/wasmtime/src/component/instance.rs @@ -1,12 +1,13 @@ use crate::component::func::HostFunc; use crate::component::matching::InstanceType; use crate::component::{ - Component, ComponentNamedList, Func, Lift, Lower, ResourceImportIndex, ResourceType, TypedFunc, + Component, ComponentItemType, ComponentNamedList, Func, Lift, Lower, ResourceImportIndex, + ResourceType, TypedFunc, }; use crate::instance::OwnedImports; use crate::linker::DefinitionType; use crate::store::{StoreOpaque, Stored}; -use crate::{AsContextMut, Module, StoreContextMut}; +use crate::{AsContextMut, Module, StoreContext, StoreContextMut}; use anyhow::{anyhow, Context, Result}; use indexmap::IndexMap; use std::marker; @@ -61,6 +62,25 @@ pub(crate) struct InstanceData { } impl Instance { + /// Iterates over all types imported by this component instance + /// + /// # Panics + /// + /// Panics if `store` does not own this instance. + pub fn import_types<'a, T: 'a>( + &self, + store: impl Into>, + ) -> impl Iterator { + let store = store.into(); + let data = store.0[self.0].as_ref().unwrap(); + let instance_ty = data.ty(); + data.component + .env_component() + .import_types + .iter() + .map(move |(_, (name, ty))| (name, ComponentItemType::from(ty, &instance_ty))) + } + /// Returns information about the exports of this instance. /// /// This method can be used to extract exported values from this component diff --git a/crates/wasmtime/src/component/mod.rs b/crates/wasmtime/src/component/mod.rs index e820525e261a..0b1e8debcd8d 100644 --- a/crates/wasmtime/src/component/mod.rs +++ b/crates/wasmtime/src/component/mod.rs @@ -24,7 +24,11 @@ pub use self::instance::{ExportInstance, Exports, Instance, InstancePre}; pub use self::linker::{Linker, LinkerInstance, ResourceImportIndex}; pub use self::resource_table::{ResourceTable, ResourceTableError}; pub use self::resources::{Resource, ResourceAny}; -pub use self::types::{ResourceType, Type}; +pub use self::types::{ + ComponentFunc as ComponentFuncType, ComponentInstance as ComponentInstanceType, + ComponentItem as ComponentItemType, CoreFunc as CoreFuncType, Module as ModuleType, + ResourceType, Type, +}; pub use self::values::{Enum, Flags, List, OptionVal, Record, ResultVal, Tuple, Val, Variant}; pub use wasmtime_component_macro::{flags, ComponentType, Lift, Lower}; diff --git a/crates/wasmtime/src/component/types.rs b/crates/wasmtime/src/component/types.rs index 401ba15ec407..7997423447e6 100644 --- a/crates/wasmtime/src/component/types.rs +++ b/crates/wasmtime/src/component/types.rs @@ -2,17 +2,19 @@ use crate::component::matching::InstanceType; use crate::component::values::{self, Val}; +use crate::{ExternType, FuncType}; use anyhow::{anyhow, Result}; use std::fmt; use std::mem; use std::ops::Deref; use std::sync::Arc; use wasmtime_environ::component::{ - CanonicalAbiInfo, ComponentTypes, InterfaceType, ResourceIndex, TypeEnumIndex, TypeFlagsIndex, - TypeListIndex, TypeOptionIndex, TypeRecordIndex, TypeResourceTableIndex, TypeResultIndex, - TypeTupleIndex, TypeVariantIndex, + CanonicalAbiInfo, ComponentTypes, InterfaceType, ResourceIndex, TypeComponentIndex, + TypeComponentInstanceIndex, TypeDef, TypeEnumIndex, TypeFlagsIndex, TypeFuncIndex, + TypeListIndex, TypeModuleIndex, TypeOptionIndex, TypeRecordIndex, TypeResourceTableIndex, + TypeResultIndex, TypeTupleIndex, TypeVariantIndex, }; -use wasmtime_environ::PrimaryMap; +use wasmtime_environ::{PrimaryMap, SignatureIndex}; pub use crate::component::resources::ResourceType; @@ -757,3 +759,195 @@ impl Type { } } } + +/// Core function type +#[derive(Debug)] +pub struct CoreFunc(Handle); + +impl CoreFunc { + pub(crate) fn from(index: SignatureIndex, ty: &InstanceType<'_>) -> Self { + Self(Handle::new(index, ty)) + } + + /// Returns [`FuncType`] associated with this function + pub fn ty(&self) -> FuncType { + FuncType::from_wasm_func_type(self.0.types[self.0.index].clone()) + } +} + +/// Component function type +#[derive(Debug)] +pub struct ComponentFunc(Handle); + +impl ComponentFunc { + pub(crate) fn from(index: TypeFuncIndex, ty: &InstanceType<'_>) -> Self { + Self(Handle::new(index, ty)) + } + + /// Iterates over types of function parameters + pub fn params(&self) -> impl Iterator + '_ { + let params = self.0.types[self.0.index].params; + self.0.types[params] + .types + .iter() + .map(|ty| Type::from(ty, &self.0.instance())) + } + + /// Iterates over types of function results + pub fn results(&self) -> impl Iterator + '_ { + let results = self.0.types[self.0.index].results; + self.0.types[results] + .types + .iter() + .map(|ty| Type::from(ty, &self.0.instance())) + } +} + +/// Core module type +#[derive(Debug)] +pub struct Module(Handle); + +impl Module { + pub(crate) fn from(index: TypeModuleIndex, ty: &InstanceType<'_>) -> Self { + Self(Handle::new(index, ty)) + } + + /// Iterates over imports of the module + pub fn imports(&self) -> impl Iterator { + self.0.types[self.0.index].imports.iter().map(|(name, ty)| { + ( + name, + ExternType::from_wasmtime(self.0.types.module_types(), ty), + ) + }) + } + + /// Iterates over exports of the module + pub fn exports(&self) -> impl Iterator { + self.0.types[self.0.index].exports.iter().map(|(name, ty)| { + ( + name, + ExternType::from_wasmtime(self.0.types.module_types(), ty), + ) + }) + } +} + +/// Component type +#[derive(Debug)] +pub struct Component(Handle); + +impl Component { + pub(crate) fn from(index: TypeComponentIndex, ty: &InstanceType<'_>) -> Self { + Self(Handle::new(index, ty)) + } + + /// Returns import associated with `name`, if such exists in the component + pub fn get_import(&self, name: &str) -> Option { + self.0.types[self.0.index] + .imports + .get(name) + .map(|ty| ComponentItem::from(ty, &self.0.instance())) + } + + /// Iterates over imports of the component + pub fn imports(&self) -> impl Iterator { + self.0.types[self.0.index] + .imports + .iter() + .map(|(name, ty)| (name, ComponentItem::from(ty, &self.0.instance()))) + } + + /// Returns export associated with `name`, if such exists in the component + pub fn get_export(&self, name: &str) -> Option { + self.0.types[self.0.index] + .exports + .get(name) + .map(|ty| ComponentItem::from(ty, &self.0.instance())) + } + + /// Iterates over exports of the component + pub fn exports(&self) -> impl Iterator { + self.0.types[self.0.index] + .exports + .iter() + .map(|(name, ty)| (name, ComponentItem::from(ty, &self.0.instance()))) + } +} + +/// Component instance type +#[derive(Debug)] +pub struct ComponentInstance(Handle); + +impl ComponentInstance { + pub(crate) fn from(index: TypeComponentInstanceIndex, ty: &InstanceType<'_>) -> Self { + Self(Handle::new(index, ty)) + } + + /// Returns export associated with `name`, if such exists in the component instance + pub fn get_export(&self, name: &str) -> Option { + self.0.types[self.0.index] + .exports + .get(name) + .map(|ty| ComponentItem::from(ty, &self.0.instance())) + } + + /// Iterates over exports of the component instance + pub fn exports(&self) -> impl Iterator { + self.0.types[self.0.index] + .exports + .iter() + .map(|(name, ty)| (name, ComponentItem::from(ty, &self.0.instance()))) + } +} + +/// Resource type +#[derive(Debug)] +pub struct Resource(Handle); + +impl Resource { + pub(crate) fn from(index: TypeResourceTableIndex, ty: &InstanceType<'_>) -> Self { + Self(Handle::new(index, ty)) + } + + /// Returns [ResourceType] associated with this resource + pub fn ty(&self) -> ResourceType { + let idx = self.0.types[self.0.index].ty; + self.0.resources[idx] + } +} + +/// Type of an item contained within the component +#[derive(Debug)] +pub enum ComponentItem { + /// Component function item + ComponentFunc(ComponentFunc), + /// Core function item + CoreFunc(CoreFunc), + /// Core module item + Module(Module), + /// Component item + Component(Component), + /// Component instance item + ComponentInstance(ComponentInstance), + /// Interface type item + Type(Type), + /// Resource item + Resource(Resource), +} + +impl ComponentItem { + pub(crate) fn from(def: &TypeDef, ty: &InstanceType<'_>) -> Self { + match def { + TypeDef::Component(idx) => Self::Component(Component::from(*idx, ty)), + TypeDef::ComponentInstance(idx) => { + Self::ComponentInstance(ComponentInstance::from(*idx, ty)) + } + TypeDef::ComponentFunc(idx) => Self::ComponentFunc(ComponentFunc::from(*idx, ty)), + TypeDef::Interface(iface_ty) => Self::Type(Type::from(iface_ty, ty)), + TypeDef::Module(idx) => Self::Module(Module::from(*idx, ty)), + TypeDef::CoreFunc(idx) => Self::CoreFunc(CoreFunc::from(*idx, ty)), + TypeDef::Resource(idx) => Self::Resource(Resource::from(*idx, ty)), + } + } +}