diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/parser/contexts.h | 12 | ||||
-rw-r--r-- | src/parser/parsers.h | 70 | ||||
-rw-r--r-- | src/parser/wat-parser.cpp | 20 |
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. |