Skip to content

Commit c6aef47

Browse files
committed
add wasmparser::WasmFeatures support to wasm-compose
Signed-off-by: Joel Dice <[email protected]>
1 parent 015b271 commit c6aef47

File tree

4 files changed

+131
-44
lines changed

4 files changed

+131
-44
lines changed

crates/wasm-compose/src/composer.rs

Lines changed: 46 additions & 20 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, WasmFeatures,
1818
};
1919

2020
/// The root component name used in configuration.
@@ -72,9 +72,13 @@ struct CompositionGraphBuilder<'a> {
7272
}
7373

7474
impl<'a> CompositionGraphBuilder<'a> {
75-
fn new(root_path: &Path, config: &'a Config) -> Result<Self> {
75+
fn new(root_path: &Path, config: &'a Config, features: WasmFeatures) -> Result<Self> {
7676
let mut graph = CompositionGraph::new();
77-
graph.add_component(Component::from_file(ROOT_COMPONENT_NAME, root_path)?)?;
77+
graph.add_component(Component::from_file(
78+
ROOT_COMPONENT_NAME,
79+
root_path,
80+
features,
81+
)?)?;
7882

7983
let definitions = config
8084
.definitions
@@ -87,7 +91,7 @@ impl<'a> CompositionGraphBuilder<'a> {
8791
)
8892
})?;
8993

90-
let component = Component::from_file(name, config.dir.join(path))?;
94+
let component = Component::from_file(name, config.dir.join(path), features)?;
9195

9296
Ok((graph.add_component(component)?, None))
9397
})
@@ -105,19 +109,19 @@ impl<'a> CompositionGraphBuilder<'a> {
105109
///
106110
/// If a component with the given name already exists, its id is returned.
107111
/// Returns `Ok(None)` if a matching component cannot be found.
108-
fn add_component(&mut self, name: &str) -> Result<Option<ComponentId>> {
112+
fn add_component(&mut self, name: &str, features: WasmFeatures) -> Result<Option<ComponentId>> {
109113
if let Some((id, _)) = self.graph.get_component_by_name(name) {
110114
return Ok(Some(id));
111115
}
112116

113-
match self.find_component(name)? {
117+
match self.find_component(name, features)? {
114118
Some(component) => Ok(Some(self.graph.add_component(component)?)),
115119
None => Ok(None),
116120
}
117121
}
118122

119123
/// Finds the component with the given name on disk.
120-
fn find_component(&self, name: &str) -> Result<Option<Component<'a>>> {
124+
fn find_component(&self, name: &str, features: WasmFeatures) -> Result<Option<Component<'a>>> {
121125
// Check the config for an explicit path (must be a valid component)
122126
if let Some(dep) = self.config.dependencies.get(name) {
123127
log::debug!(
@@ -127,13 +131,14 @@ impl<'a> CompositionGraphBuilder<'a> {
127131
return Ok(Some(Component::from_file(
128132
name,
129133
self.config.dir.join(&dep.path),
134+
features,
130135
)?));
131136
}
132137

133138
// Otherwise, search the paths for a valid component with the same name
134139
log::info!("searching for a component with name `{name}`");
135140
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)? {
141+
if let Some(component) = Self::parse_component(dir, name, features)? {
137142
return Ok(Some(component));
138143
}
139144
}
@@ -144,7 +149,11 @@ impl<'a> CompositionGraphBuilder<'a> {
144149
/// Parses a component from the given directory, if it exists.
145150
///
146151
/// Returns `Ok(None)` if the component does not exist.
147-
fn parse_component(dir: &Path, name: &str) -> Result<Option<Component<'a>>> {
152+
fn parse_component(
153+
dir: &Path,
154+
name: &str,
155+
features: WasmFeatures,
156+
) -> Result<Option<Component<'a>>> {
148157
let mut path = dir.join(name);
149158

150159
for ext in ["wasm", "wat"] {
@@ -154,7 +163,7 @@ impl<'a> CompositionGraphBuilder<'a> {
154163
continue;
155164
}
156165

157-
return Ok(Some(Component::from_file(name, &path)?));
166+
return Ok(Some(Component::from_file(name, &path, features)?));
158167
}
159168

160169
Ok(None)
@@ -165,12 +174,17 @@ impl<'a> CompositionGraphBuilder<'a> {
165174
/// Returns an index into `instances` for the instance being instantiated.
166175
///
167176
/// Returns `Ok(None)` if a component to instantiate cannot be found.
168-
fn instantiate(&mut self, name: &str, component_name: &str) -> Result<Option<(usize, bool)>> {
177+
fn instantiate(
178+
&mut self,
179+
name: &str,
180+
component_name: &str,
181+
features: WasmFeatures,
182+
) -> Result<Option<(usize, bool)>> {
169183
if let Some(index) = self.instances.get_index_of(name) {
170184
return Ok(Some((index, true)));
171185
}
172186

173-
match self.add_component(component_name)? {
187+
match self.add_component(component_name, features)? {
174188
Some(component_id) => {
175189
let (index, prev) = self
176190
.instances
@@ -301,13 +315,18 @@ impl<'a> CompositionGraphBuilder<'a> {
301315
/// Processes a dependency in the graph.
302316
///
303317
/// Returns `Ok(Some(index))` if the dependency resulted in a new dependency instance being created.
304-
fn process_dependency(&mut self, dependency: Dependency) -> Result<Option<usize>> {
318+
fn process_dependency(
319+
&mut self,
320+
dependency: Dependency,
321+
features: WasmFeatures,
322+
) -> Result<Option<usize>> {
305323
match dependency.kind {
306324
DependencyKind::Instance { instance, export } => self.process_instance_dependency(
307325
dependency.dependent,
308326
dependency.import,
309327
&instance,
310328
export.as_deref(),
329+
features,
311330
),
312331
DependencyKind::Definition { index, export } => {
313332
// The dependency is on a definition component, so we simply connect the dependent to the definition's export
@@ -348,6 +367,7 @@ impl<'a> CompositionGraphBuilder<'a> {
348367
import: InstanceImportRef,
349368
instance: &str,
350369
export: Option<&str>,
370+
features: WasmFeatures,
351371
) -> Result<Option<usize>> {
352372
let name = self.config.dependency_name(instance);
353373

@@ -356,7 +376,7 @@ impl<'a> CompositionGraphBuilder<'a> {
356376
dependent_name = self.instances.get_index(dependent_index).unwrap().0,
357377
);
358378

359-
match self.instantiate(instance, name)? {
379+
match self.instantiate(instance, name, features)? {
360380
Some((instance, existing)) => {
361381
let (dependent, import_name, import_type) = self.resolve_import_ref(import);
362382

@@ -478,12 +498,12 @@ impl<'a> CompositionGraphBuilder<'a> {
478498
}
479499

480500
/// Build the instantiation graph.
481-
fn build(mut self) -> Result<(InstanceId, CompositionGraph<'a>)> {
501+
fn build(mut self, features: WasmFeatures) -> Result<(InstanceId, CompositionGraph<'a>)> {
482502
let mut queue: VecDeque<Dependency> = VecDeque::new();
483503

484504
// Instantiate the root and push its dependencies to the queue
485505
let (root_instance, existing) = self
486-
.instantiate(ROOT_COMPONENT_NAME, ROOT_COMPONENT_NAME)?
506+
.instantiate(ROOT_COMPONENT_NAME, ROOT_COMPONENT_NAME, features)?
487507
.unwrap();
488508

489509
assert!(!existing);
@@ -492,7 +512,7 @@ impl<'a> CompositionGraphBuilder<'a> {
492512

493513
// Process all remaining dependencies in the queue
494514
while let Some(dependency) = queue.pop_front() {
495-
if let Some(instance) = self.process_dependency(dependency)? {
515+
if let Some(instance) = self.process_dependency(dependency, features)? {
496516
self.push_dependencies(instance, &mut queue)?;
497517
}
498518
}
@@ -511,6 +531,7 @@ impl<'a> CompositionGraphBuilder<'a> {
511531
pub struct ComponentComposer<'a> {
512532
component: &'a Path,
513533
config: &'a Config,
534+
features: WasmFeatures,
514535
}
515536

516537
impl<'a> ComponentComposer<'a> {
@@ -519,8 +540,12 @@ impl<'a> ComponentComposer<'a> {
519540
/// ## Arguments
520541
/// * `component` - The path to the component to compose.
521542
/// * `config` - The configuration to use for the composition.
522-
pub fn new(component: &'a Path, config: &'a Config) -> Self {
523-
Self { component, config }
543+
pub fn new(component: &'a Path, config: &'a Config, features: WasmFeatures) -> Self {
544+
Self {
545+
component,
546+
config,
547+
features,
548+
}
524549
}
525550

526551
/// Composes a WebAssembly component based on the composer's configuration.
@@ -529,7 +554,8 @@ impl<'a> ComponentComposer<'a> {
529554
/// Returns the bytes of the composed component.
530555
pub fn compose(&self) -> Result<Vec<u8>> {
531556
let (root_instance, graph) =
532-
CompositionGraphBuilder::new(self.component, self.config)?.build()?;
557+
CompositionGraphBuilder::new(self.component, self.config, self.features)?
558+
.build(self.features)?;
533559

534560
// If only the root component was instantiated, then there are no resolved dependencies
535561
if graph.instances.len() == 1 {

0 commit comments

Comments
 (0)