@@ -13,29 +13,45 @@ use wasmparser::{
1313/// parsing phase which in theory could be lifted in the future but serve as
1414/// simplifying assumptions for now:
1515///
16- /// * Nested components are not supported.
16+ /// * Nested components with modules are not supported.
1717/// * Imported modules or components are not supported.
1818/// * Instantiating a module twice is not supported.
1919/// * Component-level start functions are not supported.
2020///
2121/// Some of these restrictions are likely to be loosened over time, however.
2222pub ( crate ) fn parse < ' a > ( full_wasm : & ' a [ u8 ] ) -> anyhow:: Result < ComponentContext < ' a > > {
2323 let mut component = ComponentContext :: default ( ) ;
24- let mut parser = Parser :: new ( 0 ) . parse_all ( full_wasm) ;
24+ let parser = Parser :: new ( 0 ) . parse_all ( full_wasm) ;
25+ parse_into ( Some ( & mut component) , full_wasm, parser) ?;
26+ Ok ( component)
27+ }
2528
26- while let Some ( payload) = parser. next ( ) {
29+ fn parse_into < ' a > (
30+ mut cx : Option < & mut ComponentContext < ' a > > ,
31+ full_wasm : & ' a [ u8 ] ,
32+ mut iter : impl Iterator < Item = wasmparser:: Result < Payload < ' a > > > ,
33+ ) -> anyhow:: Result < ( ) > {
34+ let mut stack = Vec :: new ( ) ;
35+ while let Some ( payload) = iter. next ( ) {
2736 let payload = payload?;
2837
2938 match & payload {
3039 // Module sections get parsed with wizer's core wasm support.
31- Payload :: ModuleSection { .. } => {
32- let info = crate :: parse:: parse_with ( & full_wasm, & mut parser) ?;
33- component. push_module_section ( info) ;
34- }
40+ Payload :: ModuleSection { .. } => match & mut cx {
41+ Some ( component) => {
42+ let info = crate :: parse:: parse_with ( & full_wasm, & mut iter) ?;
43+ component. push_module_section ( info) ;
44+ }
45+ None => {
46+ bail ! ( "nested components with modules not currently supported" ) ;
47+ }
48+ } ,
3549
3650 // All other sections get pushed raw as-is into the component.
3751 _ => {
38- if let Some ( ( id, range) ) = payload. as_section ( ) {
52+ if let Some ( ( id, range) ) = payload. as_section ( )
53+ && let Some ( component) = & mut cx
54+ {
3955 component. push_raw_section ( wasm_encoder:: RawSection {
4056 id,
4157 data : & full_wasm[ range] ,
@@ -56,43 +72,61 @@ pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ComponentContext<
5672 }
5773
5874 Payload :: ComponentSection { .. } => {
59- bail ! ( "wizer does not currently support nested components" ) ;
75+ stack . push ( cx . take ( ) ) ;
6076 }
6177
62- Payload :: InstanceSection ( reader) => {
63- for instance in reader {
64- let instance_index = component. inc_core_instances ( ) ;
78+ Payload :: End ( _) => {
79+ if stack. len ( ) > 0 {
80+ cx = stack. pop ( ) . unwrap ( ) ;
81+ }
82+ }
6583
66- if let Instance :: Instantiate { module_index, .. } = instance? {
67- match component. core_instantiations . entry ( module_index) {
68- Entry :: Vacant ( entry) => {
69- entry. insert ( instance_index) ;
84+ Payload :: InstanceSection ( reader) => {
85+ if let Some ( component) = & mut cx {
86+ for instance in reader {
87+ let instance_index = component. inc_core_instances ( ) ;
88+
89+ if let Instance :: Instantiate { module_index, .. } = instance? {
90+ match component. core_instantiations . entry ( module_index) {
91+ Entry :: Vacant ( entry) => {
92+ entry. insert ( instance_index) ;
93+ }
94+ Entry :: Occupied ( _) => {
95+ bail ! ( "modules may be instantiated at most once" )
96+ }
7097 }
71- Entry :: Occupied ( _) => bail ! ( "modules may be instantiated at most once" ) ,
7298 }
7399 }
74100 }
75101 }
76102 Payload :: ComponentInstanceSection ( reader) => {
77- for _ in reader {
78- component. inc_instances ( ) ;
103+ if let Some ( component) = & mut cx {
104+ for _ in reader {
105+ component. inc_instances ( ) ;
106+ }
79107 }
80108 }
81109
82110 Payload :: ComponentAliasSection ( reader) => {
83111 for alias in reader {
84112 match alias? {
85113 ComponentAlias :: CoreInstanceExport { kind, .. } => {
86- component. inc_core ( kind) ;
114+ if let Some ( component) = & mut cx {
115+ component. inc_core ( kind) ;
116+ }
87117 }
88118 ComponentAlias :: InstanceExport { kind, .. } => {
89119 validate_item_kind ( kind, "aliases" ) ?;
90- component. inc ( kind) ;
120+ if let Some ( component) = & mut cx {
121+ component. inc ( kind) ;
122+ }
91123 }
92124 ComponentAlias :: Outer { kind, .. } => match kind {
93125 ComponentOuterAliasKind :: CoreType => { }
94126 ComponentOuterAliasKind :: Type => {
95- component. inc_types ( ) ;
127+ if let Some ( component) = & mut cx {
128+ component. inc_types ( ) ;
129+ }
96130 }
97131 ComponentOuterAliasKind :: CoreModule => {
98132 bail ! ( "wizer does not currently support module aliases" ) ;
@@ -109,10 +143,14 @@ pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ComponentContext<
109143 for function in reader {
110144 match function? {
111145 CanonicalFunction :: Lift { .. } => {
112- component. inc_funcs ( ) ;
146+ if let Some ( component) = & mut cx {
147+ component. inc_funcs ( ) ;
148+ }
113149 }
114150 _ => {
115- component. inc_core_funcs ( ) ;
151+ if let Some ( component) = & mut cx {
152+ component. inc_core_funcs ( ) ;
153+ }
116154 }
117155 }
118156 }
@@ -122,21 +160,27 @@ pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ComponentContext<
122160 for import in reader {
123161 let kind = import?. ty . kind ( ) ;
124162 validate_item_kind ( kind, "imports" ) ?;
125- component. inc ( kind) ;
163+ if let Some ( component) = & mut cx {
164+ component. inc ( kind) ;
165+ }
126166 }
127167 }
128168
129169 Payload :: ComponentExportSection ( reader) => {
130170 for export in reader {
131171 let kind = export?. kind ;
132172 validate_item_kind ( kind, "exports" ) ?;
133- component. inc ( kind) ;
173+ if let Some ( component) = & mut cx {
174+ component. inc ( kind) ;
175+ }
134176 }
135177 }
136178
137179 Payload :: ComponentTypeSection ( reader) => {
138180 for _ in reader {
139- component. inc_types ( ) ;
181+ if let Some ( component) = & mut cx {
182+ component. inc_types ( ) ;
183+ }
140184 }
141185 }
142186
@@ -151,7 +195,7 @@ pub(crate) fn parse<'a>(full_wasm: &'a [u8]) -> anyhow::Result<ComponentContext<
151195 }
152196 }
153197
154- Ok ( component )
198+ Ok ( ( ) )
155199}
156200
157201fn validate_item_kind ( kind : ComponentExternalKind , msg : & str ) -> Result < ( ) > {
0 commit comments