summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-06-11 17:18:50 -0700
committerGitHub <noreply@github.com>2024-06-12 00:18:50 +0000
commit475841dd5f0c50d7072f6dfc26dffd66e02abc10 (patch)
tree62d0b25a347b7dfdcf1225e0ed3a5d8a2e8d3dd8 /src/parser
parent425ecc65dea1a26c5b3667a46926a9834834b5cc (diff)
downloadbinaryen-475841dd5f0c50d7072f6dfc26dffd66e02abc10.tar.gz
binaryen-475841dd5f0c50d7072f6dfc26dffd66e02abc10.tar.bz2
binaryen-475841dd5f0c50d7072f6dfc26dffd66e02abc10.zip
[Parser][NFC] Split parser into multiple compilation units (#6653)
Because the parser has five stages, it requires instantiating all of the templates in parsers.h with up to five different contexts. Instantiating all those templates in a single compilation unit takes a long time. On my machine, a release build of wat-parser.cpp.o took 32 seconds. To reduce the time of incremental rebuilds on machines with many cores, split the code across several compilation units so that the templates need to be instantiated for just a single context in each unit. On my machine the longest compilation time after this splitting is 17 seconds. The time for a full release build also drops from 42 seconds to 33 seconds. On machines with fewer cores, the benefit may be smaller or even negative, though.
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/CMakeLists.txt5
-rw-r--r--src/parser/parse-1-decls.cpp23
-rw-r--r--src/parser/parse-2-typedefs.cpp55
-rw-r--r--src/parser/parse-3-implicit-types.cpp35
-rw-r--r--src/parser/parse-4-module-types.cpp41
-rw-r--r--src/parser/parse-5-defs.cpp95
-rw-r--r--src/parser/parsers.h31
-rw-r--r--src/parser/wat-parser-internal.h97
-rw-r--r--src/parser/wat-parser.cpp154
9 files changed, 369 insertions, 167 deletions
diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt
index 9c54646e7..045948ba1 100644
--- a/src/parser/CMakeLists.txt
+++ b/src/parser/CMakeLists.txt
@@ -3,6 +3,11 @@ set(parser_SOURCES
context-decls.cpp
context-defs.cpp
lexer.cpp
+ parse-1-decls.cpp
+ parse-2-typedefs.cpp
+ parse-3-implicit-types.cpp
+ parse-4-module-types.cpp
+ parse-5-defs.cpp
wast-parser.cpp
wat-parser.cpp
${parser_HEADERS}
diff --git a/src/parser/parse-1-decls.cpp b/src/parser/parse-1-decls.cpp
new file mode 100644
index 000000000..1c753cc61
--- /dev/null
+++ b/src/parser/parse-1-decls.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wat-parser-internal.h"
+
+namespace wasm::WATParser {
+
+Result<> parseDecls(ParseDeclsCtx& decls) { return module(decls); }
+
+} // namespace wasm::WATParser
diff --git a/src/parser/parse-2-typedefs.cpp b/src/parser/parse-2-typedefs.cpp
new file mode 100644
index 000000000..90a84941d
--- /dev/null
+++ b/src/parser/parse-2-typedefs.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wat-parser-internal.h"
+
+namespace wasm::WATParser {
+
+Result<> parseTypeDefs(
+ ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<HeapType, std::unordered_map<Name, Index>>& typeNames) {
+ TypeBuilder builder(decls.subtypeDefs.size());
+ ParseTypeDefsCtx ctx(input, builder, typeIndices);
+ for (auto& typeDef : decls.typeDefs) {
+ WithPosition with(ctx, typeDef.pos);
+ CHECK_ERR(deftype(ctx));
+ }
+ auto built = builder.build();
+ if (auto* err = built.getError()) {
+ std::stringstream msg;
+ msg << "invalid type: " << err->reason;
+ return ctx.in.err(decls.typeDefs[err->index].pos, msg.str());
+ }
+ types = *built;
+ // Record type names on the module and in typeNames.
+ for (size_t i = 0; i < types.size(); ++i) {
+ auto& names = ctx.names[i];
+ auto& fieldNames = names.fieldNames;
+ if (names.name.is() || fieldNames.size()) {
+ decls.wasm.typeNames.insert({types[i], names});
+ auto& fieldIdxMap = typeNames[types[i]];
+ for (auto [idx, name] : fieldNames) {
+ fieldIdxMap.insert({name, idx});
+ }
+ }
+ }
+ return Ok{};
+}
+
+} // namespace wasm::WATParser
diff --git a/src/parser/parse-3-implicit-types.cpp b/src/parser/parse-3-implicit-types.cpp
new file mode 100644
index 000000000..3a3a867e1
--- /dev/null
+++ b/src/parser/parse-3-implicit-types.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wat-parser-internal.h"
+
+namespace wasm::WATParser {
+
+Result<>
+parseImplicitTypeDefs(ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<Index, HeapType>& implicitTypes) {
+ ParseImplicitTypeDefsCtx ctx(input, types, implicitTypes, typeIndices);
+ for (Index pos : decls.implicitTypeDefs) {
+ WithPosition with(ctx, pos);
+ CHECK_ERR(typeuse(ctx));
+ }
+ return Ok{};
+}
+
+} // namespace wasm::WATParser
diff --git a/src/parser/parse-4-module-types.cpp b/src/parser/parse-4-module-types.cpp
new file mode 100644
index 000000000..04d8292d0
--- /dev/null
+++ b/src/parser/parse-4-module-types.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wat-parser-internal.h"
+
+namespace wasm::WATParser {
+
+Result<> parseModuleTypes(ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<Index, HeapType>& implicitTypes) {
+ ParseModuleTypesCtx ctx(input,
+ decls.wasm,
+ types,
+ implicitTypes,
+ decls.implicitElemIndices,
+ typeIndices);
+ CHECK_ERR(parseDefs(ctx, decls.funcDefs, func));
+ CHECK_ERR(parseDefs(ctx, decls.tableDefs, table));
+ CHECK_ERR(parseDefs(ctx, decls.memoryDefs, memory));
+ CHECK_ERR(parseDefs(ctx, decls.globalDefs, global));
+ CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem));
+ CHECK_ERR(parseDefs(ctx, decls.tagDefs, tag));
+ return Ok{};
+}
+
+} // namespace wasm::WATParser
diff --git a/src/parser/parse-5-defs.cpp b/src/parser/parse-5-defs.cpp
new file mode 100644
index 000000000..acc81bb75
--- /dev/null
+++ b/src/parser/parse-5-defs.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wat-parser-internal.h"
+
+namespace wasm::WATParser {
+
+Result<> parseDefinitions(
+ ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<Index, HeapType>& implicitTypes,
+ std::unordered_map<HeapType, std::unordered_map<Name, Index>>& typeNames) {
+ // Parse definitions.
+ // TODO: Parallelize this.
+ ParseDefsCtx ctx(input,
+ decls.wasm,
+ types,
+ implicitTypes,
+ typeNames,
+ decls.implicitElemIndices,
+ typeIndices);
+ CHECK_ERR(parseDefs(ctx, decls.tableDefs, table));
+ CHECK_ERR(parseDefs(ctx, decls.globalDefs, global));
+ CHECK_ERR(parseDefs(ctx, decls.startDefs, start));
+ CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem));
+ CHECK_ERR(parseDefs(ctx, decls.dataDefs, data));
+
+ for (Index i = 0; i < decls.funcDefs.size(); ++i) {
+ ctx.index = i;
+ auto* f = decls.wasm.functions[i].get();
+ WithPosition with(ctx, decls.funcDefs[i].pos);
+ ctx.setSrcLoc(decls.funcDefs[i].annotations);
+ if (!f->imported()) {
+ CHECK_ERR(ctx.visitFunctionStart(f));
+ }
+ if (auto parsed = func(ctx)) {
+ CHECK_ERR(parsed);
+ } else {
+ auto im = import_(ctx);
+ assert(im);
+ CHECK_ERR(im);
+ }
+ if (!f->imported()) {
+ auto end = ctx.irBuilder.visitEnd();
+ if (auto* err = end.getErr()) {
+ return ctx.in.err(decls.funcDefs[i].pos, err->msg);
+ }
+ }
+ }
+
+ // Parse exports.
+ // TODO: It would be more technically correct to interleave these properly
+ // with the implicit inline exports in other module field definitions.
+ for (auto pos : decls.exportDefs) {
+ WithPosition with(ctx, pos);
+ auto parsed = export_(ctx);
+ CHECK_ERR(parsed);
+ assert(parsed);
+ }
+ return Ok{};
+}
+
+Result<Literal> parseConst(Lexer& lexer) {
+ Module wasm;
+ ParseDefsCtx ctx(lexer, wasm, {}, {}, {}, {}, {});
+ auto inst = foldedinstr(ctx);
+ CHECK_ERR(inst);
+ auto expr = ctx.irBuilder.build();
+ if (auto* err = expr.getErr()) {
+ return lexer.err(err->msg);
+ }
+ auto* e = *expr;
+ if (!e->is<Const>() && !e->is<RefNull>() && !e->is<RefI31>()) {
+ return lexer.err("expected constant");
+ }
+ lexer = ctx.in;
+ return getLiteralFromConstExpression(e);
+}
+
+} // namespace wasm::WATParser
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index ab990e7b0..c4eaf5fc6 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -20,6 +20,7 @@
#include "common.h"
#include "contexts.h"
#include "lexer.h"
+#include "wat-parser-internal.h"
namespace wasm::WATParser {
@@ -350,32 +351,6 @@ template<typename Ctx> MaybeResult<> tag(Ctx&);
template<typename Ctx> MaybeResult<> modulefield(Ctx&);
template<typename Ctx> Result<> module(Ctx&);
-// =========
-// Utilities
-// =========
-
-// RAII utility for temporarily changing the parsing position of a parsing
-// context.
-template<typename Ctx> struct WithPosition {
- Ctx& ctx;
- Index original;
- std::vector<Annotation> annotations;
-
- WithPosition(Ctx& ctx, Index pos)
- : ctx(ctx), original(ctx.in.getPos()),
- annotations(ctx.in.takeAnnotations()) {
- ctx.in.setPos(pos);
- }
-
- ~WithPosition() {
- ctx.in.setPos(original);
- ctx.in.setAnnotations(std::move(annotations));
- }
-};
-
-// Deduction guide to satisfy -Wctad-maybe-unsupported.
-template<typename Ctx> WithPosition(Ctx& ctx, Index) -> WithPosition<Ctx>;
-
// =====
// Types
// =====
@@ -2699,7 +2674,7 @@ Result<typename Ctx::TypeUseT> typeuse(Ctx& ctx, bool allowNames) {
}
// ('(' 'import' mod:name nm:name ')')?
-MaybeResult<ImportNames> inlineImport(Lexer& in) {
+inline MaybeResult<ImportNames> inlineImport(Lexer& in) {
if (!in.takeSExprStart("import"sv)) {
return {};
}
@@ -2719,7 +2694,7 @@ MaybeResult<ImportNames> inlineImport(Lexer& in) {
}
// ('(' 'export' name ')')*
-Result<std::vector<Name>> inlineExports(Lexer& in) {
+inline Result<std::vector<Name>> inlineExports(Lexer& in) {
std::vector<Name> exports;
while (in.takeSExprStart("export"sv)) {
auto name = in.takeName();
diff --git a/src/parser/wat-parser-internal.h b/src/parser/wat-parser-internal.h
new file mode 100644
index 000000000..00c96abd4
--- /dev/null
+++ b/src/parser/wat-parser-internal.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2024 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "contexts.h"
+#include "parsers.h"
+
+#ifndef parser_wat_parser_internal_h
+#define parser_wat_parser_internal_h
+
+namespace wasm::WATParser {
+
+Result<> parseDecls(ParseDeclsCtx& decls);
+
+Result<> parseTypeDefs(
+ ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<HeapType, std::unordered_map<Name, Index>>& typeNames);
+
+Result<>
+parseImplicitTypeDefs(ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<Index, HeapType>& implicitTypes);
+
+Result<> parseModuleTypes(ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<Index, HeapType>& implicitTypes);
+
+Result<> parseDefinitions(
+ ParseDeclsCtx& decls,
+ Lexer& input,
+ IndexMap& typeIndices,
+ std::vector<HeapType>& types,
+ std::unordered_map<Index, HeapType>& implicitTypes,
+ std::unordered_map<HeapType, std::unordered_map<Name, Index>>& typeNames);
+
+// RAII utility for temporarily changing the parsing position of a parsing
+// context.
+template<typename Ctx> struct WithPosition {
+ Ctx& ctx;
+ Index original;
+ std::vector<Annotation> annotations;
+
+ WithPosition(Ctx& ctx, Index pos)
+ : ctx(ctx), original(ctx.in.getPos()),
+ annotations(ctx.in.takeAnnotations()) {
+ ctx.in.setPos(pos);
+ }
+
+ ~WithPosition() {
+ ctx.in.setPos(original);
+ ctx.in.setAnnotations(std::move(annotations));
+ }
+};
+
+template<typename Ctx>
+Result<> parseDefs(Ctx& ctx,
+ const std::vector<DefPos>& defs,
+ MaybeResult<> (*parser)(Ctx&)) {
+ for (auto& def : defs) {
+ ctx.index = def.index;
+ WithPosition with(ctx, def.pos);
+ if (auto parsed = parser(ctx)) {
+ CHECK_ERR(parsed);
+ } else {
+ auto im = import_(ctx);
+ assert(im);
+ CHECK_ERR(im);
+ }
+ }
+ return Ok{};
+}
+
+// Deduction guide to satisfy -Wctad-maybe-unsupported.
+template<typename Ctx> WithPosition(Ctx& ctx, Index) -> WithPosition<Ctx>;
+
+} // namespace wasm::WATParser
+
+#endif // parser_wat_parser_internal_h
diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp
index 4763c69ec..975cbd3c3 100644
--- a/src/parser/wat-parser.cpp
+++ b/src/parser/wat-parser.cpp
@@ -18,10 +18,10 @@
#include "contexts.h"
#include "ir/names.h"
#include "lexer.h"
-#include "parsers.h"
#include "pass.h"
#include "wasm-type.h"
#include "wasm.h"
+#include "wat-parser-internal.h"
// The WebAssembly text format is recursive in the sense that elements may be
// referred to before they are declared. Furthermore, elements may be referred
@@ -73,24 +73,6 @@ Result<IndexMap> createIndexMap(Lexer& in, const std::vector<DefPos>& defs) {
return indices;
}
-template<typename Ctx>
-Result<> parseDefs(Ctx& ctx,
- const std::vector<DefPos>& defs,
- MaybeResult<> (*parser)(Ctx&)) {
- for (auto& def : defs) {
- ctx.index = def.index;
- WithPosition with(ctx, def.pos);
- if (auto parsed = parser(ctx)) {
- CHECK_ERR(parsed);
- } else {
- auto im = import_(ctx);
- assert(im);
- CHECK_ERR(im);
- }
- }
- return Ok{};
-}
-
void propagateDebugLocations(Module& wasm) {
// Copy debug locations from parents or previous siblings to expressions that
// do not already have their own debug locations.
@@ -101,10 +83,16 @@ void propagateDebugLocations(Module& wasm) {
runner.run();
}
+// Parse module-level declarations.
+
+// Parse type definitions.
+
+// Parse implicit type definitions and map typeuses without explicit types to
+// the correct types.
+
Result<> doParseModule(Module& wasm, Lexer& input, bool allowExtra) {
- // Parse module-level declarations.
ParseDeclsCtx decls(input, wasm);
- CHECK_ERR(module(decls));
+ CHECK_ERR(parseDecls(decls));
if (!allowExtra && !decls.in.empty()) {
return decls.in.err("Unexpected tokens after module");
}
@@ -112,113 +100,18 @@ Result<> doParseModule(Module& wasm, Lexer& input, bool allowExtra) {
auto typeIndices = createIndexMap(decls.in, decls.subtypeDefs);
CHECK_ERR(typeIndices);
- // Parse type definitions.
std::vector<HeapType> types;
std::unordered_map<HeapType, std::unordered_map<Name, Index>> typeNames;
- {
- TypeBuilder builder(decls.subtypeDefs.size());
- ParseTypeDefsCtx ctx(input, builder, *typeIndices);
- for (auto& typeDef : decls.typeDefs) {
- WithPosition with(ctx, typeDef.pos);
- CHECK_ERR(deftype(ctx));
- }
- auto built = builder.build();
- if (auto* err = built.getError()) {
- std::stringstream msg;
- msg << "invalid type: " << err->reason;
- return ctx.in.err(decls.typeDefs[err->index].pos, msg.str());
- }
- types = *built;
- // Record type names on the module and in typeNames.
- for (size_t i = 0; i < types.size(); ++i) {
- auto& names = ctx.names[i];
- auto& fieldNames = names.fieldNames;
- if (names.name.is() || fieldNames.size()) {
- wasm.typeNames.insert({types[i], names});
- auto& fieldIdxMap = typeNames[types[i]];
- for (auto [idx, name] : fieldNames) {
- fieldIdxMap.insert({name, idx});
- }
- }
- }
- }
+ CHECK_ERR(parseTypeDefs(decls, input, *typeIndices, types, typeNames));
- // Parse implicit type definitions and map typeuses without explicit types to
- // the correct types.
std::unordered_map<Index, HeapType> implicitTypes;
+ CHECK_ERR(
+ parseImplicitTypeDefs(decls, input, *typeIndices, types, implicitTypes));
- {
- ParseImplicitTypeDefsCtx ctx(input, types, implicitTypes, *typeIndices);
- for (Index pos : decls.implicitTypeDefs) {
- WithPosition with(ctx, pos);
- CHECK_ERR(typeuse(ctx));
- }
- }
-
- {
- // Parse module-level types.
- ParseModuleTypesCtx ctx(input,
- wasm,
- types,
- implicitTypes,
- decls.implicitElemIndices,
- *typeIndices);
- CHECK_ERR(parseDefs(ctx, decls.funcDefs, func));
- CHECK_ERR(parseDefs(ctx, decls.tableDefs, table));
- CHECK_ERR(parseDefs(ctx, decls.memoryDefs, memory));
- CHECK_ERR(parseDefs(ctx, decls.globalDefs, global));
- CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem));
- CHECK_ERR(parseDefs(ctx, decls.tagDefs, tag));
- }
- {
- // Parse definitions.
- // TODO: Parallelize this.
- ParseDefsCtx ctx(input,
- wasm,
- types,
- implicitTypes,
- typeNames,
- decls.implicitElemIndices,
- *typeIndices);
- CHECK_ERR(parseDefs(ctx, decls.tableDefs, table));
- CHECK_ERR(parseDefs(ctx, decls.globalDefs, global));
- CHECK_ERR(parseDefs(ctx, decls.startDefs, start));
- CHECK_ERR(parseDefs(ctx, decls.elemDefs, elem));
- CHECK_ERR(parseDefs(ctx, decls.dataDefs, data));
-
- for (Index i = 0; i < decls.funcDefs.size(); ++i) {
- ctx.index = i;
- auto* f = wasm.functions[i].get();
- WithPosition with(ctx, decls.funcDefs[i].pos);
- ctx.setSrcLoc(decls.funcDefs[i].annotations);
- if (!f->imported()) {
- CHECK_ERR(ctx.visitFunctionStart(f));
- }
- if (auto parsed = func(ctx)) {
- CHECK_ERR(parsed);
- } else {
- auto im = import_(ctx);
- assert(im);
- CHECK_ERR(im);
- }
- if (!f->imported()) {
- auto end = ctx.irBuilder.visitEnd();
- if (auto* err = end.getErr()) {
- return ctx.in.err(decls.funcDefs[i].pos, err->msg);
- }
- }
- }
+ CHECK_ERR(parseModuleTypes(decls, input, *typeIndices, types, implicitTypes));
- // Parse exports.
- // TODO: It would be more technically correct to interleave these properly
- // with the implicit inline exports in other module field definitions.
- for (auto pos : decls.exportDefs) {
- WithPosition with(ctx, pos);
- auto parsed = export_(ctx);
- CHECK_ERR(parsed);
- assert(parsed);
- }
- }
+ CHECK_ERR(parseDefinitions(
+ decls, input, *typeIndices, types, implicitTypes, typeNames));
propagateDebugLocations(wasm);
input = decls.in;
@@ -237,21 +130,4 @@ Result<> parseModule(Module& wasm, Lexer& lexer) {
return doParseModule(wasm, lexer, true);
}
-Result<Literal> parseConst(Lexer& lexer) {
- Module wasm;
- ParseDefsCtx ctx(lexer, wasm, {}, {}, {}, {}, {});
- auto inst = foldedinstr(ctx);
- CHECK_ERR(inst);
- auto expr = ctx.irBuilder.build();
- if (auto* err = expr.getErr()) {
- return lexer.err(err->msg);
- }
- auto* e = *expr;
- if (!e->is<Const>() && !e->is<RefNull>() && !e->is<RefI31>()) {
- return lexer.err("expected constant");
- }
- lexer = ctx.in;
- return getLiteralFromConstExpression(e);
-}
-
} // namespace wasm::WATParser