@@ -177,7 +177,7 @@ pub(crate) fn encode(
177177 // Prepare to and emit the code section. This is where DWARF may optionally
178178 // be emitted depending on configuration settings. Note that `code_section`
179179 // will internally emit the branch hints section if necessary.
180- let names = find_names ( module_id, module_name, fields) ;
180+ let names = find_names ( module_id, module_name, fields, & types ) ;
181181 let num_import_funcs = imports
182182 . iter ( )
183183 . filter ( |i| matches ! ( i. item. kind, ItemKind :: Func ( ..) ) )
@@ -209,6 +209,23 @@ pub(crate) fn encode(
209209 }
210210}
211211
212+ fn func_type < ' a > ( types : & ' a [ RecOrType < ' a > ] , ty : u32 ) -> Option < & ' a FunctionType < ' a > > {
213+ // Iterate through `self.types` which is what was encoded into the
214+ // module and find the function type which gives access to the
215+ // parameters which gives access to their types.
216+ let ty = types
217+ . iter ( )
218+ . flat_map ( |t| match t {
219+ RecOrType :: Type ( t) => std:: slice:: from_ref ( * t) ,
220+ RecOrType :: Rec ( r) => & r. types ,
221+ } )
222+ . nth ( ty as usize ) ?;
223+ match & ty. def . kind {
224+ InnerTypeKind :: Func ( ty) => Some ( ty) ,
225+ _ => None ,
226+ }
227+ }
228+
212229struct Encoder < ' a > {
213230 wasm : wasm_encoder:: Module ,
214231 customs : & ' a [ & ' a Custom < ' a > ] ,
@@ -732,7 +749,9 @@ impl Func<'_> {
732749 ) -> Vec < wasm_encoder:: BranchHint > {
733750 assert ! ( self . exports. names. is_empty( ) ) ;
734751 let ( expr, locals) = match & self . kind {
735- FuncKind :: Inline { expression, locals } => ( expression, locals) ,
752+ FuncKind :: Inline {
753+ expression, locals, ..
754+ } => ( expression, locals) ,
736755 _ => panic ! ( "should only have inline functions in emission" ) ,
737756 } ;
738757
@@ -976,6 +995,7 @@ fn find_names<'a>(
976995 module_id : & Option < Id < ' a > > ,
977996 module_name : & Option < NameAnnotation < ' a > > ,
978997 fields : & [ ModuleField < ' a > ] ,
998+ types : & ' a [ RecOrType < ' a > ] ,
979999) -> Names < ' a > {
9801000 fn get_name < ' a > ( id : & Option < Id < ' a > > , name : & Option < NameAnnotation < ' a > > ) -> Option < & ' a str > {
9811001 name. as_ref ( ) . map ( |n| n. name ) . or ( id. and_then ( |id| {
@@ -1056,19 +1076,40 @@ fn find_names<'a>(
10561076 let mut label_names = Vec :: new ( ) ;
10571077 let mut local_idx = 0 ;
10581078 let mut label_idx = 0 ;
1079+ let mut discard_locals = false ;
10591080
1060- // Consult the inline type listed for local names of parameters.
1061- // This is specifically preserved during the name resolution
1062- // pass, but only for functions, so here we can look at the
1063- // original source's names.
10641081 if let Some ( ty) = & f. ty . inline {
1082+ // Consult the inline type listed for local names of parameters.
1083+ // This is specifically preserved during the name resolution
1084+ // pass, but only for functions, so here we can look at the
1085+ // original source's names.
10651086 for ( id, name, _) in ty. params . iter ( ) {
10661087 if let Some ( name) = get_name ( id, name) {
10671088 local_names. push ( ( local_idx, name) ) ;
10681089 }
10691090 local_idx += 1 ;
10701091 }
1092+ } else {
1093+ // If the inline type isn't listed then it's either not present
1094+ // (e.g. no params or results) or it was referenced by index.
1095+ // Either way we've got the index here, so look it up in the
1096+ // list of types and see how many parameters this function's
1097+ // type has.
1098+ let index = match f. ty . index . as_ref ( ) . unwrap ( ) {
1099+ Index :: Num ( n, _) => * n,
1100+ _ => unreachable ! ( ) ,
1101+ } ;
1102+
1103+ match func_type ( types, index) {
1104+ Some ( ft) => local_idx = ft. params . len ( ) as u32 ,
1105+ // If the function type index is invalid then skip
1106+ // preserving names since we don't know how many parameters
1107+ // this function will have so we don't know where to start
1108+ // indexing at.
1109+ None => discard_locals = true ,
1110+ }
10711111 }
1112+
10721113 if let FuncKind :: Inline {
10731114 locals, expression, ..
10741115 } = & f. kind
@@ -1096,7 +1137,7 @@ fn find_names<'a>(
10961137 }
10971138 }
10981139 }
1099- if local_names. len ( ) > 0 {
1140+ if !discard_locals && local_names. len ( ) > 0 {
11001141 ret. locals . push ( ( * idx, local_names) ) ;
11011142 }
11021143 if label_names. len ( ) > 0 {
0 commit comments