@@ -10,6 +10,7 @@ struct ValidateThenVisit<'a, T, U>(T, &'a mut U);
1010macro_rules! validate_then_visit {
1111 ( $( @$proposal: ident $op: ident $( { $( $arg: ident: $argty: ty) ,* } ) ? => $visit: ident) * ) => {
1212 $(
13+ #[ inline]
1314 fn $visit( & mut self $( $( , $arg: $argty) * ) ?) -> Self :: Output {
1415 self . 0. $visit( $( $( $arg. clone( ) ) ,* ) ?) ?;
1516 Ok ( self . 1. $visit( $( $( $arg) ,* ) ?) )
@@ -24,23 +25,29 @@ where
2425 U : VisitOperator < ' a > ,
2526{
2627 type Output = Result < U :: Output > ;
27-
2828 wasmparser:: for_each_operator!( validate_then_visit) ;
2929}
3030
3131pub ( crate ) fn process_operators < R : WasmModuleResources > (
32- validator : & mut FuncValidator < R > ,
32+ validator : Option < & mut FuncValidator < R > > ,
3333 body : & FunctionBody < ' _ > ,
3434) -> Result < Box < [ Instruction ] > > {
3535 let mut reader = body. get_operators_reader ( ) ?;
36- let mut builder = FunctionBuilder :: new ( 1024 ) ;
36+ let remaining = reader. get_binary_reader ( ) . bytes_remaining ( ) ;
37+ let mut builder = FunctionBuilder :: new ( remaining) ;
3738
38- while !reader. eof ( ) {
39- let validate = validator. visitor ( reader. original_position ( ) ) ;
40- reader. visit_operator ( & mut ValidateThenVisit ( validate, & mut builder) ) ???;
39+ if let Some ( validator) = validator {
40+ while !reader. eof ( ) {
41+ let validate = validator. visitor ( reader. original_position ( ) ) ;
42+ reader. visit_operator ( & mut ValidateThenVisit ( validate, & mut builder) ) ???;
43+ }
44+ validator. finish ( reader. original_position ( ) ) ?;
45+ } else {
46+ while !reader. eof ( ) {
47+ reader. visit_operator ( & mut builder) ??;
48+ }
4149 }
4250
43- validator. finish ( reader. original_position ( ) ) ?;
4451 Ok ( builder. instructions . into_boxed_slice ( ) )
4552}
4653
@@ -114,7 +121,7 @@ pub(crate) struct FunctionBuilder {
114121
115122impl FunctionBuilder {
116123 pub ( crate ) fn new ( instr_capacity : usize ) -> Self {
117- Self { instructions : Vec :: with_capacity ( instr_capacity) , label_ptrs : Vec :: with_capacity ( 64 ) }
124+ Self { instructions : Vec :: with_capacity ( instr_capacity) , label_ptrs : Vec :: with_capacity ( 128 ) }
118125 }
119126
120127 #[ cold]
@@ -124,7 +131,8 @@ impl FunctionBuilder {
124131
125132 #[ inline]
126133 fn visit ( & mut self , op : Instruction ) -> Result < ( ) > {
127- Ok ( self . instructions . push ( op) )
134+ self . instructions . push ( op) ;
135+ Ok ( ( ) )
128136 }
129137}
130138
@@ -337,6 +345,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
337345 self . visit ( Instruction :: Else ( 0 ) )
338346 }
339347
348+ #[ inline]
340349 fn visit_end ( & mut self ) -> Self :: Output {
341350 let Some ( label_pointer) = self . label_ptrs . pop ( ) else {
342351 return self . visit ( Instruction :: EndFunc ) ;
@@ -348,16 +357,19 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
348357 Instruction :: Else ( ref mut else_instr_end_offset) => {
349358 * else_instr_end_offset = current_instr_ptr - label_pointer;
350359
360+ #[ cold]
361+ fn error ( ) -> crate :: ParseError {
362+ crate :: ParseError :: UnsupportedOperator (
363+ "Expected to end an if block, but the last label was not an if" . to_string ( ) ,
364+ )
365+ }
366+
351367 // since we're ending an else block, we need to end the if block as well
352- let if_label_pointer = self . label_ptrs . pop ( ) . ok_or ( crate :: ParseError :: UnsupportedOperator (
353- "Expected to end an if block, but the last label was not an if" . to_string ( ) ,
354- ) ) ?;
368+ let if_label_pointer = self . label_ptrs . pop ( ) . ok_or_else ( error) ?;
355369
356370 let if_instruction = & mut self . instructions [ if_label_pointer] ;
357371 let Instruction :: If ( _, ref mut else_offset, ref mut end_offset) = if_instruction else {
358- return Err ( crate :: ParseError :: UnsupportedOperator (
359- "Expected to end an if block, but the last label was not an if" . to_string ( ) ,
360- ) ) ;
372+ return Err ( error ( ) ) ;
361373 } ;
362374
363375 * else_offset = Some ( label_pointer - if_label_pointer) ;
@@ -386,8 +398,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
386398 . collect :: < Result < Vec < Instruction > , wasmparser:: BinaryReaderError > > ( )
387399 . expect ( "BrTable targets are invalid, this should have been caught by the validator" ) ;
388400
389- self . instructions
390- . extend ( IntoIterator :: into_iter ( [ Instruction :: BrTable ( def, instrs. len ( ) ) ] ) . chain ( instrs. into_iter ( ) ) ) ;
401+ self . instructions . extend ( IntoIterator :: into_iter ( [ Instruction :: BrTable ( def, instrs. len ( ) ) ] ) . chain ( instrs) ) ;
391402 Ok ( ( ) )
392403 }
393404
0 commit comments