summaryrefslogtreecommitdiff
path: root/src/parser/parsers.h
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-05-17 17:49:45 -0700
committerGitHub <noreply@github.com>2024-05-17 17:49:45 -0700
commit921644ca65afbafb84fb82d58dacc4a028e2d720 (patch)
tree9253fbcf3f1dd9930dd1b9bc9f545234399b918e /src/parser/parsers.h
parent369cddfb44ddbada2ef7742a9ebef54727d12dd5 (diff)
downloadbinaryen-921644ca65afbafb84fb82d58dacc4a028e2d720.tar.gz
binaryen-921644ca65afbafb84fb82d58dacc4a028e2d720.tar.bz2
binaryen-921644ca65afbafb84fb82d58dacc4a028e2d720.zip
Rewrite wasm-shell to use new wast parser (#6601)
Use the new wast parser to parse a full script up front, then traverse the parsed script data structure and execute the commands. wasm-shell had previously used the new wat parser for top-level modules, but it now uses the new parser for module assertions as well. Fix various bugs this uncovered. After this change, wasm-shell supports all the assertions used in the upstream spec tests (although not new kinds of assertions introduced in any proposals). Uncomment various `assert_exhaustion` tests that we can now execute. Other kinds of assertions remain commented out in our tests: wasm-shell now supports `assert_unlinkable`, but the interpreter does not eagerly check for the existence of imports, so those tests do not pass. Tests that check for NaNs also remain commented out because they do not yet use the standard syntax that wasm-shell now supports for canonical and arithmetic NaN results, and our interpreter would not pass all of those tests even if they did use the standard syntax.
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r--src/parser/parsers.h22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 88600fec3..5900deb27 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -30,7 +30,8 @@ template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::RefTypeT> reftype(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::TypeT> tupletype(Ctx&);
template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx&);
-template<typename Ctx> MaybeResult<typename Ctx::ParamsT> params(Ctx&);
+template<typename Ctx>
+MaybeResult<typename Ctx::ParamsT> params(Ctx&, bool allowNames = true);
template<typename Ctx> MaybeResult<typename Ctx::ResultsT> results(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::SignatureT> functype(Ctx&);
template<typename Ctx> Result<typename Ctx::FieldT> storagetype(Ctx&);
@@ -325,7 +326,8 @@ MaybeResult<typename Ctx::LabelIdxT> maybeLabelidx(Ctx&,
template<typename Ctx>
Result<typename Ctx::LabelIdxT> labelidx(Ctx&, bool inDelegate = false);
template<typename Ctx> Result<typename Ctx::TagIdxT> tagidx(Ctx&);
-template<typename Ctx> Result<typename Ctx::TypeUseT> typeuse(Ctx&);
+template<typename Ctx>
+Result<typename Ctx::TypeUseT> typeuse(Ctx&, bool allowNames = true);
MaybeResult<ImportNames> inlineImport(Lexer&);
Result<std::vector<Name>> inlineExports(Lexer&);
template<typename Ctx> Result<> strtype(Ctx&);
@@ -561,13 +563,18 @@ template<typename Ctx> Result<typename Ctx::TypeT> valtype(Ctx& ctx) {
// param ::= '(' 'param id? t:valtype ')' => [t]
// | '(' 'param t*:valtype* ')' => [t*]
// params ::= param*
-template<typename Ctx> MaybeResult<typename Ctx::ParamsT> params(Ctx& ctx) {
+template<typename Ctx>
+MaybeResult<typename Ctx::ParamsT> params(Ctx& ctx, bool allowNames) {
bool hasAny = false;
auto res = ctx.makeParams();
while (ctx.in.takeSExprStart("param"sv)) {
hasAny = true;
+ auto pos = ctx.in.getPos();
if (auto id = ctx.in.takeID()) {
// Single named param
+ if (!allowNames) {
+ return ctx.in.err(pos, "unexpected named parameter");
+ }
auto type = valtype(ctx);
CHECK_ERR(type);
if (!ctx.in.takeRParen()) {
@@ -1065,7 +1072,7 @@ template<typename Ctx> Result<typename Ctx::BlockTypeT> blocktype(Ctx& ctx) {
// We either had no results or multiple results. Reset and parse again as a
// type use.
ctx.in = initialLexer;
- auto use = typeuse(ctx);
+ auto use = typeuse(ctx, false);
CHECK_ERR(use);
auto type = ctx.getBlockTypeFromTypeUse(pos, *use);
@@ -1935,7 +1942,7 @@ Result<> makeCallIndirect(Ctx& ctx,
bool isReturn) {
auto table = maybeTableidx(ctx);
CHECK_ERR(table);
- auto type = typeuse(ctx);
+ auto type = typeuse(ctx, false);
CHECK_ERR(type);
return ctx.makeCallIndirect(
pos, annotations, table.getPtr(), *type, isReturn);
@@ -2669,7 +2676,8 @@ template<typename Ctx> Result<typename Ctx::TagIdxT> tagidx(Ctx& ctx) {
// (if typedefs[x] = [t1*] -> [t2*])
// | ((t1,IDs):param)* (t2:result)* => x, IDs
// (if x is minimum s.t. typedefs[x] = [t1*] -> [t2*])
-template<typename Ctx> Result<typename Ctx::TypeUseT> typeuse(Ctx& ctx) {
+template<typename Ctx>
+Result<typename Ctx::TypeUseT> typeuse(Ctx& ctx, bool allowNames) {
auto pos = ctx.in.getPos();
std::optional<typename Ctx::HeapTypeT> type;
if (ctx.in.takeSExprStart("type"sv)) {
@@ -2683,7 +2691,7 @@ template<typename Ctx> Result<typename Ctx::TypeUseT> typeuse(Ctx& ctx) {
type = *x;
}
- auto namedParams = params(ctx);
+ auto namedParams = params(ctx, allowNames);
CHECK_ERR(namedParams);
auto resultTypes = results(ctx);