Skip to content

Commit 8d16aad

Browse files
author
Peter Huene
authored
Fix component model bugs in wasmparser and wasm-compose. (#935)
* wasmparser: fix component validation for type instantiation arguments. This commit fixes validation when a component is instantiated that imports a type and the type is provided as an instantiation argument. Previously, the type was being ignored and not populated in the list of instantiation arguments, resulting in an incorrect validation message of "instantiation argument not provided". The fix is to add type arguments to the arguments list. * wasm-compose: fix incorrect type indexes caused by type imports. Currently `wasm-compose` writes all core and component types out in contiguous sections. The problem with this approach is that imports of types occur *after* these sections, so an import of a type will be assigned an incorrect type index. The fix is to simply encode core types, component types, and imports as encountered rather than trying to group them all into the same section.
1 parent 673e74b commit 8d16aad

File tree

6 files changed

+157
-112
lines changed

6 files changed

+157
-112
lines changed

crates/wasm-compose/src/encoding.rs

Lines changed: 60 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,27 @@ impl Encodable for InstanceType {
7272
}
7373
}
7474

75-
impl Encodable for (&mut CoreTypeSection, &mut ComponentTypeSection) {
75+
struct EncodableEntityType<'a> {
76+
start_type_count: u32,
77+
core_types: &'a mut CoreTypeSection,
78+
component_types: &'a mut ComponentTypeSection,
79+
}
80+
81+
impl<'a> Encodable for EncodableEntityType<'a> {
7682
fn type_count(&self) -> u32 {
77-
self.1.len()
83+
self.start_type_count + self.component_types.len()
7884
}
7985

8086
fn core_type_count(&self) -> u32 {
81-
self.0.len()
87+
self.core_types.len()
8288
}
8389

8490
fn ty(&mut self) -> ComponentTypeEncoder {
85-
self.1.ty()
91+
self.component_types.ty()
8692
}
8793

8894
fn core_type(&mut self) -> CoreTypeEncoder {
89-
self.0.ty()
95+
self.core_types.ty()
9096
}
9197
}
9298

@@ -132,12 +138,12 @@ impl<'a> TypeEncoder<'a> {
132138
let mut types = TypeMap::new();
133139

134140
for (name, url, ty) in imports {
135-
let ty = self.encodable_component_entity_type(&mut encoded, &mut types, ty);
141+
let ty = self.component_entity_type(&mut encoded, &mut types, ty);
136142
encoded.import(name, url, ty);
137143
}
138144

139145
for (name, url, ty) in exports {
140-
let ty = self.encodable_component_entity_type(&mut encoded, &mut types, ty);
146+
let ty = self.component_entity_type(&mut encoded, &mut types, ty);
141147
encoded.export(name, url, ty);
142148
}
143149

@@ -152,7 +158,7 @@ impl<'a> TypeEncoder<'a> {
152158
let mut types = TypeMap::new();
153159

154160
for (name, url, ty) in exports {
155-
let ty = self.encodable_component_entity_type(&mut encoded, &mut types, ty);
161+
let ty = self.component_entity_type(&mut encoded, &mut types, ty);
156162
encoded.export(name, url, ty);
157163
}
158164

@@ -180,17 +186,6 @@ impl<'a> TypeEncoder<'a> {
180186
encoded
181187
}
182188

183-
pub fn component_entity_type(
184-
&self,
185-
core_types: &mut CoreTypeSection,
186-
component_types: &mut ComponentTypeSection,
187-
types: &mut TypeMap<'a>,
188-
ty: wasmparser::types::ComponentEntityType,
189-
) -> ComponentTypeRef {
190-
let mut encodable = (core_types, component_types);
191-
self.encodable_component_entity_type(&mut encodable, types, ty)
192-
}
193-
194189
fn entity_type(
195190
&self,
196191
encodable: &mut ModuleType,
@@ -239,7 +234,7 @@ impl<'a> TypeEncoder<'a> {
239234
}
240235
}
241236

242-
fn encodable_component_entity_type(
237+
fn component_entity_type(
243238
&self,
244239
encodable: &mut impl Encodable,
245240
types: &mut TypeMap<'a>,
@@ -988,14 +983,6 @@ impl<'a> ImportMap<'a> {
988983
}
989984
}
990985

991-
#[derive(Default)]
992-
struct ImportEncodingContext<'a> {
993-
types: TypeMap<'a>,
994-
import_section: ComponentImportSection,
995-
core_type_section: CoreTypeSection,
996-
type_section: ComponentTypeSection,
997-
}
998-
999986
/// Used to encode a composition graph as a new WebAssembly component.
1000987
pub(crate) struct CompositionGraphEncoder<'a> {
1001988
/// The options for the encoding.
@@ -1063,28 +1050,25 @@ impl<'a> CompositionGraphEncoder<'a> {
10631050

10641051
fn encode_imports(&mut self, encoded: &mut Component) -> Result<()> {
10651052
let imports = ImportMap::new(!self.options.define_components, self.graph)?;
1066-
let mut context = ImportEncodingContext::default();
1067-
1053+
let mut type_map = TypeMap::default();
10681054
for (name, entry) in imports.0 {
10691055
match entry {
10701056
ImportMapEntry::Component(component) => {
1071-
self.encode_component_import(&mut context, name.as_ref(), "", component);
1057+
self.encode_component_import(encoded, name.as_ref(), "", component);
10721058
}
10731059
ImportMapEntry::Argument(arg) => {
10741060
let index = match arg.kind {
10751061
ArgumentImportKind::Item(component, ty) => self.encode_item_import(
1076-
&mut context,
1062+
encoded,
1063+
&mut type_map,
10771064
name.as_ref(),
10781065
arg.url,
10791066
component,
10801067
ty,
10811068
),
1082-
ArgumentImportKind::Instance(exports) => self.encode_instance_import(
1083-
&mut context,
1084-
name.as_ref(),
1085-
arg.url,
1086-
exports,
1087-
),
1069+
ArgumentImportKind::Instance(exports) => {
1070+
self.encode_instance_import(encoded, name.as_ref(), arg.url, exports)
1071+
}
10881072
};
10891073

10901074
self.imported_args
@@ -1093,35 +1077,18 @@ impl<'a> CompositionGraphEncoder<'a> {
10931077
}
10941078
}
10951079

1096-
if !context.core_type_section.is_empty() {
1097-
encoded.section(&context.core_type_section);
1098-
}
1099-
1100-
if !context.type_section.is_empty() {
1101-
encoded.section(&context.type_section);
1102-
}
1103-
1104-
if !context.import_section.is_empty() {
1105-
encoded.section(&context.import_section);
1106-
}
1107-
11081080
Ok(())
11091081
}
11101082

11111083
fn encode_component_import(
11121084
&mut self,
1113-
context: &mut ImportEncodingContext<'a>,
1085+
encoded: &mut Component,
11141086
name: &str,
11151087
url: &str,
11161088
component: &'a crate::graph::Component,
11171089
) -> u32 {
1118-
let type_index = self.define_component_type(&mut context.type_section, component);
1119-
let index = self.import(
1120-
&mut context.import_section,
1121-
name,
1122-
url,
1123-
ComponentTypeRef::Component(type_index),
1124-
);
1090+
let type_index = self.define_component_type(encoded, component);
1091+
let index = self.import(encoded, name, url, ComponentTypeRef::Component(type_index));
11251092

11261093
assert!(self
11271094
.encoded_components
@@ -1133,29 +1100,40 @@ impl<'a> CompositionGraphEncoder<'a> {
11331100

11341101
fn encode_item_import(
11351102
&mut self,
1136-
context: &mut ImportEncodingContext<'a>,
1103+
encoded: &mut Component,
1104+
type_map: &mut TypeMap<'a>,
11371105
name: &str,
11381106
url: &str,
11391107
component: &'a crate::graph::Component,
11401108
ty: ComponentEntityType,
11411109
) -> u32 {
1142-
let prev_type_count = context.type_section.len();
1110+
let mut core_type_section = CoreTypeSection::new();
1111+
let mut type_section = ComponentTypeSection::new();
11431112

11441113
let encoder = TypeEncoder::new(&component.types);
1145-
let ty = encoder.component_entity_type(
1146-
&mut context.core_type_section,
1147-
&mut context.type_section,
1148-
&mut context.types,
1149-
ty,
1150-
);
11511114

1152-
self.types += context.type_section.len() - prev_type_count;
1153-
self.import(&mut context.import_section, name, url, ty)
1115+
let mut encodable = EncodableEntityType {
1116+
start_type_count: self.types,
1117+
core_types: &mut core_type_section,
1118+
component_types: &mut type_section,
1119+
};
1120+
let ty = encoder.component_entity_type(&mut encodable, type_map, ty);
1121+
1122+
if !core_type_section.is_empty() {
1123+
encoded.section(&core_type_section);
1124+
}
1125+
1126+
if !type_section.is_empty() {
1127+
encoded.section(&type_section);
1128+
self.types += type_section.len();
1129+
}
1130+
1131+
self.import(encoded, name, url, ty)
11541132
}
11551133

11561134
fn encode_instance_import(
11571135
&mut self,
1158-
context: &mut ImportEncodingContext<'a>,
1136+
encoded: &mut Component,
11591137
name: &str,
11601138
url: &str,
11611139
exports: IndexMap<&'a str, (&'a str, &'a crate::graph::Component, ComponentEntityType)>,
@@ -1164,20 +1142,17 @@ impl<'a> CompositionGraphEncoder<'a> {
11641142
let mut types = TypeMap::new();
11651143
for (name, (url, component, ty)) in exports {
11661144
let encoder = TypeEncoder::new(&component.types);
1167-
let ty = encoder.encodable_component_entity_type(&mut instance_type, &mut types, ty);
1145+
let ty = encoder.component_entity_type(&mut instance_type, &mut types, ty);
11681146
instance_type.export(name, url, ty);
11691147
}
11701148

11711149
let index = self.types;
1172-
context.type_section.instance(&instance_type);
1150+
let mut type_section = ComponentTypeSection::new();
1151+
type_section.instance(&instance_type);
1152+
encoded.section(&type_section);
11731153
self.types += 1;
11741154

1175-
self.import(
1176-
&mut context.import_section,
1177-
name,
1178-
url,
1179-
ComponentTypeRef::Instance(index),
1180-
)
1155+
self.import(encoded, name, url, ComponentTypeRef::Instance(index))
11811156
}
11821157

11831158
fn encode_instantiations(&mut self, encoded: &mut Component) -> Result<()> {
@@ -1306,11 +1281,14 @@ impl<'a> CompositionGraphEncoder<'a> {
13061281

13071282
fn define_component_type(
13081283
&mut self,
1309-
type_section: &mut ComponentTypeSection,
1284+
encoded: &mut Component,
13101285
component: &crate::graph::Component,
13111286
) -> u32 {
1312-
let type_index = self.types;
1287+
let mut type_section = ComponentTypeSection::new();
13131288
type_section.component(&component.ty());
1289+
encoded.section(&type_section);
1290+
1291+
let type_index = self.types;
13141292
self.types += 1;
13151293
type_index
13161294
}
@@ -1398,7 +1376,7 @@ impl<'a> CompositionGraphEncoder<'a> {
13981376

13991377
fn import(
14001378
&mut self,
1401-
import_section: &mut ComponentImportSection,
1379+
encoded: &mut Component,
14021380
name: &str,
14031381
url: &str,
14041382
ty: ComponentTypeRef,
@@ -1414,7 +1392,9 @@ impl<'a> CompositionGraphEncoder<'a> {
14141392

14151393
log::debug!("importing {desc} with `{name}` (encoded index {count}) in composed component");
14161394

1395+
let mut import_section = ComponentImportSection::new();
14171396
import_section.import(name, url, ty);
1397+
encoded.section(&import_section);
14181398

14191399
let index = *count;
14201400
*count += 1;

0 commit comments

Comments
 (0)