@@ -256,9 +256,8 @@ impl Encoder<'_> {
256256
257257 if !list. is_empty ( ) {
258258 let mut branch_hints = wasm_encoder:: BranchHints :: new ( ) ;
259- let mut code_section = Vec :: new ( ) ;
259+ let mut code_section = wasm_encoder :: CodeSection :: new ( ) ;
260260
261- list. len ( ) . encode ( & mut code_section) ;
262261 for func in list. iter ( ) {
263262 let hints = func. encode ( & mut code_section, dwarf. as_deref_mut ( ) ) ;
264263 if !hints. is_empty ( ) {
@@ -274,13 +273,10 @@ impl Encoder<'_> {
274273 }
275274
276275 // Finally, insert the Code section from the tmp buffer
277- self . wasm . section ( & wasm_encoder:: RawSection {
278- id : wasm_encoder:: SectionId :: Code as u8 ,
279- data : & code_section,
280- } ) ;
276+ self . wasm . section ( & code_section) ;
281277
282278 if let Some ( dwarf) = & mut dwarf {
283- dwarf. set_code_section_size ( code_section. len ( ) ) ;
279+ dwarf. set_code_section_size ( code_section. byte_len ( ) ) ;
284280 }
285281 }
286282 self . custom_sections ( CustomPlace :: After ( CustomPlaceAnchor :: Code ) ) ;
@@ -449,90 +445,13 @@ impl Encode for Option<Id<'_>> {
449445
450446impl < ' a > Encode for ValType < ' a > {
451447 fn encode ( & self , e : & mut Vec < u8 > ) {
452- match self {
453- ValType :: I32 => e. push ( 0x7f ) ,
454- ValType :: I64 => e. push ( 0x7e ) ,
455- ValType :: F32 => e. push ( 0x7d ) ,
456- ValType :: F64 => e. push ( 0x7c ) ,
457- ValType :: V128 => e. push ( 0x7b ) ,
458- ValType :: Ref ( ty) => {
459- ty. encode ( e) ;
460- }
461- }
448+ wasm_encoder:: Encode :: encode ( & wasm_encoder:: ValType :: from ( * self ) , e)
462449 }
463450}
464451
465452impl < ' a > Encode for HeapType < ' a > {
466453 fn encode ( & self , e : & mut Vec < u8 > ) {
467- match self {
468- HeapType :: Abstract { shared, ty } => {
469- if * shared {
470- e. push ( 0x65 ) ;
471- }
472- ty. encode ( e)
473- }
474- // Note that this is encoded as a signed leb128 so be sure to cast
475- // to an i64 first
476- HeapType :: Concrete ( Index :: Num ( n, _) ) => i64:: from ( * n) . encode ( e) ,
477- HeapType :: Concrete ( Index :: Id ( n) ) => {
478- panic ! ( "unresolved index in emission: {:?}" , n)
479- }
480- }
481- }
482- }
483-
484- impl < ' a > Encode for AbstractHeapType {
485- fn encode ( & self , e : & mut Vec < u8 > ) {
486- use AbstractHeapType :: * ;
487- match self {
488- Func => e. push ( 0x70 ) ,
489- Extern => e. push ( 0x6f ) ,
490- Cont => e. push ( 0x68 ) ,
491- Exn => e. push ( 0x69 ) ,
492- Any => e. push ( 0x6e ) ,
493- Eq => e. push ( 0x6d ) ,
494- Struct => e. push ( 0x6b ) ,
495- Array => e. push ( 0x6a ) ,
496- I31 => e. push ( 0x6c ) ,
497- NoFunc => e. push ( 0x73 ) ,
498- NoExtern => e. push ( 0x72 ) ,
499- NoExn => e. push ( 0x74 ) ,
500- NoCont => e. push ( 0x75 ) ,
501- None => e. push ( 0x71 ) ,
502- }
503- }
504- }
505-
506- impl < ' a > Encode for RefType < ' a > {
507- fn encode ( & self , e : & mut Vec < u8 > ) {
508- match self {
509- // Binary abbreviations (i.e., short form), for when the ref is
510- // nullable.
511- RefType {
512- nullable : true ,
513- heap : heap @ HeapType :: Abstract { .. } ,
514- } => {
515- heap. encode ( e) ;
516- }
517-
518- // Generic 'ref null <heaptype>' encoding (i.e., long form).
519- RefType {
520- nullable : true ,
521- heap,
522- } => {
523- e. push ( 0x63 ) ;
524- heap. encode ( e) ;
525- }
526-
527- // Generic 'ref <heaptype>' encoding.
528- RefType {
529- nullable : false ,
530- heap,
531- } => {
532- e. push ( 0x64 ) ;
533- heap. encode ( e) ;
534- }
535- }
454+ wasm_encoder:: Encode :: encode ( & wasm_encoder:: HeapType :: from ( * self ) , e)
536455 }
537456}
538457
@@ -672,7 +591,7 @@ impl SectionItem for Table<'_> {
672591 ty,
673592 init_expr : Some ( init_expr) ,
674593 } => {
675- section. table_with_init ( ty. to_table_type ( ) , & init_expr. to_const_expr ( None ) ) ;
594+ section. table_with_init ( ty. to_table_type ( ) , & init_expr. to_const_expr ( ) ) ;
676595 }
677596 _ => panic ! ( "TableKind should be normal during encoding" ) ,
678597 }
@@ -701,7 +620,7 @@ impl SectionItem for Global<'_> {
701620 fn encode ( & self , section : & mut wasm_encoder:: GlobalSection ) {
702621 assert ! ( self . exports. names. is_empty( ) ) ;
703622 let init = match & self . kind {
704- GlobalKind :: Inline ( expr) => expr. to_const_expr ( None ) ,
623+ GlobalKind :: Inline ( expr) => expr. to_const_expr ( ) ,
705624 _ => panic ! ( "GlobalKind should be inline during encoding" ) ,
706625 } ;
707626 section. global ( self . ty . to_global_type ( ) , & init) ;
@@ -730,14 +649,14 @@ impl SectionItem for Elem<'_> {
730649 }
731650 ElemPayload :: Exprs { exprs, ty } => Elements :: Expressions (
732651 ( * ty) . into ( ) ,
733- Cow :: Owned ( exprs. iter ( ) . map ( |e| e. to_const_expr ( None ) ) . collect ( ) ) ,
652+ Cow :: Owned ( exprs. iter ( ) . map ( |e| e. to_const_expr ( ) ) . collect ( ) ) ,
734653 ) ,
735654 } ;
736655 match & self . kind {
737656 ElemKind :: Active { table, offset } => {
738657 section. active (
739658 table. map ( |t| t. unwrap_u32 ( ) ) ,
740- & offset. to_const_expr ( None ) ,
659+ & offset. to_const_expr ( ) ,
741660 elements,
742661 ) ;
743662 }
@@ -765,7 +684,7 @@ impl SectionItem for Data<'_> {
765684 section. passive ( data) ;
766685 }
767686 DataKind :: Active { memory, offset } => {
768- section. active ( memory. unwrap_u32 ( ) , & offset. to_const_expr ( None ) , data) ;
687+ section. active ( memory. unwrap_u32 ( ) , & offset. to_const_expr ( ) , data) ;
769688 }
770689 }
771690 }
@@ -779,7 +698,7 @@ impl Func<'_> {
779698 /// for each instruction.
780699 fn encode (
781700 & self ,
782- e : & mut Vec < u8 > ,
701+ section : & mut wasm_encoder :: CodeSection ,
783702 mut dwarf : Option < & mut dwarf:: Dwarf > ,
784703 ) -> Vec < wasm_encoder:: BranchHint > {
785704 assert ! ( self . exports. names. is_empty( ) ) ;
@@ -799,55 +718,41 @@ impl Func<'_> {
799718 // Encode the function into a temporary vector because functions are
800719 // prefixed with their length. The temporary vector, when encoded,
801720 // encodes its length first then the body.
802- let mut tmp = Vec :: new ( ) ;
803- locals. encode ( & mut tmp) ;
804- let branch_hints = expr. encode ( & mut tmp, dwarf. as_deref_mut ( ) ) ;
805- tmp. encode ( e) ;
721+ let mut func =
722+ wasm_encoder:: Function :: new_with_locals_types ( locals. iter ( ) . map ( |t| t. ty . into ( ) ) ) ;
723+ let branch_hints = expr. encode ( & mut func, dwarf. as_deref_mut ( ) ) ;
724+ let func_size = func. byte_len ( ) ;
725+ section. function ( & func) ;
806726
807727 if let Some ( dwarf) = & mut dwarf {
808- dwarf. end_func ( tmp . len ( ) , e . len ( ) ) ;
728+ dwarf. end_func ( func_size , section . byte_len ( ) ) ;
809729 }
810730
811731 branch_hints
812732 }
813733}
814734
815- impl Encode for Box < [ Local < ' _ > ] > {
816- fn encode ( & self , e : & mut Vec < u8 > ) {
817- let mut locals_compressed = Vec :: < ( u32 , ValType ) > :: new ( ) ;
818- for local in self . iter ( ) {
819- if let Some ( ( cnt, prev) ) = locals_compressed. last_mut ( ) {
820- if * prev == local. ty {
821- * cnt += 1 ;
822- continue ;
823- }
824- }
825- locals_compressed. push ( ( 1 , local. ty ) ) ;
826- }
827- locals_compressed. encode ( e) ;
828- }
829- }
830-
831735impl Expression < ' _ > {
832736 /// Encodes this expression into `e` and optionally tracks debugging
833737 /// information for each instruction in `dwarf`.
834738 ///
835739 /// Returns all branch hints, if any, found while parsing this function.
836740 fn encode (
837741 & self ,
838- e : & mut Vec < u8 > ,
742+ func : & mut wasm_encoder :: Function ,
839743 mut dwarf : Option < & mut dwarf:: Dwarf > ,
840744 ) -> Vec < wasm_encoder:: BranchHint > {
841745 let mut hints = Vec :: with_capacity ( self . branch_hints . len ( ) ) ;
842746 let mut next_hint = self . branch_hints . iter ( ) . peekable ( ) ;
747+ let mut tmp = Vec :: new ( ) ;
843748
844749 for ( i, instr) in self . instrs . iter ( ) . enumerate ( ) {
845750 // Branch hints are stored in order of increasing `instr_index` so
846751 // check to see if the next branch hint matches this instruction's
847752 // index.
848753 if let Some ( hint) = next_hint. next_if ( |h| h. instr_index == i) {
849754 hints. push ( wasm_encoder:: BranchHint {
850- branch_func_offset : u32:: try_from ( e . len ( ) ) . unwrap ( ) ,
755+ branch_func_offset : u32:: try_from ( func . byte_len ( ) + tmp . len ( ) ) . unwrap ( ) ,
851756 branch_hint_value : hint. value ,
852757 } ) ;
853758 }
@@ -856,22 +761,24 @@ impl Expression<'_> {
856761 // and source location.
857762 if let Some ( dwarf) = & mut dwarf {
858763 if let Some ( span) = self . instr_spans . as_ref ( ) . map ( |s| s[ i] ) {
859- dwarf. instr ( e . len ( ) , span) ;
764+ dwarf. instr ( func . byte_len ( ) + tmp . len ( ) , span) ;
860765 }
861766 }
862767
863768 // Finally emit the instruction and move to the next.
864- instr. encode ( e ) ;
769+ instr. encode ( & mut tmp ) ;
865770 }
866- e. push ( 0x0b ) ;
771+ func. raw ( tmp. iter ( ) . copied ( ) ) ;
772+ func. instruction ( & wasm_encoder:: Instruction :: End ) ;
867773
868774 hints
869775 }
870776
871- fn to_const_expr ( & self , dwarf : Option < & mut dwarf :: Dwarf > ) -> wasm_encoder:: ConstExpr {
777+ fn to_const_expr ( & self ) -> wasm_encoder:: ConstExpr {
872778 let mut tmp = Vec :: new ( ) ;
873- self . encode ( & mut tmp, dwarf) ;
874- tmp. pop ( ) ; // remove trailing 0x0b byte which wasm-encoder doesn't want
779+ for instr in self . instrs . iter ( ) {
780+ instr. encode ( & mut tmp) ;
781+ }
875782 wasm_encoder:: ConstExpr :: raw ( tmp)
876783 }
877784}
0 commit comments