From 42233e8eda482659c8665cf51da833de3c3be3bf Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 4 Aug 2022 15:45:11 -0700 Subject: [PATCH] components: ignore export aliases to types in translation. (#4604) * components: ignore export aliases to types in translation. Currently, translation is ignoring type exports from components during translation by skipping over them before adding them to the exports map. If a component instantiates an inner component and aliases a type export of that instance, it will cause wasmtime to panic with a failure to find the export in the exports map. The fix is to add a representation for exported types to the map that is simply ignored when encountered. This also makes it easier to track places where we would have to support type exports in translation in the future. * Keep type information for type exports. This commit keeps the type information for type exports so that types can be properly aliased from an instance export and thereby adjusting the type index space accordingly. * Add a simple test case for type exports for the component model. --- crates/environ/src/component/translate.rs | 19 +++++++------------ .../environ/src/component/translate/inline.rs | 14 ++++++++++++++ crates/environ/src/component/types.rs | 3 ++- .../misc_testsuite/component-model/types.wast | 11 +++++++++++ 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/crates/environ/src/component/translate.rs b/crates/environ/src/component/translate.rs index 1bc559b38e..1205b66f0d 100644 --- a/crates/environ/src/component/translate.rs +++ b/crates/environ/src/component/translate.rs @@ -612,16 +612,6 @@ impl<'a, 'data> Translator<'a, 'data> { self.validator.component_export_section(&s)?; for export in s { let export = export?; - - // TODO: https://github.com/bytecodealliance/wasmtime/issues/4494 - // Currently, wit-component-based tooling creates components that - // export types to represent the interface of a component so that - // bindings can (potentially) be generated directly from the component - // itself without a wit file. For now, we ignore these exports in Wasmtime. - if wasmparser::ComponentExternalKind::Type == export.kind { - continue; - } - let item = self.kind_to_item(export.kind, export.index); let prev = self.result.exports.insert(export.name, item); assert!(prev.is_none()); @@ -797,7 +787,7 @@ impl<'a, 'data> Translator<'a, 'data> { ComponentItem::ComponentInstance(i) => Some(ComponentItemType::Instance( self.result.component_instances[i], )), - ComponentItem::Module(_) => None, + ComponentItem::Module(_) | ComponentItem::Type(_) => None, }; map.insert(export.name, idx); if let Some(ty) = ty { @@ -835,7 +825,9 @@ impl<'a, 'data> Translator<'a, 'data> { unimplemented!("component values"); } wasmparser::ComponentExternalKind::Type => { - unimplemented!("component type export"); + let index = ComponentTypeIndex::from_u32(index); + let ty = self.types.component_outer_type(0, index); + ComponentItem::Type(ty) } } } @@ -896,6 +888,9 @@ impl<'a, 'data> Translator<'a, 'data> { .component_instances .push(translation.component_instances[idx]); } + ComponentItem::Type(ty) => { + self.types.push_component_typedef(ty); + } // ignored during this type pass ComponentItem::Module(_) => {} diff --git a/crates/environ/src/component/translate/inline.rs b/crates/environ/src/component/translate/inline.rs index a1244eedcf..bfb5590f32 100644 --- a/crates/environ/src/component/translate/inline.rs +++ b/crates/environ/src/component/translate/inline.rs @@ -224,6 +224,10 @@ enum ComponentItemDef<'a> { Instance(ComponentInstanceDef<'a>), Func(ComponentFuncDef<'a>), Module(ModuleDef<'a>), + // TODO: https://github.com/bytecodealliance/wasmtime/issues/4494 + // The entity is a type; currently unsupported but represented here + // so that type exports can be ignored for now. + Type, } #[derive(Clone)] @@ -377,6 +381,7 @@ impl<'a> Inliner<'a> { ComponentItemDef::Func(i) => { frame.component_funcs.push(i.clone()); } + ComponentItemDef::Type => {} }, // Lowering a component function to a core wasm function is @@ -703,6 +708,9 @@ impl<'a> Inliner<'a> { let instance = i.clone(); frame.component_instances.push(instance); } + ComponentItemDef::Type => { + // Ignore type aliases for now + } }, } } @@ -920,6 +928,11 @@ impl<'a> Inliner<'a> { ComponentItemDef::Component(_) => { bail!("exporting a component from the root component is not supported") } + + ComponentItemDef::Type => { + // Ignore type exports for now + return Ok(()); + } }; map.insert(name.to_string(), export); @@ -966,6 +979,7 @@ impl<'a> InlinerFrame<'a> { ComponentItemDef::Instance(self.component_instances[i].clone()) } ComponentItem::Module(i) => ComponentItemDef::Module(self.modules[i].clone()), + ComponentItem::Type(_) => ComponentItemDef::Type, } } diff --git a/crates/environ/src/component/types.rs b/crates/environ/src/component/types.rs index b3f964e55d..3f1ade9d77 100644 --- a/crates/environ/src/component/types.rs +++ b/crates/environ/src/component/types.rs @@ -94,7 +94,7 @@ indices! { pub struct TypeExpectedIndex(u32); // ======================================================================== - // Index types used to identify modules and components during compliation. + // Index types used to identify modules and components during compilation. /// Index into a "closed over variables" list for components used to /// implement outer aliases. For more information on this see the @@ -181,6 +181,7 @@ pub enum ComponentItem { Module(ModuleIndex), Component(ComponentIndex), ComponentInstance(ComponentInstanceIndex), + Type(TypeDef), } /// Runtime information about the type information contained within a component. diff --git a/tests/misc_testsuite/component-model/types.wast b/tests/misc_testsuite/component-model/types.wast index 845005358e..91d75c4a75 100644 --- a/tests/misc_testsuite/component-model/types.wast +++ b/tests/misc_testsuite/component-model/types.wast @@ -102,6 +102,17 @@ ) ) +;; type exports work +(component $C + (component $C2 + (type string) + (export "x" (type 0)) + ) + (instance (instantiate 0)) + (alias export 0 "x" (type)) + (export "x" (type 0)) +) + (component (core module $m (func (export "") (param i32) (result i32) local.get 0)) (core instance $m (instantiate $m))