Skip to content

Commit 5e3f81c

Browse files
authored
[Parser] Support standalone import definitions (#6191)
We previously support the in-line import abbreviation, but now add support for explicit, non-abbreviated imports as well.
1 parent 95ed4f3 commit 5e3f81c

4 files changed

Lines changed: 164 additions & 62 deletions

File tree

src/parser/contexts.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
12491249
return Ok{};
12501250
}
12511251

1252+
Result<>
1253+
addMemory(Name, const std::vector<Name>&, ImportNames*, TableTypeT, Index) {
1254+
return Ok{};
1255+
}
1256+
12521257
Result<> addGlobal(Name,
12531258
const std::vector<Name>&,
12541259
ImportNames*,
@@ -1259,7 +1264,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
12591264
Result<> addImplicitElems(Type type, std::vector<Expression*>&& elems);
12601265

12611266
Result<> addDeclareElem(Name, std::vector<Expression*>&&, Index) {
1262-
// TODO: Validate that referenced functions appear in a declaratve element
1267+
// TODO: Validate that referenced functions appear in a declarative element
12631268
// segment.
12641269
return Ok{};
12651270
}
@@ -1273,6 +1278,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
12731278
Result<>
12741279
addData(Name, Name* mem, std::optional<ExprT> offset, DataStringT, Index pos);
12751280

1281+
Result<>
1282+
addTag(Name, const std::vector<Name>, ImportNames*, TypeUseT, Index) {
1283+
return Ok{};
1284+
}
1285+
12761286
Result<> addExport(Index, Name value, Name name, ExternalKind kind) {
12771287
wasm.addExport(builder.makeExport(name, value, kind));
12781288
return Ok{};

src/parser/parsers.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ template<typename Ctx> Result<> strtype(Ctx&);
191191
template<typename Ctx> MaybeResult<typename Ctx::ModuleNameT> subtype(Ctx&);
192192
template<typename Ctx> MaybeResult<> deftype(Ctx&);
193193
template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx&);
194+
template<typename Ctx> MaybeResult<> import_(Ctx&);
194195
template<typename Ctx> MaybeResult<> func(Ctx&);
195196
template<typename Ctx> MaybeResult<> table(Ctx&);
196197
template<typename Ctx> MaybeResult<> memory(Ctx&);
@@ -2168,6 +2169,71 @@ template<typename Ctx> MaybeResult<typename Ctx::LocalsT> locals(Ctx& ctx) {
21682169
return {};
21692170
}
21702171

2172+
// import ::= '(' 'import' mod:name nm:name importdesc ')'
2173+
// importdesc ::= '(' 'func' id? typeuse ')'
2174+
// | '(' 'table' id? tabletype ')'
2175+
// | '(' 'memory' id? memtype ')'
2176+
// | '(' 'global' id? globaltype ')'
2177+
// | '(' 'tag' id? typeuse ')'
2178+
template<typename Ctx> MaybeResult<> import_(Ctx& ctx) {
2179+
auto pos = ctx.in.getPos();
2180+
2181+
if (!ctx.in.takeSExprStart("import"sv)) {
2182+
return {};
2183+
}
2184+
2185+
auto mod = ctx.in.takeName();
2186+
if (!mod) {
2187+
return ctx.in.err("expected import module name");
2188+
}
2189+
2190+
auto nm = ctx.in.takeName();
2191+
if (!nm) {
2192+
return ctx.in.err("expected import name");
2193+
}
2194+
ImportNames names{*mod, *nm};
2195+
2196+
if (ctx.in.takeSExprStart("func"sv)) {
2197+
auto name = ctx.in.takeID();
2198+
auto type = typeuse(ctx);
2199+
CHECK_ERR(type);
2200+
CHECK_ERR(
2201+
ctx.addFunc(name ? *name : Name{}, {}, &names, *type, std::nullopt, pos));
2202+
} else if (ctx.in.takeSExprStart("table"sv)) {
2203+
auto name = ctx.in.takeID();
2204+
auto type = tabletype(ctx);
2205+
CHECK_ERR(type);
2206+
CHECK_ERR(ctx.addTable(name ? *name : Name{}, {}, &names, *type, pos));
2207+
} else if (ctx.in.takeSExprStart("memory"sv)) {
2208+
auto name = ctx.in.takeID();
2209+
auto type = memtype(ctx);
2210+
CHECK_ERR(type);
2211+
CHECK_ERR(ctx.addMemory(name ? *name : Name{}, {}, &names, *type, pos));
2212+
} else if (ctx.in.takeSExprStart("global"sv)) {
2213+
auto name = ctx.in.takeID();
2214+
auto type = globaltype(ctx);
2215+
CHECK_ERR(type);
2216+
CHECK_ERR(ctx.addGlobal(
2217+
name ? *name : Name{}, {}, &names, *type, std::nullopt, pos));
2218+
} else if (ctx.in.takeSExprStart("tag"sv)) {
2219+
auto name = ctx.in.takeID();
2220+
auto type = typeuse(ctx);
2221+
CHECK_ERR(type);
2222+
CHECK_ERR(ctx.addTag(name ? *name : Name{}, {}, &names, *type, pos));
2223+
} else {
2224+
return ctx.in.err("expected import description");
2225+
}
2226+
2227+
if (!ctx.in.takeRParen()) {
2228+
return ctx.in.err("expected end of import description");
2229+
}
2230+
if (!ctx.in.takeRParen()) {
2231+
return ctx.in.err("expected end of import");
2232+
}
2233+
2234+
return Ok{};
2235+
}
2236+
21712237
// func ::= '(' 'func' id? ('(' 'export' name ')')*
21722238
// x,I:typeuse t*:vec(local) (in:instr)* ')'
21732239
// | '(' 'func' id? ('(' 'export' name ')')*
@@ -2651,6 +2717,10 @@ template<typename Ctx> MaybeResult<> modulefield(Ctx& ctx) {
26512717
CHECK_ERR(res);
26522718
return Ok{};
26532719
}
2720+
if (auto res = import_(ctx)) {
2721+
CHECK_ERR(res);
2722+
return Ok{};
2723+
}
26542724
if (auto res = func(ctx)) {
26552725
CHECK_ERR(res);
26562726
return Ok{};

src/parser/wat-parser.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ Result<> parseDefs(Ctx& ctx,
8080
for (auto& def : defs) {
8181
ctx.index = def.index;
8282
WithPosition with(ctx, def.pos);
83-
auto parsed = parser(ctx);
84-
CHECK_ERR(parsed);
85-
assert(parsed);
83+
if (auto parsed = parser(ctx)) {
84+
CHECK_ERR(parsed);
85+
} else {
86+
auto im = import_(ctx);
87+
assert(im);
88+
CHECK_ERR(im);
89+
}
8690
}
8791
return Ok{};
8892
}
@@ -174,9 +178,13 @@ Result<> parseModule(Module& wasm, std::string_view input) {
174178
ctx.index = i;
175179
CHECK_ERR(ctx.visitFunctionStart(wasm.functions[i].get()));
176180
WithPosition with(ctx, decls.funcDefs[i].pos);
177-
auto parsed = func(ctx);
178-
CHECK_ERR(parsed);
179-
assert(parsed);
181+
if (auto parsed = func(ctx)) {
182+
CHECK_ERR(parsed);
183+
} else {
184+
auto im = import_(ctx);
185+
assert(im);
186+
CHECK_ERR(im);
187+
}
180188
}
181189

182190
// Parse exports.

0 commit comments

Comments
 (0)