summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/contexts.h12
-rw-r--r--src/parser/parsers.h70
-rw-r--r--src/parser/wat-parser.cpp20
3 files changed, 95 insertions, 7 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index e09f8bbd0..503f4dc3a 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -1249,6 +1249,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return Ok{};
}
+ Result<>
+ addMemory(Name, const std::vector<Name>&, ImportNames*, TableTypeT, Index) {
+ return Ok{};
+ }
+
Result<> addGlobal(Name,
const std::vector<Name>&,
ImportNames*,
@@ -1259,7 +1264,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
Result<> addImplicitElems(Type type, std::vector<Expression*>&& elems);
Result<> addDeclareElem(Name, std::vector<Expression*>&&, Index) {
- // TODO: Validate that referenced functions appear in a declaratve element
+ // TODO: Validate that referenced functions appear in a declarative element
// segment.
return Ok{};
}
@@ -1273,6 +1278,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
Result<>
addData(Name, Name* mem, std::optional<ExprT> offset, DataStringT, Index pos);
+ Result<>
+ addTag(Name, const std::vector<Name>, ImportNames*, TypeUseT, Index) {
+ return Ok{};
+ }
+
Result<> addExport(Index, Name value, Name name, ExternalKind kind) {
wasm.addExport(builder.makeExport(name, value, kind));
return Ok{};
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 7f4005c3d..6dd617309 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -191,6 +191,7 @@ template<typename Ctx> Result<> strtype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::ModuleNameT> subtype(Ctx&);
template<typename Ctx> MaybeResult<> deftype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx&);
+template<typename Ctx> MaybeResult<> import_(Ctx&);
template<typename Ctx> MaybeResult<> func(Ctx&);
template<typename Ctx> MaybeResult<> table(Ctx&);
template<typename Ctx> MaybeResult<> memory(Ctx&);
@@ -2168,6 +2169,71 @@ template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx& ctx) {
return {};
}
+// import ::= '(' 'import' mod:name nm:name importdesc ')'
+// importdesc ::= '(' 'func' id? typeuse ')'
+// | '(' 'table' id? tabletype ')'
+// | '(' 'memory' id? memtype ')'
+// | '(' 'global' id? globaltype ')'
+// | '(' 'tag' id? typeuse ')'
+template<typename Ctx> MaybeResult<> import_(Ctx& ctx) {
+ auto pos = ctx.in.getPos();
+
+ if (!ctx.in.takeSExprStart("import"sv)) {
+ return {};
+ }
+
+ auto mod = ctx.in.takeName();
+ if (!mod) {
+ return ctx.in.err("expected import module name");
+ }
+
+ auto nm = ctx.in.takeName();
+ if (!nm) {
+ return ctx.in.err("expected import name");
+ }
+ ImportNames names{*mod, *nm};
+
+ if (ctx.in.takeSExprStart("func"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = typeuse(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(
+ ctx.addFunc(name ? *name : Name{}, {}, &names, *type, std::nullopt, pos));
+ } else if (ctx.in.takeSExprStart("table"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = tabletype(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addTable(name ? *name : Name{}, {}, &names, *type, pos));
+ } else if (ctx.in.takeSExprStart("memory"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = memtype(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addMemory(name ? *name : Name{}, {}, &names, *type, pos));
+ } else if (ctx.in.takeSExprStart("global"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = globaltype(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addGlobal(
+ name ? *name : Name{}, {}, &names, *type, std::nullopt, pos));
+ } else if (ctx.in.takeSExprStart("tag"sv)) {
+ auto name = ctx.in.takeID();
+ auto type = typeuse(ctx);
+ CHECK_ERR(type);
+ CHECK_ERR(ctx.addTag(name ? *name : Name{}, {}, &names, *type, pos));
+ } else {
+ return ctx.in.err("expected import description");
+ }
+
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of import description");
+ }
+ if (!ctx.in.takeRParen()) {
+ return ctx.in.err("expected end of import");
+ }
+
+ return Ok{};
+}
+
// func ::= '(' 'func' id? ('(' 'export' name ')')*
// x,I:typeuse t*:vec(local) (in:instr)* ')'
// | '(' 'func' id? ('(' 'export' name ')')*
@@ -2651,6 +2717,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
CHECK_ERR(res);
return Ok{};
}
+ if (auto res = import_(ctx)) {
+ CHECK_ERR(res);
+ return Ok{};
+ }
if (auto res = func(ctx)) {
CHECK_ERR(res);
return Ok{};
diff --git a/src/parser/wat-parser.cpp b/src/parser/wat-parser.cpp
index 95dfa1405..a9ee2a189 100644
--- a/src/parser/wat-parser.cpp
+++ b/src/parser/wat-parser.cpp
@@ -80,9 +80,13 @@ Result<> parseDefs(Ctx& ctx,
for (auto& def : defs) {
ctx.index = def.index;
WithPosition with(ctx, def.pos);
- auto parsed = parser(ctx);
- CHECK_ERR(parsed);
- assert(parsed);
+ if (auto parsed = parser(ctx)) {
+ CHECK_ERR(parsed);
+ } else {
+ auto im = import_(ctx);
+ assert(im);
+ CHECK_ERR(im);
+ }
}
return Ok{};
}
@@ -174,9 +178,13 @@ Result<> parseModule(Module& wasm, std::string_view input) {
ctx.index = i;
CHECK_ERR(ctx.visitFunctionStart(wasm.functions[i].get()));
WithPosition with(ctx, decls.funcDefs[i].pos);
- auto parsed = func(ctx);
- CHECK_ERR(parsed);
- assert(parsed);
+ if (auto parsed = func(ctx)) {
+ CHECK_ERR(parsed);
+ } else {
+ auto im = import_(ctx);
+ assert(im);
+ CHECK_ERR(im);
+ }
}
// Parse exports.