summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/contexts.h14
-rw-r--r--src/parser/parsers.h22
-rw-r--r--src/parser/wat-parser.cpp1
3 files changed, 37 insertions, 0 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index c1ccefe53..507a54342 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -589,6 +589,7 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx {
std::vector<DefPos> tableDefs;
std::vector<DefPos> memoryDefs;
std::vector<DefPos> globalDefs;
+ std::vector<DefPos> startDefs;
std::vector<DefPos> elemDefs;
std::vector<DefPos> dataDefs;
std::vector<DefPos> tagDefs;
@@ -715,6 +716,14 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx {
std::optional<ExprT>,
Index pos);
+ Result<> addStart(FuncIdxT, Index pos) {
+ if (!startDefs.empty()) {
+ return Err{"unexpected extra 'start' function"};
+ }
+ startDefs.push_back({{}, pos, 0});
+ return Ok{};
+ }
+
Result<> addElem(Name, TableIdxT*, std::optional<ExprT>, ElemListT&&, Index);
Result<> addDeclareElem(Name, ElemListT&&, Index) { return Ok{}; }
@@ -1325,6 +1334,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
std::optional<ExprT> exp,
Index);
+ Result<> addStart(Name name, Index pos) {
+ wasm.start = name;
+ return Ok{};
+ }
+
Result<> addImplicitElems(Type type, std::vector<Expression*>&& elems);
Result<> addDeclareElem(Name, std::vector<Expression*>&&, Index) {
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index c7b9168b1..d62645441 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -202,6 +202,7 @@ template<typename Ctx> MaybeResult<> table(Ctx&);
template<typename Ctx> MaybeResult<> memory(Ctx&);
template<typename Ctx> MaybeResult<> global(Ctx&);
template<typename Ctx> MaybeResult<> export_(Ctx&);
+template<typename Ctx> MaybeResult<> start(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::ExprT> maybeElemexpr(Ctx&);
template<typename Ctx> Result<typename Ctx::ElemListT> elemlist(Ctx&, bool);
template<typename Ctx> MaybeResult<> elem(Ctx&);
@@ -2648,6 +2649,23 @@ template<typename Ctx> MaybeResult<> export_(Ctx& ctx) {
return Ok{};
}
+// start ::= '(' 'start' funcidx ')'
+template<typename Ctx> MaybeResult<> start(Ctx& ctx) {
+ auto pos = ctx.in.getPos();
+ if (!ctx.in.takeSExprStart("start"sv)) {
+ return {};
+ }
+ auto func = funcidx(ctx);
+ CHECK_ERR(func);
+
+ CHECK_ERR(ctx.addStart(*func, pos));
+
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of start declaration");
+ }
+ return Ok{};
+}
+
// elemexpr ::= '(' 'item' expr ')' | '(' instr ')'
template<typename Ctx>
MaybeResult<typename Ctx::ExprT> maybeElemexpr(Ctx& ctx) {
@@ -2896,6 +2914,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
CHECK_ERR(res);
return Ok{};
}
+ if (auto res = start(ctx)) {
+ CHECK_ERR(res);
+ return Ok{};
+ }
if (auto res = elem(ctx)) {
CHECK_ERR(res);
return Ok{};
diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp
index a9ee2a189..f247dbf48 100644
--- a/src/parser/wat-parser.cpp
+++ b/src/parser/wat-parser.cpp
@@ -171,6 +171,7 @@ Result<> parseModule(Module& wasm, std::string_view input) {
*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));