summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/contexts.h13
-rw-r--r--src/parser/parsers.h55
-rw-r--r--src/parser/wat-parser.cpp10
3 files changed, 78 insertions, 0 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 3ed455043..e09f8bbd0 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -548,6 +548,9 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx {
std::vector<DefPos> dataDefs;
std::vector<DefPos> tagDefs;
+ // Positions of export definitions.
+ std::vector<Index> exportDefs;
+
// Positions of typeuses that might implicitly define new types.
std::vector<Index> implicitTypeDefs;
@@ -684,6 +687,11 @@ struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx {
ImportNames* import,
TypeUseT type,
Index pos);
+
+ Result<> addExport(Index pos, Ok, Name, ExternalKind) {
+ exportDefs.push_back(pos);
+ return Ok{};
+ }
};
// Phase 2: Parse type definitions into a TypeBuilder.
@@ -1265,6 +1273,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
Result<>
addData(Name, Name* mem, std::optional<ExprT> offset, DataStringT, Index pos);
+ Result<> addExport(Index, Name value, Name name, ExternalKind kind) {
+ wasm.addExport(builder.makeExport(name, value, kind));
+ return Ok{};
+ }
+
Result<Index> addScratchLocal(Index pos, Type type) {
if (!func) {
return in.err(pos,
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index dc86e0d60..54644cafc 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -194,6 +194,7 @@ template<typename Ctx> MaybeResult<> func(Ctx&);
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<typename Ctx::ExprT> maybeElemexpr(Ctx&);
template<typename Ctx> Result<typename Ctx::ElemListT> elemlist(Ctx&, bool);
template<typename Ctx> MaybeResult<> elem(Ctx&);
@@ -2371,6 +2372,56 @@ template<typename Ctx> MaybeResult<> global(Ctx& ctx) {
return Ok{};
}
+// export ::= '(' 'export' nm:name exportdesc ')'
+// exportdesc ::= '(' 'func' x:funcidx ')'
+// | '(' 'table' x:tableidx ')'
+// | '(' 'memory' x:memidx ')'
+// | '(' 'global' x:globalidx ')'
+// | '(' 'tag' x:tagidx ')'
+template<typename Ctx> MaybeResult<> export_(Ctx& ctx) {
+ auto pos = ctx.in.getPos();
+ if (!ctx.in.takeSExprStart("export"sv)) {
+ return {};
+ }
+
+ auto name = ctx.in.takeName();
+ if (!name) {
+ return ctx.in.err("expected export name");
+ }
+
+ if (ctx.in.takeSExprStart("func"sv)) {
+ auto idx = funcidx(ctx);
+ CHECK_ERR(idx);
+ CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Function));
+ } else if (ctx.in.takeSExprStart("table"sv)) {
+ auto idx = tableidx(ctx);
+ CHECK_ERR(idx);
+ CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Table));
+ } else if (ctx.in.takeSExprStart("memory"sv)) {
+ auto idx = memidx(ctx);
+ CHECK_ERR(idx);
+ CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Memory));
+ } else if (ctx.in.takeSExprStart("global"sv)) {
+ auto idx = globalidx(ctx);
+ CHECK_ERR(idx);
+ CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Global));
+ } else if (ctx.in.takeSExprStart("tag"sv)) {
+ auto idx = tagidx(ctx);
+ CHECK_ERR(idx);
+ CHECK_ERR(ctx.addExport(pos, *idx, *name, ExternalKind::Tag));
+ } else {
+ return ctx.in.err("expected export description");
+ }
+
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of export description");
+ }
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of export");
+ }
+ return Ok{};
+}
+
// elemexpr ::= '(' 'item' expr ')' | '(' instr ')'
template<typename Ctx>
MaybeResult<typename Ctx::ExprT> maybeElemexpr(Ctx& ctx) {
@@ -2611,6 +2662,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
CHECK_ERR(res);
return Ok{};
}
+ if (auto res = export_(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 cc0f582fc..95dfa1405 100644
--- a/src/parser/wat-parser.cpp
+++ b/src/parser/wat-parser.cpp
@@ -178,6 +178,16 @@ Result<> parseModule(Module& wasm, std::string_view input) {
CHECK_ERR(parsed);
assert(parsed);
}
+
+ // 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{};