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.
This commit is contained in:
Peter Huene
2022-08-04 15:45:11 -07:00
committed by GitHub
parent cd847d071d
commit 42233e8eda
4 changed files with 34 additions and 13 deletions

View File

@@ -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(_) => {}

View File

@@ -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,
}
}

View File

@@ -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.

View File

@@ -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))