1- use crate :: { conversion :: convert_blocktype , Result } ;
1+ use crate :: Result ;
22
3- use crate :: conversion:: convert_heaptype;
3+ use crate :: conversion:: { convert_heaptype, convert_valtype } ;
44use alloc:: string:: ToString ;
55use alloc:: { boxed:: Box , vec:: Vec } ;
66use tinywasm_types:: { Instruction , MemoryArg } ;
@@ -357,7 +357,13 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
357357 }
358358
359359 fn visit_local_get ( & mut self , idx : u32 ) -> Self :: Output {
360- let resolved_idx = self . local_addr_map [ idx as usize ] ;
360+ let Ok ( resolved_idx) = self . local_addr_map [ idx as usize ] . try_into ( ) else {
361+ self . errors . push ( crate :: ParseError :: UnsupportedOperator (
362+ "Local index is too large, tinywasm does not support local indexes that large" . to_string ( ) ,
363+ ) ) ;
364+ return ;
365+ } ;
366+
361367 match self . validator . get_local_type ( idx) {
362368 Some ( t) => self . instructions . push ( match t {
363369 wasmparser:: ValType :: I32 => Instruction :: LocalGet32 ( resolved_idx) ,
@@ -372,7 +378,13 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
372378 }
373379
374380 fn visit_local_set ( & mut self , idx : u32 ) -> Self :: Output {
375- let resolved_idx = self . local_addr_map [ idx as usize ] ;
381+ let Ok ( resolved_idx) = self . local_addr_map [ idx as usize ] . try_into ( ) else {
382+ self . errors . push ( crate :: ParseError :: UnsupportedOperator (
383+ "Local index is too large, tinywasm does not support local indexes that large" . to_string ( ) ,
384+ ) ) ;
385+ return ;
386+ } ;
387+
376388 match self . validator . get_operand_type ( 0 ) {
377389 Some ( Some ( t) ) => self . instructions . push ( match t {
378390 wasmparser:: ValType :: I32 => Instruction :: LocalSet32 ( resolved_idx) ,
@@ -387,7 +399,13 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
387399 }
388400
389401 fn visit_local_tee ( & mut self , idx : u32 ) -> Self :: Output {
390- let resolved_idx = self . local_addr_map [ idx as usize ] ;
402+ let Ok ( resolved_idx) = self . local_addr_map [ idx as usize ] . try_into ( ) else {
403+ self . errors . push ( crate :: ParseError :: UnsupportedOperator (
404+ "Local index is too large, tinywasm does not support local indexes that large" . to_string ( ) ,
405+ ) ) ;
406+ return ;
407+ } ;
408+
391409 match self . validator . get_operand_type ( 0 ) {
392410 Some ( Some ( t) ) => self . instructions . push ( match t {
393411 wasmparser:: ValType :: I32 => Instruction :: LocalTee32 ( resolved_idx) ,
@@ -411,17 +429,29 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
411429
412430 fn visit_block ( & mut self , blockty : wasmparser:: BlockType ) -> Self :: Output {
413431 self . label_ptrs . push ( self . instructions . len ( ) ) ;
414- self . instructions . push ( Instruction :: Block ( convert_blocktype ( blockty) , 0 ) )
432+ self . instructions . push ( match blockty {
433+ wasmparser:: BlockType :: Empty => Instruction :: Block ( 0 ) ,
434+ wasmparser:: BlockType :: FuncType ( idx) => Instruction :: BlockWithFuncType ( idx, 0 ) ,
435+ wasmparser:: BlockType :: Type ( ty) => Instruction :: BlockWithType ( convert_valtype ( & ty) , 0 ) ,
436+ } )
415437 }
416438
417439 fn visit_loop ( & mut self , ty : wasmparser:: BlockType ) -> Self :: Output {
418440 self . label_ptrs . push ( self . instructions . len ( ) ) ;
419- self . instructions . push ( Instruction :: Loop ( convert_blocktype ( ty) , 0 ) )
441+ self . instructions . push ( match ty {
442+ wasmparser:: BlockType :: Empty => Instruction :: Loop ( 0 ) ,
443+ wasmparser:: BlockType :: FuncType ( idx) => Instruction :: LoopWithFuncType ( idx, 0 ) ,
444+ wasmparser:: BlockType :: Type ( ty) => Instruction :: LoopWithType ( convert_valtype ( & ty) , 0 ) ,
445+ } )
420446 }
421447
422448 fn visit_if ( & mut self , ty : wasmparser:: BlockType ) -> Self :: Output {
423449 self . label_ptrs . push ( self . instructions . len ( ) ) ;
424- self . instructions . push ( Instruction :: If ( convert_blocktype ( ty) . into ( ) , 0 , 0 ) )
450+ self . instructions . push ( match ty {
451+ wasmparser:: BlockType :: Empty => Instruction :: If ( 0 , 0 ) ,
452+ wasmparser:: BlockType :: FuncType ( idx) => Instruction :: IfWithFuncType ( idx, 0 , 0 ) ,
453+ wasmparser:: BlockType :: Type ( ty) => Instruction :: IfWithType ( convert_valtype ( & ty) , 0 , 0 ) ,
454+ } )
425455 }
426456
427457 fn visit_else ( & mut self ) -> Self :: Output {
@@ -451,12 +481,18 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
451481 } ;
452482
453483 let if_instruction = & mut self . instructions [ if_label_pointer] ;
454- let Instruction :: If ( _, else_offset, end_offset) = if_instruction else {
455- self . errors . push ( crate :: ParseError :: UnsupportedOperator (
456- "Expected to end an if block, but the last label was not an if" . to_string ( ) ,
457- ) ) ;
458484
459- return ;
485+ let ( else_offset, end_offset) = match if_instruction {
486+ Instruction :: If ( else_offset, end_offset)
487+ | Instruction :: IfWithFuncType ( _, else_offset, end_offset)
488+ | Instruction :: IfWithType ( _, else_offset, end_offset) => ( else_offset, end_offset) ,
489+ _ => {
490+ self . errors . push ( crate :: ParseError :: UnsupportedOperator (
491+ "Expected to end an if block, but the last label was not an if" . to_string ( ) ,
492+ ) ) ;
493+
494+ return ;
495+ }
460496 } ;
461497
462498 * else_offset = ( label_pointer - if_label_pointer)
@@ -467,9 +503,15 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
467503 . try_into ( )
468504 . expect ( "else_instr_end_offset is too large, tinywasm does not support blocks that large" ) ;
469505 }
470- Some ( Instruction :: Block ( _, end_offset) )
471- | Some ( Instruction :: Loop ( _, end_offset) )
472- | Some ( Instruction :: If ( _, _, end_offset) ) => {
506+ Some ( Instruction :: Block ( end_offset) )
507+ | Some ( Instruction :: BlockWithType ( _, end_offset) )
508+ | Some ( Instruction :: BlockWithFuncType ( _, end_offset) )
509+ | Some ( Instruction :: Loop ( end_offset) )
510+ | Some ( Instruction :: LoopWithFuncType ( _, end_offset) )
511+ | Some ( Instruction :: LoopWithType ( _, end_offset) )
512+ | Some ( Instruction :: If ( _, end_offset) )
513+ | Some ( Instruction :: IfWithFuncType ( _, _, end_offset) )
514+ | Some ( Instruction :: IfWithType ( _, _, end_offset) ) => {
473515 * end_offset = ( current_instr_ptr - label_pointer)
474516 . try_into ( )
475517 . expect ( "else_instr_end_offset is too large, tinywasm does not support blocks that large" ) ;
0 commit comments