@@ -14,7 +14,7 @@ use std::{collections::VecDeque, ffi::OsStr, path::Path};
1414use 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
7474impl < ' 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> {
511531pub struct ComponentComposer < ' a > {
512532 component : & ' a Path ,
513533 config : & ' a Config ,
534+ features : WasmFeatures ,
514535}
515536
516537impl < ' 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