Skip to content

Commit eb0d17d

Browse files
committed
Move parser private data into WastParserContext
1 parent 472da42 commit eb0d17d

File tree

3 files changed

+112
-75
lines changed

3 files changed

+112
-75
lines changed

include/wabt/ir.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -255,26 +255,6 @@ struct FuncSignature {
255255
TypeVector param_types;
256256
TypeVector result_types;
257257

258-
// Reference types can have names, for example (ref $foo) represents
259-
// a type which name is $foo. These types are translated to their
260-
// corresponding index after the parsing is completed. The position
261-
// and names of these reference types are stored in a ReferenceVars
262-
// vector. The names are stored as variables, because the error
263-
// message construction requires a location when a name is not found.
264-
// TODO: move out this parser specific structure from IR.
265-
struct ReferenceVar {
266-
ReferenceVar(uint32_t index, Var var)
267-
: index(index), var(var) {}
268-
269-
uint32_t index;
270-
Var var;
271-
};
272-
273-
typedef std::vector<ReferenceVar> ReferenceVars;
274-
275-
ReferenceVars param_type_vars;
276-
ReferenceVars result_type_vars;
277-
278258
Index GetNumParams() const { return param_types.size(); }
279259
Index GetNumResults() const { return result_types.size(); }
280260
Type GetParamType(Index index) const { return param_types[index]; }
@@ -938,12 +918,6 @@ struct Func {
938918
std::string name;
939919
FuncDeclaration decl;
940920
LocalTypes local_types;
941-
// When some locals are named references, the parser keeps the
942-
// non-compressed local vector until the module parsing is
943-
// completed. After the locals are resolved, local_types are
944-
// constructed from this vector, and then this vector is freed.
945-
// TODO: move out this parser specific structure from IR.
946-
TypeVector local_type_list;
947921
BindingHash bindings;
948922
ExprList exprs;
949923
Location loc;

include/wabt/wast-parser.h

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,41 @@ struct WastParseOptions {
3939

4040
using TokenTypePair = std::array<TokenType, 2>;
4141

42+
class WastParserContext {
43+
public:
44+
struct ReferenceVar {
45+
ReferenceVar(uint32_t index, Var var)
46+
: index(index), var(var) {}
47+
48+
uint32_t index;
49+
Var var;
50+
};
51+
52+
typedef std::vector<ReferenceVar> ReferenceVars;
53+
54+
struct FuncSignatureExtraData {
55+
// Reference types can have names, for example (ref $foo) represents
56+
// a type which name is $foo. These types are translated to their
57+
// corresponding index after the parsing is completed. The position
58+
// and names of these reference types are stored in a ReferenceVars
59+
// vector. The names are stored as variables, because the error
60+
// message construction requires a location when a name is not found.
61+
ReferenceVars param_type_vars;
62+
ReferenceVars result_type_vars;
63+
ReferenceVars local_type_vars;
64+
};
65+
66+
Result ResolveTypeNames(const Module&, FuncSignature*, Errors*);
67+
68+
std::unordered_map<FuncSignature*, FuncSignatureExtraData> func_sig_data;
69+
70+
// When some locals are named references, the parser keeps the
71+
// non-compressed local vector until the module parsing is
72+
// completed. After the locals are resolved, local_types are
73+
// constructed from this vector, and then this vector is freed.
74+
std::unordered_map<Func*, TypeVector> local_type_data;
75+
};
76+
4277
class WastParser {
4378
public:
4479
WastParser(WastLexer*, Errors*, WastParseOptions*);
@@ -137,7 +172,7 @@ class WastParser {
137172
Result ParseValueType(Var* out_type);
138173
Result ParseValueTypeList(
139174
TypeVector* out_type_list,
140-
FuncSignature::ReferenceVars* type_vars,
175+
WastParserContext::ReferenceVars* type_vars,
141176
Index binding_index_offset);
142177
Result ParseRefKind(Type* out_type);
143178
Result ParseRefType(Type* out_type);
@@ -177,13 +212,13 @@ class WastParser {
177212
Result ParseBoundValueTypeList(TokenType,
178213
TypeVector*,
179214
BindingHash*,
180-
FuncSignature::ReferenceVars*,
215+
WastParserContext::ReferenceVars*,
181216
Index binding_index_offset = 0);
182217
Result ParseUnboundValueTypeList(TokenType,
183218
TypeVector*,
184-
FuncSignature::ReferenceVars*);
219+
WastParserContext::ReferenceVars*);
185220
Result ParseResultList(TypeVector*,
186-
FuncSignature::ReferenceVars*);
221+
WastParserContext::ReferenceVars*);
187222
Result ParseInstrList(ExprList*);
188223
Result ParseTerminatingInstrList(ExprList*);
189224
Result ParseInstr(ExprList*);
@@ -258,12 +293,14 @@ class WastParser {
258293
Result ParseSimdV128Const(Const*, TokenType, ConstType);
259294

260295
void CheckImportOrdering(Module*);
296+
Result ResolveTypeNames(const Module&, FuncSignature*, Errors*);
261297
bool HasError() const;
262298

263299
WastLexer* lexer_;
264300
Index last_module_index_ = kInvalidIndex;
265301
Errors* errors_;
266302
WastParseOptions* options_;
303+
WastParserContext context_;
267304

268305
// two-element queue of upcoming tokens
269306
class TokenQueue {

src/wast-parser.cc

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ bool ResolveFuncTypeWithEmptySignature(const Module& module,
322322
Result ResolveRefTypes(const Module& module,
323323
TypeVector& types,
324324
uint32_t base_index,
325-
FuncSignature::ReferenceVars& ref_vars,
325+
WastParserContext::ReferenceVars& ref_vars,
326326
Errors* errors) {
327327
Result result = Result::Ok;
328328
size_t types_size = types.size();
@@ -361,19 +361,6 @@ Result ResolveRefTypes(const Module& module,
361361
return Result::Ok;
362362
}
363363

364-
Result ResolveTypeNames(const Module& module,
365-
FuncSignature& signature,
366-
Errors* errors) {
367-
Result result = Result::Ok;
368-
369-
result |= ResolveRefTypes(module, signature.param_types, 0,
370-
signature.param_type_vars, errors);
371-
372-
result |= ResolveRefTypes(module, signature.result_types, 0,
373-
signature.result_type_vars, errors);
374-
return result;
375-
}
376-
377364
void ResolveImplicitlyDefinedFunctionType(const Location& loc,
378365
Module* module,
379366
const FuncDeclaration& decl) {
@@ -475,11 +462,11 @@ bool IsInlinableFuncSignature(const FuncSignature& sig) {
475462

476463
class ResolveFuncTypesExprVisitorDelegate : public ExprVisitor::DelegateNop {
477464
public:
478-
explicit ResolveFuncTypesExprVisitorDelegate(Module* module, Errors* errors)
479-
: module_(module), errors_(errors) {}
465+
explicit ResolveFuncTypesExprVisitorDelegate(WastParserContext* parser_context, Module* module, Errors* errors)
466+
: parser_context_(parser_context), module_(module), errors_(errors) {}
480467

481468
void ResolveBlockDeclaration(const Location& loc, BlockDeclaration* decl) {
482-
ResolveTypeNames(*module_, decl->sig, errors_);
469+
parser_context_->ResolveTypeNames(*module_, &decl->sig, errors_);
483470
ResolveFuncTypeWithEmptySignature(*module_, decl);
484471
if (!IsInlinableFuncSignature(decl->sig)) {
485472
ResolveImplicitlyDefinedFunctionType(loc, module_, *decl);
@@ -525,11 +512,12 @@ class ResolveFuncTypesExprVisitorDelegate : public ExprVisitor::DelegateNop {
525512
}
526513

527514
private:
515+
WastParserContext* parser_context_;
528516
Module* module_;
529517
Errors* errors_;
530518
};
531519

532-
Result ResolveFuncTypes(Module* module, Errors* errors) {
520+
Result ResolveFuncTypes(WastParserContext* parser_context, Module* module, Errors* errors) {
533521
Result result = Result::Ok;
534522
for (ModuleField& field : module->fields) {
535523
Func* func = nullptr;
@@ -556,7 +544,7 @@ Result ResolveFuncTypes(Module* module, Errors* errors) {
556544

557545
if (entry->kind() == TypeEntryKind::Func) {
558546
FuncType* func_type = cast<FuncType>(entry);
559-
result |= ResolveTypeNames(*module, func_type->sig, errors);
547+
result |= parser_context->ResolveTypeNames(*module, &func_type->sig, errors);
560548
}
561549
continue;
562550
} else {
@@ -566,7 +554,7 @@ Result ResolveFuncTypes(Module* module, Errors* errors) {
566554
bool has_func_type_and_empty_signature = false;
567555

568556
if (decl) {
569-
result |= ResolveTypeNames(*module, decl->sig, errors);
557+
result |= parser_context->ResolveTypeNames(*module, &decl->sig, errors);
570558
has_func_type_and_empty_signature =
571559
ResolveFuncTypeWithEmptySignature(*module, decl);
572560
ResolveImplicitlyDefinedFunctionType(field.loc, module, *decl);
@@ -575,13 +563,16 @@ Result ResolveFuncTypes(Module* module, Errors* errors) {
575563
}
576564

577565
if (func) {
578-
if (!func->local_type_list.empty()) {
579-
result |= ResolveRefTypes(*module, func->local_type_list,
566+
auto it = parser_context->local_type_data.find(func);
567+
if (it != parser_context->local_type_data.end()) {
568+
auto data = parser_context->func_sig_data[&decl->sig];
569+
assert(!data.local_type_vars.empty());
570+
571+
result |= ResolveRefTypes(*module, it->second,
580572
func->GetNumParams(),
581-
decl->sig.param_type_vars, errors);
573+
data.local_type_vars, errors);
582574

583-
func->local_types.Set(func->local_type_list);
584-
func->local_type_list.clear();
575+
func->local_types.Set(it->second);
585576
}
586577

587578
if (has_func_type_and_empty_signature) {
@@ -595,7 +586,7 @@ Result ResolveFuncTypes(Module* module, Errors* errors) {
595586
}
596587
}
597588

598-
ResolveFuncTypesExprVisitorDelegate delegate(module, errors);
589+
ResolveFuncTypesExprVisitorDelegate delegate(parser_context, module, errors);
599590
ExprVisitor visitor(&delegate);
600591
result |= visitor.VisitFunc(func);
601592
}
@@ -618,6 +609,22 @@ void AppendInlineExportFields(Module* module,
618609

619610
} // End of anonymous namespace
620611

612+
Result WastParserContext::ResolveTypeNames(const Module& module,
613+
FuncSignature* signature,
614+
Errors* errors) {
615+
Result result = Result::Ok;
616+
auto it = func_sig_data.find(signature);
617+
618+
if (it != func_sig_data.end()) {
619+
result |= ResolveRefTypes(module, signature->param_types, 0,
620+
it->second.param_type_vars, errors);
621+
622+
result |= ResolveRefTypes(module, signature->result_types, 0,
623+
it->second.result_type_vars, errors);
624+
}
625+
return result;
626+
}
627+
621628
WastParser::WastParser(WastLexer* lexer,
622629
Errors* errors,
623630
WastParseOptions* options)
@@ -1000,7 +1007,7 @@ Result WastParser::ParseValueType(Var* out_type) {
10001007
}
10011008

10021009
Result WastParser::ParseValueTypeList(TypeVector* out_type_list,
1003-
FuncSignature::ReferenceVars* type_vars,
1010+
WastParserContext::ReferenceVars* type_vars,
10041011
Index binding_index_offset) {
10051012
WABT_TRACE(ParseValueTypeList);
10061013
while (true) {
@@ -1022,7 +1029,7 @@ Result WastParser::ParseValueTypeList(TypeVector* out_type_list,
10221029
assert(type.is_name());
10231030
assert(options_->features.function_references_enabled());
10241031
uint32_t index = binding_index_offset + out_type_list->size();
1025-
type_vars->push_back(FuncSignature::ReferenceVar(index, type));
1032+
type_vars->push_back(WastParserContext::ReferenceVar(index, type));
10261033
out_type_list->push_back(Type(Type::Reference, kInvalidIndex));
10271034
}
10281035
}
@@ -1380,7 +1387,7 @@ Result WastParser::ParseModuleFieldList(Module* module) {
13801387
CHECK_RESULT(Synchronize(IsModuleField));
13811388
}
13821389
}
1383-
CHECK_RESULT(ResolveFuncTypes(module, errors_));
1390+
CHECK_RESULT(ResolveFuncTypes(&context_, module, errors_));
13841391
CHECK_RESULT(ResolveNamesModule(module, errors_));
13851392
return Result::Ok;
13861393
}
@@ -1585,15 +1592,19 @@ Result WastParser::ParseFuncModuleField(Module* module) {
15851592
CHECK_RESULT(ParseTypeUseOpt(&func.decl));
15861593
CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.bindings));
15871594

1588-
size_t names_size = func.decl.sig.param_type_vars.size();
1595+
WastParserContext::ReferenceVars locals_references;
1596+
TypeVector types;
1597+
15891598
CHECK_RESULT(ParseBoundValueTypeList(
1590-
TokenType::Local, &func.local_type_list, &func.bindings,
1591-
&func.decl.sig.param_type_vars, func.GetNumParams()));
1599+
TokenType::Local, &types, &func.bindings,
1600+
&locals_references, func.GetNumParams()));
15921601

1593-
if (names_size == func.decl.sig.param_type_vars.size()) {
1602+
if (locals_references.empty()) {
15941603
// No named references in the list, local types can be processed now.
1595-
func.local_types.Set(func.local_type_list);
1596-
func.local_type_list.clear();
1604+
func.local_types.Set(types);
1605+
} else {
1606+
context_.local_type_data[&func] = std::move(types);
1607+
context_.func_sig_data[&func.decl.sig].local_type_vars = std::move(locals_references);
15971608
}
15981609

15991610
CHECK_RESULT(ParseTerminatingInstrList(&func.exprs));
@@ -2016,25 +2027,41 @@ Result WastParser::ParseTypeUseOpt(FuncDeclaration* decl) {
20162027
Result WastParser::ParseFuncSignature(FuncSignature* sig,
20172028
BindingHash* param_bindings) {
20182029
WABT_TRACE(ParseFuncSignature);
2030+
assert(context_.func_sig_data.find(sig) == context_.func_sig_data.end());
2031+
2032+
WastParserContext::FuncSignatureExtraData extra_data;
2033+
20192034
CHECK_RESULT(ParseBoundValueTypeList(TokenType::Param, &sig->param_types,
2020-
param_bindings, &sig->param_type_vars));
2021-
CHECK_RESULT(ParseResultList(&sig->result_types, &sig->result_type_vars));
2035+
param_bindings, &extra_data.param_type_vars));
2036+
CHECK_RESULT(ParseResultList(&sig->result_types, &extra_data.result_type_vars));
2037+
2038+
if (!extra_data.param_type_vars.empty() || !extra_data.result_type_vars.empty()) {
2039+
context_.func_sig_data[sig] = std::move(extra_data);
2040+
}
2041+
20222042
return Result::Ok;
20232043
}
20242044

20252045
Result WastParser::ParseUnboundFuncSignature(FuncSignature* sig) {
20262046
WABT_TRACE(ParseUnboundFuncSignature);
2047+
assert(context_.func_sig_data.find(sig) == context_.func_sig_data.end());
2048+
2049+
WastParserContext::FuncSignatureExtraData extra_data;
20272050
CHECK_RESULT(ParseUnboundValueTypeList(TokenType::Param, &sig->param_types,
2028-
&sig->param_type_vars));
2029-
CHECK_RESULT(ParseResultList(&sig->result_types, &sig->result_type_vars));
2051+
&extra_data.param_type_vars));
2052+
CHECK_RESULT(ParseResultList(&sig->result_types, &extra_data.result_type_vars));
2053+
2054+
if (!extra_data.param_type_vars.empty() || !extra_data.result_type_vars.empty()) {
2055+
context_.func_sig_data[sig] = std::move(extra_data);
2056+
}
20302057
return Result::Ok;
20312058
}
20322059

20332060
Result WastParser::ParseBoundValueTypeList(
20342061
TokenType token,
20352062
TypeVector* types,
20362063
BindingHash* bindings,
2037-
FuncSignature::ReferenceVars* type_vars,
2064+
WastParserContext::ReferenceVars* type_vars,
20382065
Index binding_index_offset) {
20392066
WABT_TRACE(ParseBoundValueTypeList);
20402067
while (MatchLpar(token)) {
@@ -2052,7 +2079,7 @@ Result WastParser::ParseBoundValueTypeList(
20522079
assert(type.is_name());
20532080
assert(options_->features.function_references_enabled());
20542081
uint32_t index = binding_index_offset + types->size();
2055-
type_vars->push_back(FuncSignature::ReferenceVar(index, type));
2082+
type_vars->push_back(WastParserContext::ReferenceVar(index, type));
20562083
types->push_back(Type(Type::Reference, kInvalidIndex));
20572084
}
20582085
} else {
@@ -2066,7 +2093,7 @@ Result WastParser::ParseBoundValueTypeList(
20662093
Result WastParser::ParseUnboundValueTypeList(
20672094
TokenType token,
20682095
TypeVector* types,
2069-
FuncSignature::ReferenceVars* type_vars) {
2096+
WastParserContext::ReferenceVars* type_vars) {
20702097
WABT_TRACE(ParseUnboundValueTypeList);
20712098
while (MatchLpar(token)) {
20722099
CHECK_RESULT(ParseValueTypeList(types, type_vars, 0));
@@ -2076,7 +2103,7 @@ Result WastParser::ParseUnboundValueTypeList(
20762103
}
20772104

20782105
Result WastParser::ParseResultList(TypeVector* result_types,
2079-
FuncSignature::ReferenceVars* type_vars) {
2106+
WastParserContext::ReferenceVars* type_vars) {
20802107
WABT_TRACE(ParseResultList);
20812108
return ParseUnboundValueTypeList(TokenType::Result, result_types, type_vars);
20822109
}
@@ -3152,10 +3179,9 @@ Result WastParser::ParseBlockDeclaration(BlockDeclaration* decl) {
31523179
WABT_TRACE(ParseBlockDeclaration);
31533180
FuncDeclaration func_decl;
31543181
CHECK_RESULT(ParseTypeUseOpt(&func_decl));
3155-
CHECK_RESULT(ParseUnboundFuncSignature(&func_decl.sig));
3182+
CHECK_RESULT(ParseUnboundFuncSignature(&decl->sig));
31563183
decl->has_func_type = func_decl.has_func_type;
31573184
decl->type_var = func_decl.type_var;
3158-
decl->sig = func_decl.sig;
31593185
return Result::Ok;
31603186
}
31613187

0 commit comments

Comments
 (0)