@@ -235,29 +235,45 @@ pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType {
235235 }
236236}
237237
238- pub ( crate ) fn process_const_operators ( ops : OperatorsReader < ' _ > ) -> Result < ConstInstruction > {
238+ pub ( crate ) fn process_const_operators ( ops : OperatorsReader < ' _ > ) -> Result < Box < [ ConstInstruction ] > > {
239239 let ops = ops. into_iter ( ) . collect :: < wasmparser:: Result < Vec < _ > > > ( ) ?;
240240 // In practice, the len can never be something other than 2,
241241 // but we'll keep this here since it's part of the spec
242242 // Invalid modules will be rejected by the validator anyway (there are also tests for this in the testsuite)
243243 assert ! ( ops. len( ) >= 2 ) ;
244244 assert ! ( matches!( ops[ ops. len( ) - 1 ] , wasmparser:: Operator :: End ) ) ;
245245
246- match & ops[ ops. len ( ) - 2 ] {
247- wasmparser:: Operator :: RefNull { hty } => match convert_heaptype ( * hty) {
248- ValType :: RefFunc => Ok ( ConstInstruction :: RefFunc ( None ) ) ,
249- ValType :: RefExtern => Ok ( ConstInstruction :: RefExtern ( None ) ) ,
250- _ => unimplemented ! ( "Unsupported heap type: {:?}" , hty) ,
251- } ,
252- wasmparser:: Operator :: RefFunc { function_index } => Ok ( ConstInstruction :: RefFunc ( Some ( * function_index) ) ) ,
253- wasmparser:: Operator :: I32Const { value } => Ok ( ConstInstruction :: I32Const ( * value) ) ,
254- wasmparser:: Operator :: I64Const { value } => Ok ( ConstInstruction :: I64Const ( * value) ) ,
255- wasmparser:: Operator :: F32Const { value } => Ok ( ConstInstruction :: F32Const ( f32:: from_bits ( value. bits ( ) ) ) ) ,
256- wasmparser:: Operator :: F64Const { value } => Ok ( ConstInstruction :: F64Const ( f64:: from_bits ( value. bits ( ) ) ) ) ,
257- wasmparser:: Operator :: V128Const { value } => Ok ( ConstInstruction :: V128Const ( value. i128 ( ) ) ) ,
258- wasmparser:: Operator :: GlobalGet { global_index } => Ok ( ConstInstruction :: GlobalGet ( * global_index) ) ,
259- op => Err ( crate :: ParseError :: UnsupportedOperator ( format ! ( "Unsupported const instruction: {op:?}" ) ) ) ,
246+ let mut out = Vec :: with_capacity ( ops. len ( ) . saturating_sub ( 1 ) ) ;
247+ for op in ops. iter ( ) . take ( ops. len ( ) - 1 ) {
248+ let instr = match op {
249+ wasmparser:: Operator :: RefNull { hty } => match convert_heaptype ( * hty) {
250+ ValType :: RefFunc => ConstInstruction :: RefFunc ( None ) ,
251+ ValType :: RefExtern => ConstInstruction :: RefExtern ( None ) ,
252+ _ => unimplemented ! ( "Unsupported heap type: {:?}" , hty) ,
253+ } ,
254+ wasmparser:: Operator :: RefFunc { function_index } => ConstInstruction :: RefFunc ( Some ( * function_index) ) ,
255+ wasmparser:: Operator :: I32Const { value } => ConstInstruction :: I32Const ( * value) ,
256+ wasmparser:: Operator :: I64Const { value } => ConstInstruction :: I64Const ( * value) ,
257+ wasmparser:: Operator :: F32Const { value } => ConstInstruction :: F32Const ( f32:: from_bits ( value. bits ( ) ) ) ,
258+ wasmparser:: Operator :: F64Const { value } => ConstInstruction :: F64Const ( f64:: from_bits ( value. bits ( ) ) ) ,
259+ wasmparser:: Operator :: V128Const { value } => ConstInstruction :: V128Const ( value. i128 ( ) ) ,
260+ wasmparser:: Operator :: GlobalGet { global_index } => ConstInstruction :: GlobalGet ( * global_index) ,
261+ wasmparser:: Operator :: I32Add => ConstInstruction :: I32Add ,
262+ wasmparser:: Operator :: I32Sub => ConstInstruction :: I32Sub ,
263+ wasmparser:: Operator :: I32Mul => ConstInstruction :: I32Mul ,
264+ wasmparser:: Operator :: I64Add => ConstInstruction :: I64Add ,
265+ wasmparser:: Operator :: I64Sub => ConstInstruction :: I64Sub ,
266+ wasmparser:: Operator :: I64Mul => ConstInstruction :: I64Mul ,
267+ other => {
268+ return Err ( crate :: ParseError :: UnsupportedOperator ( format ! (
269+ "Unsupported const instruction: {other:?}"
270+ ) ) ) ;
271+ }
272+ } ;
273+ out. push ( instr) ;
260274 }
275+
276+ Ok ( out. into_boxed_slice ( ) )
261277}
262278
263279pub ( crate ) fn convert_heaptype ( heap : wasmparser:: HeapType ) -> ValType {
0 commit comments