Skip to content

Commit b6fdcc8

Browse files
authored
Use a single type arena for all of wasm-compose (#2169)
This commit updates parsing of components in `wasm-compose` to use the same `Validator` for all components to ensure that type information is deduplicated. This will also become an API contract required in the upcoming component-model/GC work so this is future-proofing against that change as well.
1 parent 725ae03 commit b6fdcc8

File tree

4 files changed

+138
-27
lines changed

4 files changed

+138
-27
lines changed

crates/wasm-compose/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ serde_yaml = "0.9.22"
2727
smallvec = "1.10.0"
2828
wasm-encoder = { workspace = true, features = ['std', 'wasmparser', 'component-model'] }
2929
wasmparser = { workspace = true, features = ['std', 'validate', 'component-model', 'features'] }
30-
wat = { workspace = true }
30+
wat = { workspace = true, features = ['component-model'] }
3131

3232
[dev-dependencies]
3333
glob = "0.3.0"
3434
pretty_assertions = "1.2.1"
35-
wasmprinter = { workspace = true }
35+
wasmprinter = { workspace = true, features = ['component-model'] }
3636
wit-component = { workspace = true }

crates/wasm-compose/src/composer.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{collections::VecDeque, ffi::OsStr, path::Path};
1414
use wasmparser::{
1515
component_types::{ComponentEntityType, ComponentInstanceTypeId},
1616
types::TypesRef,
17-
ComponentExternalKind, ComponentTypeRef,
17+
ComponentExternalKind, ComponentTypeRef, Validator, WasmFeatures,
1818
};
1919

2020
/// The root component name used in configuration.
@@ -69,12 +69,19 @@ struct CompositionGraphBuilder<'a> {
6969
instances: IndexMap<String, InstanceId>,
7070
/// The definition components in the graph.
7171
definitions: Vec<(ComponentId, Option<InstanceId>)>,
72+
/// Wasm validator and shared type arenas.
73+
validator: Validator,
7274
}
7375

7476
impl<'a> CompositionGraphBuilder<'a> {
7577
fn new(root_path: &Path, config: &'a Config) -> Result<Self> {
7678
let mut graph = CompositionGraph::new();
77-
graph.add_component(Component::from_file(ROOT_COMPONENT_NAME, root_path)?)?;
79+
let mut validator = Validator::new_with_features(WasmFeatures::all());
80+
graph.add_component(Component::from_file(
81+
&mut validator,
82+
ROOT_COMPONENT_NAME,
83+
root_path,
84+
)?)?;
7885

7986
let definitions = config
8087
.definitions
@@ -87,7 +94,7 @@ impl<'a> CompositionGraphBuilder<'a> {
8794
)
8895
})?;
8996

90-
let component = Component::from_file(name, config.dir.join(path))?;
97+
let component = Component::from_file(&mut validator, name, config.dir.join(path))?;
9198

9299
Ok((graph.add_component(component)?, None))
93100
})
@@ -98,6 +105,7 @@ impl<'a> CompositionGraphBuilder<'a> {
98105
graph,
99106
instances: Default::default(),
100107
definitions,
108+
validator,
101109
})
102110
}
103111

@@ -117,14 +125,15 @@ impl<'a> CompositionGraphBuilder<'a> {
117125
}
118126

119127
/// Finds the component with the given name on disk.
120-
fn find_component(&self, name: &str) -> Result<Option<Component<'a>>> {
128+
fn find_component(&mut self, name: &str) -> Result<Option<Component<'a>>> {
121129
// Check the config for an explicit path (must be a valid component)
122130
if let Some(dep) = self.config.dependencies.get(name) {
123131
log::debug!(
124132
"component with name `{name}` has an explicit path of `{path}`",
125133
path = dep.path.display()
126134
);
127135
return Ok(Some(Component::from_file(
136+
&mut self.validator,
128137
name,
129138
self.config.dir.join(&dep.path),
130139
)?));
@@ -133,7 +142,7 @@ impl<'a> CompositionGraphBuilder<'a> {
133142
// Otherwise, search the paths for a valid component with the same name
134143
log::info!("searching for a component with name `{name}`");
135144
for dir in std::iter::once(&self.config.dir).chain(self.config.search_paths.iter()) {
136-
if let Some(component) = Self::parse_component(dir, name)? {
145+
if let Some(component) = Self::parse_component(&mut self.validator, dir, name)? {
137146
return Ok(Some(component));
138147
}
139148
}
@@ -144,7 +153,11 @@ impl<'a> CompositionGraphBuilder<'a> {
144153
/// Parses a component from the given directory, if it exists.
145154
///
146155
/// Returns `Ok(None)` if the component does not exist.
147-
fn parse_component(dir: &Path, name: &str) -> Result<Option<Component<'a>>> {
156+
fn parse_component(
157+
validator: &mut Validator,
158+
dir: &Path,
159+
name: &str,
160+
) -> Result<Option<Component<'a>>> {
148161
let mut path = dir.join(name);
149162

150163
for ext in ["wasm", "wat"] {
@@ -154,7 +167,7 @@ impl<'a> CompositionGraphBuilder<'a> {
154167
continue;
155168
}
156169

157-
return Ok(Some(Component::from_file(name, &path)?));
170+
return Ok(Some(Component::from_file(validator, name, &path)?));
158171
}
159172

160173
Ok(None)

0 commit comments

Comments
 (0)