@@ -10,6 +10,7 @@ struct ValidateThenVisit<'a, T, U>(T, &'a mut U);
10
10
macro_rules! validate_then_visit {
11
11
( $( @$proposal: ident $op: ident $( { $( $arg: ident: $argty: ty) ,* } ) ? => $visit: ident) * ) => {
12
12
$(
13
+ #[ inline]
13
14
fn $visit( & mut self $( $( , $arg: $argty) * ) ?) -> Self :: Output {
14
15
self . 0. $visit( $( $( $arg. clone( ) ) ,* ) ?) ?;
15
16
Ok ( self . 1. $visit( $( $( $arg) ,* ) ?) )
@@ -24,23 +25,29 @@ where
24
25
U : VisitOperator < ' a > ,
25
26
{
26
27
type Output = Result < U :: Output > ;
27
-
28
28
wasmparser:: for_each_operator!( validate_then_visit) ;
29
29
}
30
30
31
31
pub ( crate ) fn process_operators < R : WasmModuleResources > (
32
- validator : & mut FuncValidator < R > ,
32
+ validator : Option < & mut FuncValidator < R > > ,
33
33
body : & FunctionBody < ' _ > ,
34
34
) -> Result < Box < [ Instruction ] > > {
35
35
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) ;
37
38
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
+ }
41
49
}
42
50
43
- validator. finish ( reader. original_position ( ) ) ?;
44
51
Ok ( builder. instructions . into_boxed_slice ( ) )
45
52
}
46
53
@@ -114,7 +121,7 @@ pub(crate) struct FunctionBuilder {
114
121
115
122
impl FunctionBuilder {
116
123
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 ) }
118
125
}
119
126
120
127
#[ cold]
@@ -124,7 +131,8 @@ impl FunctionBuilder {
124
131
125
132
#[ inline]
126
133
fn visit ( & mut self , op : Instruction ) -> Result < ( ) > {
127
- Ok ( self . instructions . push ( op) )
134
+ self . instructions . push ( op) ;
135
+ Ok ( ( ) )
128
136
}
129
137
}
130
138
@@ -337,6 +345,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
337
345
self . visit ( Instruction :: Else ( 0 ) )
338
346
}
339
347
348
+ #[ inline]
340
349
fn visit_end ( & mut self ) -> Self :: Output {
341
350
let Some ( label_pointer) = self . label_ptrs . pop ( ) else {
342
351
return self . visit ( Instruction :: EndFunc ) ;
@@ -348,16 +357,19 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
348
357
Instruction :: Else ( ref mut else_instr_end_offset) => {
349
358
* else_instr_end_offset = current_instr_ptr - label_pointer;
350
359
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
+
351
367
// 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) ?;
355
369
356
370
let if_instruction = & mut self . instructions [ if_label_pointer] ;
357
371
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 ( ) ) ;
361
373
} ;
362
374
363
375
* else_offset = Some ( label_pointer - if_label_pointer) ;
@@ -386,8 +398,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder {
386
398
. collect :: < Result < Vec < Instruction > , wasmparser:: BinaryReaderError > > ( )
387
399
. expect ( "BrTable targets are invalid, this should have been caught by the validator" ) ;
388
400
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) ) ;
391
402
Ok ( ( ) )
392
403
}
393
404
0 commit comments