@@ -319,37 +319,54 @@ bool ResolveFuncTypeWithEmptySignature(const Module& module,
319319 return false ;
320320}
321321
322- void ResolveTypeName (
323- const Module& module ,
324- Type& type,
325- Index index,
326- const std::unordered_map<uint32_t , std::string>& bindings) {
327- if (type != Type::Reference || type.GetReferenceIndex () != kInvalidIndex ) {
328- return ;
329- }
322+ Result ResolveRefTypes (const Module& module ,
323+ TypeVector& types,
324+ uint32_t base_index,
325+ const std::unordered_map<uint32_t , Var>& bindings,
326+ Errors* errors) {
327+ Result result = Result::Ok;
328+ size_t types_size = types.size ();
329+
330+ for (auto & [index, binding] : bindings) {
331+ if (index < base_index || (index - base_index) >= types_size) {
332+ continue ;
333+ }
334+
335+ Type type = types[index - base_index];
336+
337+ assert (type.IsReferenceWithIndex ());
338+
339+ if (type.GetReferenceIndex () != kInvalidIndex ) {
340+ continue ;
341+ }
342+
343+ const auto type_index = module .type_bindings .FindIndex (binding.name ());
330344
331- const auto name_iterator = bindings.find (index);
332- assert (name_iterator != bindings.cend ());
333- const auto type_index = module .type_bindings .FindIndex (name_iterator->second );
334- assert (type_index != kInvalidIndex );
335- type = Type (Type::Reference, type_index);
345+ if (type_index == kInvalidIndex ) {
346+ errors->emplace_back (
347+ ErrorLevel::Error, binding.loc ,
348+ StringPrintf (" Unknown reference: %s" , binding.name ().c_str ()));
349+ result = Result::Error;
350+ continue ;
351+ }
352+
353+ types[index - base_index] = Type (static_cast <Type::Enum>(type), type_index);
354+ }
355+
356+ return Result::Ok;
336357}
337358
338- void ResolveTypeNames (const Module& module , FuncDeclaration* decl) {
339- assert (decl);
340- auto & signature = decl->sig ;
359+ Result ResolveTypeNames (const Module& module ,
360+ FuncSignature& signature,
361+ Errors* errors) {
362+ Result result = Result::Ok;
341363
342- for (uint32_t param_index = 0 ; param_index < signature.GetNumParams ();
343- ++param_index) {
344- ResolveTypeName (module , signature.param_types [param_index], param_index,
345- signature.param_type_names );
346- }
364+ result |= ResolveRefTypes (module , signature.param_types , 0 ,
365+ signature.param_type_names , errors);
347366
348- for (uint32_t result_index = 0 ; result_index < signature.GetNumResults ();
349- ++result_index) {
350- ResolveTypeName (module , signature.result_types [result_index], result_index,
351- signature.result_type_names );
352- }
367+ result |= ResolveRefTypes (module , signature.result_types , 0 ,
368+ signature.result_type_names , errors);
369+ return result;
353370}
354371
355372void ResolveImplicitlyDefinedFunctionType (const Location& loc,
@@ -457,7 +474,7 @@ class ResolveFuncTypesExprVisitorDelegate : public ExprVisitor::DelegateNop {
457474 : module_(module ), errors_(errors) {}
458475
459476 void ResolveBlockDeclaration (const Location& loc, BlockDeclaration* decl) {
460- ResolveTypeNames (*module_, decl);
477+ ResolveTypeNames (*module_, decl-> sig , errors_ );
461478 ResolveFuncTypeWithEmptySignature (*module_, decl);
462479 if (!IsInlinableFuncSignature (decl->sig )) {
463480 ResolveImplicitlyDefinedFunctionType (loc, module_, *decl);
@@ -529,14 +546,22 @@ Result ResolveFuncTypes(Module* module, Errors* errors) {
529546 } else {
530547 continue ;
531548 }
549+ } else if (auto * type_field = dyn_cast<TypeModuleField>(&field)) {
550+ TypeEntry* entry = type_field->type .get ();
551+
552+ if (entry->kind () == TypeEntryKind::Func) {
553+ FuncType* func_type = cast<FuncType>(entry);
554+ result |= ResolveTypeNames (*module , func_type->sig , errors);
555+ }
556+ continue ;
532557 } else {
533558 continue ;
534559 }
535560
536561 bool has_func_type_and_empty_signature = false ;
537562
538563 if (decl) {
539- ResolveTypeNames (*module , decl);
564+ result |= ResolveTypeNames (*module , decl-> sig , errors );
540565 has_func_type_and_empty_signature =
541566 ResolveFuncTypeWithEmptySignature (*module , decl);
542567 ResolveImplicitlyDefinedFunctionType (field.loc , module , *decl);
@@ -545,6 +570,15 @@ Result ResolveFuncTypes(Module* module, Errors* errors) {
545570 }
546571
547572 if (func) {
573+ if (!func->local_type_list .empty ()) {
574+ result |= ResolveRefTypes (*module , func->local_type_list ,
575+ func->GetNumParams (),
576+ decl->sig .param_type_names , errors);
577+
578+ func->local_types .Set (func->local_type_list );
579+ func->local_type_list .clear ();
580+ }
581+
548582 if (has_func_type_and_empty_signature) {
549583 // The call to ResolveFuncTypeWithEmptySignature may have updated the
550584 // function signature so there are parameters. Since parameters and
@@ -962,7 +996,8 @@ Result WastParser::ParseValueType(Var* out_type) {
962996
963997Result WastParser::ParseValueTypeList (
964998 TypeVector* out_type_list,
965- std::unordered_map<uint32_t , std::string>* type_names) {
999+ std::unordered_map<uint32_t , Var>* type_names,
1000+ Index binding_index_offset) {
9661001 WABT_TRACE (ParseValueTypeList);
9671002 while (true ) {
9681003 if (!PeekMatchRefType () && !PeekMatch (TokenType::ValueType)) {
@@ -973,11 +1008,16 @@ Result WastParser::ParseValueTypeList(
9731008 CHECK_RESULT (ParseValueType (&type));
9741009
9751010 if (type.is_index ()) {
976- out_type_list->push_back (Type (type.index ()));
1011+ // TODO: Temporary fix.
1012+ if (type.index () >= static_cast <Index>(Type::Void)) {
1013+ out_type_list->push_back (Type (type.index ()));
1014+ } else {
1015+ out_type_list->push_back (Type (Type::Reference, type.index ()));
1016+ }
9771017 } else {
9781018 assert (type.is_name ());
9791019 assert (options_->features .function_references_enabled ());
980- type_names->emplace (out_type_list->size (), type. name () );
1020+ type_names->emplace (binding_index_offset + out_type_list->size (), type);
9811021 out_type_list->push_back (Type (Type::Reference, kInvalidIndex ));
9821022 }
9831023 }
@@ -1539,11 +1579,18 @@ Result WastParser::ParseFuncModuleField(Module* module) {
15391579 func.loc = GetLocation ();
15401580 CHECK_RESULT (ParseTypeUseOpt (&func.decl ));
15411581 CHECK_RESULT (ParseFuncSignature (&func.decl .sig , &func.bindings ));
1542- TypeVector local_types;
1582+
1583+ size_t names_size = func.decl .sig .param_type_names .size ();
15431584 CHECK_RESULT (ParseBoundValueTypeList (
1544- TokenType::Local, &local_types , &func.bindings ,
1585+ TokenType::Local, &func. local_type_list , &func.bindings ,
15451586 &func.decl .sig .param_type_names , func.GetNumParams ()));
1546- func.local_types .Set (local_types);
1587+
1588+ if (names_size == func.decl .sig .param_type_names .size ()) {
1589+ // No named references in the list, local types can be processed now.
1590+ func.local_types .Set (func.local_type_list );
1591+ func.local_type_list .clear ();
1592+ }
1593+
15471594 CHECK_RESULT (ParseTerminatingInstrList (&func.exprs ));
15481595 module ->AppendField (std::move (field));
15491596 }
@@ -1982,7 +2029,7 @@ Result WastParser::ParseBoundValueTypeList(
19822029 TokenType token,
19832030 TypeVector* types,
19842031 BindingHash* bindings,
1985- std::unordered_map<uint32_t , std::string >* type_names,
2032+ std::unordered_map<uint32_t , Var >* type_names,
19862033 Index binding_index_offset) {
19872034 WABT_TRACE (ParseBoundValueTypeList);
19882035 while (MatchLpar (token)) {
@@ -1999,11 +2046,11 @@ Result WastParser::ParseBoundValueTypeList(
19992046 } else {
20002047 assert (type.is_name ());
20012048 assert (options_->features .function_references_enabled ());
2002- type_names->emplace (binding_index_offset + types->size (), type. name () );
2049+ type_names->emplace (binding_index_offset + types->size (), type);
20032050 types->push_back (Type (Type::Reference, kInvalidIndex ));
20042051 }
20052052 } else {
2006- CHECK_RESULT (ParseValueTypeList (types, type_names));
2053+ CHECK_RESULT (ParseValueTypeList (types, type_names, binding_index_offset ));
20072054 }
20082055 EXPECT (Rpar);
20092056 }
@@ -2013,18 +2060,18 @@ Result WastParser::ParseBoundValueTypeList(
20132060Result WastParser::ParseUnboundValueTypeList (
20142061 TokenType token,
20152062 TypeVector* types,
2016- std::unordered_map<uint32_t , std::string >* type_names) {
2063+ std::unordered_map<uint32_t , Var >* type_names) {
20172064 WABT_TRACE (ParseUnboundValueTypeList);
20182065 while (MatchLpar (token)) {
2019- CHECK_RESULT (ParseValueTypeList (types, type_names));
2066+ CHECK_RESULT (ParseValueTypeList (types, type_names, 0 ));
20202067 EXPECT (Rpar);
20212068 }
20222069 return Result::Ok;
20232070}
20242071
20252072Result WastParser::ParseResultList (
20262073 TypeVector* result_types,
2027- std::unordered_map<uint32_t , std::string >* type_names) {
2074+ std::unordered_map<uint32_t , Var >* type_names) {
20282075 WABT_TRACE (ParseResultList);
20292076 return ParseUnboundValueTypeList (TokenType::Result, result_types, type_names);
20302077}
0 commit comments