diff options
author | Thomas Lively <tlively@google.com> | 2023-09-21 13:46:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-21 13:46:51 -0700 |
commit | 2c09a60ecbb0ba0276982204d8788b4343356417 (patch) | |
tree | 459f657111276a48fb9ee40520203c764c8a464d /src/parser/parsers.h | |
parent | d491136eeb94b748225be50bdcc86c74cdbd154e (diff) | |
download | binaryen-2c09a60ecbb0ba0276982204d8788b4343356417.tar.gz binaryen-2c09a60ecbb0ba0276982204d8788b4343356417.tar.bz2 binaryen-2c09a60ecbb0ba0276982204d8788b4343356417.zip |
[NFC][Parser] Simplify instruction handling (#5964)
The new wat parser previously returned InstrT types when parsing individual
instructions and collected InstrsT types when parsing sequences of instructions.
However, instructions were always actually tracked in the internal state of the
parsing context, so these types never held any interesting or necessary data.
Simplify the parser by removing these types and leaning into the pattern that
the parser context will keep track of parsed instructions.
This allows for a much cleaner separation between the `instrs` and
`foldedinstrs` parser functions.
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r-- | src/parser/parsers.h | 736 |
1 files changed, 284 insertions, 452 deletions
diff --git a/src/parser/parsers.h b/src/parser/parsers.h index d162de58c..f36f5ccfb 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -42,175 +42,128 @@ template<typename Ctx> Result<typename Ctx::MemTypeT> memtype(Ctx&); template<typename Ctx> Result<typename Ctx::GlobalTypeT> globaltype(Ctx&); // Instructions -template<typename Ctx> MaybeResult<typename Ctx::InstrT> foldedBlockinstr(Ctx&); -template<typename Ctx> -MaybeResult<typename Ctx::InstrT> unfoldedBlockinstr(Ctx&); -template<typename Ctx> MaybeResult<typename Ctx::InstrT> blockinstr(Ctx&); -template<typename Ctx> MaybeResult<typename Ctx::InstrT> plaininstr(Ctx&); -template<typename Ctx> MaybeResult<typename Ctx::InstrT> instr(Ctx&); -template<typename Ctx> -Result<typename Ctx::InstrsT> instrs(Ctx&, bool requireFolded = false); -template<typename Ctx> Result<typename Ctx::InstrsT> foldedinstrs(Ctx&); +template<typename Ctx> MaybeResult<> foldedBlockinstr(Ctx&); +template<typename Ctx> MaybeResult<> unfoldedBlockinstr(Ctx&); +template<typename Ctx> MaybeResult<> blockinstr(Ctx&); +template<typename Ctx> MaybeResult<> plaininstr(Ctx&); +template<typename Ctx> MaybeResult<> instr(Ctx&); +template<typename Ctx> Result<> foldedinstrs(Ctx&); +template<typename Ctx> Result<> instrs(Ctx&); template<typename Ctx> Result<typename Ctx::ExprT> expr(Ctx&); template<typename Ctx> Result<typename Ctx::MemargT> memarg(Ctx&, uint32_t); template<typename Ctx> Result<typename Ctx::BlockTypeT> blocktype(Ctx&); -template<typename Ctx> MaybeResult<typename Ctx::InstrT> block(Ctx&, bool); -template<typename Ctx> MaybeResult<typename Ctx::InstrT> ifelse(Ctx&, bool); -template<typename Ctx> -Result<typename Ctx::InstrT> makeUnreachable(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeNop(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeBinary(Ctx&, Index, BinaryOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> makeUnary(Ctx&, Index, UnaryOp op); -template<typename Ctx> Result<typename Ctx::InstrT> makeSelect(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeDrop(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeMemorySize(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeMemoryGrow(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeLocalGet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeLocalTee(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeLocalSet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeGlobalGet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeGlobalSet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeBlock(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeThenOrElse(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeConst(Ctx&, Index, Type type); -template<typename Ctx> -Result<typename Ctx::InstrT> +template<typename Ctx> MaybeResult<> block(Ctx&, bool); +template<typename Ctx> MaybeResult<> ifelse(Ctx&, bool); +template<typename Ctx> Result<> makeUnreachable(Ctx&, Index); +template<typename Ctx> Result<> makeNop(Ctx&, Index); +template<typename Ctx> Result<> makeBinary(Ctx&, Index, BinaryOp op); +template<typename Ctx> Result<> makeUnary(Ctx&, Index, UnaryOp op); +template<typename Ctx> Result<> makeSelect(Ctx&, Index); +template<typename Ctx> Result<> makeDrop(Ctx&, Index); +template<typename Ctx> Result<> makeMemorySize(Ctx&, Index); +template<typename Ctx> Result<> makeMemoryGrow(Ctx&, Index); +template<typename Ctx> Result<> makeLocalGet(Ctx&, Index); +template<typename Ctx> Result<> makeLocalTee(Ctx&, Index); +template<typename Ctx> Result<> makeLocalSet(Ctx&, Index); +template<typename Ctx> Result<> makeGlobalGet(Ctx&, Index); +template<typename Ctx> Result<> makeGlobalSet(Ctx&, Index); +template<typename Ctx> Result<> makeBlock(Ctx&, Index); +template<typename Ctx> Result<> makeThenOrElse(Ctx&, Index); +template<typename Ctx> Result<> makeConst(Ctx&, Index, Type type); +template<typename Ctx> +Result<> makeLoad(Ctx&, Index, Type type, bool signed_, int bytes, bool isAtomic); template<typename Ctx> -Result<typename Ctx::InstrT> -makeStore(Ctx&, Index, Type type, int bytes, bool isAtomic); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeAtomicRMW(Ctx&, Index, AtomicRMWOp op, Type type, uint8_t bytes); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeAtomicCmpxchg(Ctx&, Index, Type type, uint8_t bytes); -template<typename Ctx> -Result<typename Ctx::InstrT> makeAtomicWait(Ctx&, Index, Type type); -template<typename Ctx> -Result<typename Ctx::InstrT> makeAtomicNotify(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeAtomicFence(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDExtract(Ctx&, Index, SIMDExtractOp op, size_t lanes); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDReplace(Ctx&, Index, SIMDReplaceOp op, size_t lanes); -template<typename Ctx> -Result<typename Ctx::InstrT> makeSIMDShuffle(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeSIMDTernary(Ctx&, Index, SIMDTernaryOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> makeSIMDShift(Ctx&, Index, SIMDShiftOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDLoad(Ctx&, Index, SIMDLoadOp op, int bytes); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDLoadStoreLane(Ctx&, Index, SIMDLoadStoreLaneOp op, int bytes); -template<typename Ctx> Result<typename Ctx::InstrT> makeMemoryInit(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeDataDrop(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeMemoryCopy(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeMemoryFill(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makePop(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeIf(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeMaybeBlock(Ctx&, Index, size_t i, Type type); -template<typename Ctx> Result<typename Ctx::InstrT> makeLoop(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeCall(Ctx&, Index, bool isReturn); -template<typename Ctx> -Result<typename Ctx::InstrT> makeCallIndirect(Ctx&, Index, bool isReturn); -template<typename Ctx> Result<typename Ctx::InstrT> makeBreak(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeBreakTable(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeReturn(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefNull(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefIsNull(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefFunc(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefEq(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTableGet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTableSet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTableSize(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTableGrow(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTableFill(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTry(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeTryOrCatchBody(Ctx&, Index, Type type, bool isTry); -template<typename Ctx> Result<typename Ctx::InstrT> makeThrow(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeRethrow(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeTupleMake(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeTupleExtract(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeCallRef(Ctx&, Index, bool isReturn); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefI31(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeI31Get(Ctx&, Index, bool signed_); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefTest(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeRefCast(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeBrOnNull(Ctx&, Index, bool onFail = false); -template<typename Ctx> -Result<typename Ctx::InstrT> makeBrOnCast(Ctx&, Index, bool onFail = false); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStructNew(Ctx&, Index, bool default_); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStructGet(Ctx&, Index, bool signed_ = false); -template<typename Ctx> Result<typename Ctx::InstrT> makeStructSet(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNew(Ctx&, Index, bool default_); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNewData(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNewElem(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNewFixed(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayGet(Ctx&, Index, bool signed_ = false); -template<typename Ctx> Result<typename Ctx::InstrT> makeArraySet(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeArrayLen(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeArrayCopy(Ctx&, Index); -template<typename Ctx> Result<typename Ctx::InstrT> makeArrayFill(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayInitData(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayInitElem(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefAs(Ctx&, Index, RefAsOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringNew(Ctx&, Index, StringNewOp op, bool try_); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringConst(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringMeasure(Ctx&, Index, StringMeasureOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringEncode(Ctx&, Index, StringEncodeOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringConcat(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringEq(Ctx&, Index, StringEqOp); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringAs(Ctx&, Index, StringAsOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringWTF8Advance(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringWTF16Get(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringIterNext(Ctx&, Index); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringIterMove(Ctx&, Index, StringIterMoveOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringSliceWTF(Ctx&, Index, StringSliceWTFOp op); -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringSliceIter(Ctx&, Index); +Result<> makeStore(Ctx&, Index, Type type, int bytes, bool isAtomic); +template<typename Ctx> +Result<> makeAtomicRMW(Ctx&, Index, AtomicRMWOp op, Type type, uint8_t bytes); +template<typename Ctx> +Result<> makeAtomicCmpxchg(Ctx&, Index, Type type, uint8_t bytes); +template<typename Ctx> Result<> makeAtomicWait(Ctx&, Index, Type type); +template<typename Ctx> Result<> makeAtomicNotify(Ctx&, Index); +template<typename Ctx> Result<> makeAtomicFence(Ctx&, Index); +template<typename Ctx> +Result<> makeSIMDExtract(Ctx&, Index, SIMDExtractOp op, size_t lanes); +template<typename Ctx> +Result<> makeSIMDReplace(Ctx&, Index, SIMDReplaceOp op, size_t lanes); +template<typename Ctx> Result<> makeSIMDShuffle(Ctx&, Index); +template<typename Ctx> Result<> makeSIMDTernary(Ctx&, Index, SIMDTernaryOp op); +template<typename Ctx> Result<> makeSIMDShift(Ctx&, Index, SIMDShiftOp op); +template<typename Ctx> +Result<> makeSIMDLoad(Ctx&, Index, SIMDLoadOp op, int bytes); +template<typename Ctx> +Result<> makeSIMDLoadStoreLane(Ctx&, Index, SIMDLoadStoreLaneOp op, int bytes); +template<typename Ctx> Result<> makeMemoryInit(Ctx&, Index); +template<typename Ctx> Result<> makeDataDrop(Ctx&, Index); +template<typename Ctx> Result<> makeMemoryCopy(Ctx&, Index); +template<typename Ctx> Result<> makeMemoryFill(Ctx&, Index); +template<typename Ctx> Result<> makePop(Ctx&, Index); +template<typename Ctx> Result<> makeIf(Ctx&, Index); +template<typename Ctx> +Result<> makeMaybeBlock(Ctx&, Index, size_t i, Type type); +template<typename Ctx> Result<> makeLoop(Ctx&, Index); +template<typename Ctx> Result<> makeCall(Ctx&, Index, bool isReturn); +template<typename Ctx> Result<> makeCallIndirect(Ctx&, Index, bool isReturn); +template<typename Ctx> Result<> makeBreak(Ctx&, Index); +template<typename Ctx> Result<> makeBreakTable(Ctx&, Index); +template<typename Ctx> Result<> makeReturn(Ctx&, Index); +template<typename Ctx> Result<> makeRefNull(Ctx&, Index); +template<typename Ctx> Result<> makeRefIsNull(Ctx&, Index); +template<typename Ctx> Result<> makeRefFunc(Ctx&, Index); +template<typename Ctx> Result<> makeRefEq(Ctx&, Index); +template<typename Ctx> Result<> makeTableGet(Ctx&, Index); +template<typename Ctx> Result<> makeTableSet(Ctx&, Index); +template<typename Ctx> Result<> makeTableSize(Ctx&, Index); +template<typename Ctx> Result<> makeTableGrow(Ctx&, Index); +template<typename Ctx> Result<> makeTableFill(Ctx&, Index); +template<typename Ctx> Result<> makeTry(Ctx&, Index); +template<typename Ctx> +Result<> makeTryOrCatchBody(Ctx&, Index, Type type, bool isTry); +template<typename Ctx> Result<> makeThrow(Ctx&, Index); +template<typename Ctx> Result<> makeRethrow(Ctx&, Index); +template<typename Ctx> Result<> makeTupleMake(Ctx&, Index); +template<typename Ctx> Result<> makeTupleExtract(Ctx&, Index); +template<typename Ctx> Result<> makeCallRef(Ctx&, Index, bool isReturn); +template<typename Ctx> Result<> makeRefI31(Ctx&, Index); +template<typename Ctx> Result<> makeI31Get(Ctx&, Index, bool signed_); +template<typename Ctx> Result<> makeRefTest(Ctx&, Index); +template<typename Ctx> Result<> makeRefCast(Ctx&, Index); +template<typename Ctx> Result<> makeBrOnNull(Ctx&, Index, bool onFail = false); +template<typename Ctx> Result<> makeBrOnCast(Ctx&, Index, bool onFail = false); +template<typename Ctx> Result<> makeStructNew(Ctx&, Index, bool default_); +template<typename Ctx> +Result<> makeStructGet(Ctx&, Index, bool signed_ = false); +template<typename Ctx> Result<> makeStructSet(Ctx&, Index); +template<typename Ctx> Result<> makeArrayNew(Ctx&, Index, bool default_); +template<typename Ctx> Result<> makeArrayNewData(Ctx&, Index); +template<typename Ctx> Result<> makeArrayNewElem(Ctx&, Index); +template<typename Ctx> Result<> makeArrayNewFixed(Ctx&, Index); +template<typename Ctx> Result<> makeArrayGet(Ctx&, Index, bool signed_ = false); +template<typename Ctx> Result<> makeArraySet(Ctx&, Index); +template<typename Ctx> Result<> makeArrayLen(Ctx&, Index); +template<typename Ctx> Result<> makeArrayCopy(Ctx&, Index); +template<typename Ctx> Result<> makeArrayFill(Ctx&, Index); +template<typename Ctx> Result<> makeArrayInitData(Ctx&, Index); +template<typename Ctx> Result<> makeArrayInitElem(Ctx&, Index); +template<typename Ctx> Result<> makeRefAs(Ctx&, Index, RefAsOp op); +template<typename Ctx> +Result<> makeStringNew(Ctx&, Index, StringNewOp op, bool try_); +template<typename Ctx> Result<> makeStringConst(Ctx&, Index); +template<typename Ctx> +Result<> makeStringMeasure(Ctx&, Index, StringMeasureOp op); +template<typename Ctx> +Result<> makeStringEncode(Ctx&, Index, StringEncodeOp op); +template<typename Ctx> Result<> makeStringConcat(Ctx&, Index); +template<typename Ctx> Result<> makeStringEq(Ctx&, Index, StringEqOp); +template<typename Ctx> Result<> makeStringAs(Ctx&, Index, StringAsOp op); +template<typename Ctx> Result<> makeStringWTF8Advance(Ctx&, Index); +template<typename Ctx> Result<> makeStringWTF16Get(Ctx&, Index); +template<typename Ctx> Result<> makeStringIterNext(Ctx&, Index); +template<typename Ctx> +Result<> makeStringIterMove(Ctx&, Index, StringIterMoveOp op); +template<typename Ctx> +Result<> makeStringSliceWTF(Ctx&, Index, StringSliceWTFOp op); +template<typename Ctx> Result<> makeStringSliceIter(Ctx&, Index); // Modules template<typename Ctx> MaybeResult<Index> maybeTypeidx(Ctx& ctx); @@ -592,8 +545,7 @@ template<typename Ctx> Result<typename Ctx::GlobalTypeT> globaltype(Ctx& ctx) { // ============ // blockinstr ::= block | loop | if-else | try-catch -template<typename Ctx> -MaybeResult<typename Ctx::InstrT> foldedBlockinstr(Ctx& ctx) { +template<typename Ctx> MaybeResult<> foldedBlockinstr(Ctx& ctx) { if (auto i = block(ctx, true)) { return i; } @@ -604,8 +556,7 @@ MaybeResult<typename Ctx::InstrT> foldedBlockinstr(Ctx& ctx) { return {}; } -template<typename Ctx> -MaybeResult<typename Ctx::InstrT> unfoldedBlockinstr(Ctx& ctx) { +template<typename Ctx> MaybeResult<> unfoldedBlockinstr(Ctx& ctx) { if (auto i = block(ctx, false)) { return i; } @@ -616,7 +567,7 @@ MaybeResult<typename Ctx::InstrT> unfoldedBlockinstr(Ctx& ctx) { return {}; } -template<typename Ctx> MaybeResult<typename Ctx::InstrT> blockinstr(Ctx& ctx) { +template<typename Ctx> MaybeResult<> blockinstr(Ctx& ctx) { if (auto i = foldedBlockinstr(ctx)) { return i; } @@ -627,7 +578,7 @@ template<typename Ctx> MaybeResult<typename Ctx::InstrT> blockinstr(Ctx& ctx) { } // plaininstr ::= ... all plain instructions ... -template<typename Ctx> MaybeResult<typename Ctx::InstrT> plaininstr(Ctx& ctx) { +template<typename Ctx> MaybeResult<> plaininstr(Ctx& ctx) { auto pos = ctx.in.getPos(); auto keyword = ctx.in.takeKeyword(); if (!keyword) { @@ -640,7 +591,7 @@ template<typename Ctx> MaybeResult<typename Ctx::InstrT> plaininstr(Ctx& ctx) { } // instr ::= plaininstr | blockinstr -template<typename Ctx> MaybeResult<typename Ctx::InstrT> instr(Ctx& ctx) { +template<typename Ctx> MaybeResult<> instr(Ctx& ctx) { // Check for valid strings that are not instructions. if (auto tok = ctx.in.peek()) { if (auto keyword = tok->getKeyword()) { @@ -659,109 +610,84 @@ template<typename Ctx> MaybeResult<typename Ctx::InstrT> instr(Ctx& ctx) { return {}; } -template<typename Ctx> -Result<typename Ctx::InstrsT> instrs(Ctx& ctx, bool requireFolded) { - auto insts = ctx.makeInstrs(); - bool parsedFolded = false; +template<typename Ctx> Result<> foldedinstrs(Ctx& ctx) { + if (auto blockinst = foldedBlockinstr(ctx)) { + CHECK_ERR(blockinst); + return Ok{}; + } + // Parse an arbitrary number of folded instructions. + if (ctx.in.takeLParen()) { + // A stack of (start, end) position pairs defining the positions of + // instructions that need to be parsed after their folded children. + std::vector<std::pair<Index, std::optional<Index>>> foldedInstrs; + + // Begin a folded instruction. Push its start position and a placeholder + // end position. + foldedInstrs.push_back({ctx.in.getPos(), {}}); + while (!foldedInstrs.empty()) { + // Consume everything up to the next paren. This span will be parsed as + // an instruction later after its folded children have been parsed. + if (!ctx.in.takeUntilParen()) { + return ctx.in.err(foldedInstrs.back().first, + "unterminated folded instruction"); + } - while (true) { - if (auto blockinst = foldedBlockinstr(ctx)) { - CHECK_ERR(blockinst); - ctx.appendInstr(insts, *blockinst); - parsedFolded = true; - if (requireFolded) { - // Do not continue to parse another sibling folded instruction. - break; + if (!foldedInstrs.back().second) { + // The folded instruction we just started should end here. + foldedInstrs.back().second = ctx.in.getPos(); } - continue; - } - // Parse an arbitrary number of folded instructions. - if (ctx.in.takeLParen()) { - // A stack of (start, end) position pairs defining the positions of - // instructions that need to be parsed after their folded children. - std::vector<std::pair<Index, std::optional<Index>>> foldedInstrs; - - // Begin a folded instruction. Push its start position and a placeholder - // end position. - foldedInstrs.push_back({ctx.in.getPos(), {}}); - while (!foldedInstrs.empty()) { - // Consume everything up to the next paren. This span will be parsed as - // an instruction later after its folded children have been parsed. - if (!ctx.in.takeUntilParen()) { - return ctx.in.err(foldedInstrs.back().first, - "unterminated folded instruction"); - } - if (!foldedInstrs.back().second) { - // The folded instruction we just started should end here. - foldedInstrs.back().second = ctx.in.getPos(); + // We have either the start of a new folded child or the end of the last + // one. + if (auto blockinst = foldedBlockinstr(ctx)) { + CHECK_ERR(blockinst); + } else if (ctx.in.takeLParen()) { + foldedInstrs.push_back({ctx.in.getPos(), {}}); + } else if (ctx.in.takeRParen()) { + auto [start, end] = foldedInstrs.back(); + assert(end && "Should have found end of instruction"); + foldedInstrs.pop_back(); + + WithPosition with(ctx, start); + if (auto inst = plaininstr(ctx)) { + CHECK_ERR(inst); + } else { + return ctx.in.err(start, "expected folded instruction"); } - // We have either the start of a new folded child or the end of the last - // one. - if (auto blockinst = foldedBlockinstr(ctx)) { - CHECK_ERR(blockinst); - ctx.appendInstr(insts, *blockinst); - parsedFolded = true; - } else if (ctx.in.takeLParen()) { - foldedInstrs.push_back({ctx.in.getPos(), {}}); - } else if (ctx.in.takeRParen()) { - auto [start, end] = foldedInstrs.back(); - assert(end && "Should have found end of instruction"); - foldedInstrs.pop_back(); - - WithPosition with(ctx, start); - if (auto inst = plaininstr(ctx)) { - CHECK_ERR(inst); - ctx.appendInstr(insts, *inst); - parsedFolded = true; - } else { - return ctx.in.err(start, "expected folded instruction"); - } - - if (ctx.in.getPos() != *end) { - return ctx.in.err("expected end of instruction"); - } - } else { - WASM_UNREACHABLE("expected paren"); + if (ctx.in.getPos() != *end) { + return ctx.in.err("expected end of instruction"); } + } else { + WASM_UNREACHABLE("expected paren"); } - if (requireFolded) { - // Do not continue to parse another sibling folded instruction. - break; - } - continue; } + return Ok{}; + } + return ctx.in.err("expected folded instruction"); +} - if (requireFolded) { - // Do not continue to parse a non-folded instruction. - break; +template<typename Ctx> Result<> instrs(Ctx& ctx) { + while (true) { + // Try to parse a folded instruction tree. + if (!foldedinstrs(ctx).getErr()) { + continue; } - // A non-folded instruction. + // Otherwise parse a non-folded instruction. if (auto inst = instr(ctx)) { CHECK_ERR(inst); - ctx.appendInstr(insts, *inst); } else { break; } } - if (requireFolded && !parsedFolded) { - return ctx.in.err("expected folded instructions"); - } - - return ctx.finishInstrs(insts); -} - -template<typename Ctx> Result<typename Ctx::InstrsT> foldedinstrs(Ctx& ctx) { - return instrs(ctx, true); + return Ok{}; } template<typename Ctx> Result<typename Ctx::ExprT> expr(Ctx& ctx) { - auto insts = instrs(ctx); - CHECK_ERR(insts); - return ctx.makeExpr(*insts); + CHECK_ERR(instrs(ctx)); + return ctx.makeExpr(); } // memarg_n ::= o:offset a:align_n @@ -804,8 +730,7 @@ template<typename Ctx> Result<typename Ctx::BlockTypeT> blocktype(Ctx& ctx) { // block ::= 'block' label blocktype instr* 'end' id? if id = {} or id = label // | '(' 'block' label blocktype instr* ')' -template<typename Ctx> -MaybeResult<typename Ctx::InstrT> block(Ctx& ctx, bool folded) { +template<typename Ctx> MaybeResult<> block(Ctx& ctx, bool folded) { auto pos = ctx.in.getPos(); if (folded) { @@ -825,8 +750,7 @@ MaybeResult<typename Ctx::InstrT> block(Ctx& ctx, bool folded) { ctx.makeBlock(pos, label, *type); - auto insts = instrs(ctx); - CHECK_ERR(insts); + CHECK_ERR(instrs(ctx)); if (folded) { if (!ctx.in.takeRParen()) { @@ -842,14 +766,13 @@ MaybeResult<typename Ctx::InstrT> block(Ctx& ctx, bool folded) { } } - return ctx.visitEnd(pos, std::move(*insts)); + return ctx.visitEnd(pos); } // if ::= 'if' label blocktype instr1* ('else' id1? instr2*)? 'end' id2? // | '(' 'if' label blocktype instr* '(' 'then' instr1* ')' // ('(' 'else' instr2* ')')? ')' -template<typename Ctx> -MaybeResult<typename Ctx::InstrT> ifelse(Ctx& ctx, bool folded) { +template<typename Ctx> MaybeResult<> ifelse(Ctx& ctx, bool folded) { auto pos = ctx.in.getPos(); if (folded) { @@ -877,8 +800,7 @@ MaybeResult<typename Ctx::InstrT> ifelse(Ctx& ctx, bool folded) { return ctx.in.err("expected 'then' before if instructions"); } - auto insts = instrs(ctx); - CHECK_ERR(insts); + CHECK_ERR(instrs(ctx)); if (folded && !ctx.in.takeRParen()) { return ctx.in.err("expected ')' at end of then block"); @@ -893,8 +815,7 @@ MaybeResult<typename Ctx::InstrT> ifelse(Ctx& ctx, bool folded) { ctx.visitElse(pos); - auto elseInsts = instrs(ctx); - CHECK_ERR(elseInsts); + CHECK_ERR(instrs(ctx)); if (folded && !ctx.in.takeRParen()) { return ctx.in.err("expected ')' at end of else block"); @@ -916,97 +837,82 @@ MaybeResult<typename Ctx::InstrT> ifelse(Ctx& ctx, bool folded) { return ctx.in.err("end label does not match if label"); } - return ctx.visitEnd(pos, std::move(*insts)); + return ctx.visitEnd(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeUnreachable(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeUnreachable(Ctx& ctx, Index pos) { return ctx.makeUnreachable(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeNop(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeNop(Ctx& ctx, Index pos) { return ctx.makeNop(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeBinary(Ctx& ctx, Index pos, BinaryOp op) { +template<typename Ctx> Result<> makeBinary(Ctx& ctx, Index pos, BinaryOp op) { return ctx.makeBinary(pos, op); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeUnary(Ctx& ctx, Index pos, UnaryOp op) { +template<typename Ctx> Result<> makeUnary(Ctx& ctx, Index pos, UnaryOp op) { return ctx.makeUnary(pos, op); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeSelect(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeSelect(Ctx& ctx, Index pos) { auto res = results(ctx); CHECK_ERR(res); return ctx.makeSelect(pos, res.getPtr()); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeDrop(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeDrop(Ctx& ctx, Index pos) { return ctx.makeDrop(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeMemorySize(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeMemorySize(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); return ctx.makeMemorySize(pos, mem.getPtr()); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeMemoryGrow(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeMemoryGrow(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); return ctx.makeMemoryGrow(pos, mem.getPtr()); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeLocalGet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeLocalGet(Ctx& ctx, Index pos) { auto local = localidx(ctx); CHECK_ERR(local); return ctx.makeLocalGet(pos, *local); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeLocalTee(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeLocalTee(Ctx& ctx, Index pos) { auto local = localidx(ctx); CHECK_ERR(local); return ctx.makeLocalTee(pos, *local); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeLocalSet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeLocalSet(Ctx& ctx, Index pos) { auto local = localidx(ctx); CHECK_ERR(local); return ctx.makeLocalSet(pos, *local); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeGlobalGet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeGlobalGet(Ctx& ctx, Index pos) { auto global = globalidx(ctx); CHECK_ERR(global); return ctx.makeGlobalGet(pos, *global); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeGlobalSet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeGlobalSet(Ctx& ctx, Index pos) { auto global = globalidx(ctx); CHECK_ERR(global); return ctx.makeGlobalSet(pos, *global); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeBlock(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeBlock(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeConst(Ctx& ctx, Index pos, Type type) { +template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { assert(type.isBasic()); switch (type.getBasic()) { case Type::i32: @@ -1039,7 +945,7 @@ Result<typename Ctx::InstrT> makeConst(Ctx& ctx, Index pos, Type type) { } template<typename Ctx> -Result<typename Ctx::InstrT> makeLoad( +Result<> makeLoad( Ctx& ctx, Index pos, Type type, bool signed_, int bytes, bool isAtomic) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); @@ -1049,8 +955,7 @@ Result<typename Ctx::InstrT> makeLoad( } template<typename Ctx> -Result<typename Ctx::InstrT> -makeStore(Ctx& ctx, Index pos, Type type, int bytes, bool isAtomic) { +Result<> makeStore(Ctx& ctx, Index pos, Type type, int bytes, bool isAtomic) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); @@ -1059,7 +964,7 @@ makeStore(Ctx& ctx, Index pos, Type type, int bytes, bool isAtomic) { } template<typename Ctx> -Result<typename Ctx::InstrT> +Result<> makeAtomicRMW(Ctx& ctx, Index pos, AtomicRMWOp op, Type type, uint8_t bytes) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); @@ -1069,8 +974,7 @@ makeAtomicRMW(Ctx& ctx, Index pos, AtomicRMWOp op, Type type, uint8_t bytes) { } template<typename Ctx> -Result<typename Ctx::InstrT> -makeAtomicCmpxchg(Ctx& ctx, Index pos, Type type, uint8_t bytes) { +Result<> makeAtomicCmpxchg(Ctx& ctx, Index pos, Type type, uint8_t bytes) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); @@ -1078,8 +982,7 @@ makeAtomicCmpxchg(Ctx& ctx, Index pos, Type type, uint8_t bytes) { return ctx.makeAtomicCmpxchg(pos, type, bytes, mem.getPtr(), *arg); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeAtomicWait(Ctx& ctx, Index pos, Type type) { +template<typename Ctx> Result<> makeAtomicWait(Ctx& ctx, Index pos, Type type) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, type == Type::i32 ? 4 : 8); @@ -1087,8 +990,7 @@ Result<typename Ctx::InstrT> makeAtomicWait(Ctx& ctx, Index pos, Type type) { return ctx.makeAtomicWait(pos, type, mem.getPtr(), *arg); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeAtomicNotify(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeAtomicNotify(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, 4); @@ -1096,14 +998,12 @@ Result<typename Ctx::InstrT> makeAtomicNotify(Ctx& ctx, Index pos) { return ctx.makeAtomicNotify(pos, mem.getPtr(), *arg); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeAtomicFence(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeAtomicFence(Ctx& ctx, Index pos) { return ctx.makeAtomicFence(pos); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDExtract(Ctx& ctx, Index pos, SIMDExtractOp op, size_t) { +Result<> makeSIMDExtract(Ctx& ctx, Index pos, SIMDExtractOp op, size_t) { auto lane = ctx.in.takeU8(); if (!lane) { return ctx.in.err("expected lane index"); @@ -1112,8 +1012,7 @@ makeSIMDExtract(Ctx& ctx, Index pos, SIMDExtractOp op, size_t) { } template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDReplace(Ctx& ctx, Index pos, SIMDReplaceOp op, size_t lanes) { +Result<> makeSIMDReplace(Ctx& ctx, Index pos, SIMDReplaceOp op, size_t lanes) { auto lane = ctx.in.takeU8(); if (!lane) { return ctx.in.err("expected lane index"); @@ -1121,8 +1020,7 @@ makeSIMDReplace(Ctx& ctx, Index pos, SIMDReplaceOp op, size_t lanes) { return ctx.makeSIMDReplace(pos, op, *lane); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeSIMDShuffle(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeSIMDShuffle(Ctx& ctx, Index pos) { std::array<uint8_t, 16> lanes; for (int i = 0; i < 16; ++i) { auto lane = ctx.in.takeU8(); @@ -1135,20 +1033,17 @@ Result<typename Ctx::InstrT> makeSIMDShuffle(Ctx& ctx, Index pos) { } template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDTernary(Ctx& ctx, Index pos, SIMDTernaryOp op) { +Result<> makeSIMDTernary(Ctx& ctx, Index pos, SIMDTernaryOp op) { return ctx.makeSIMDTernary(pos, op); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDShift(Ctx& ctx, Index pos, SIMDShiftOp op) { +Result<> makeSIMDShift(Ctx& ctx, Index pos, SIMDShiftOp op) { return ctx.makeSIMDShift(pos, op); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeSIMDLoad(Ctx& ctx, Index pos, SIMDLoadOp op, int bytes) { +Result<> makeSIMDLoad(Ctx& ctx, Index pos, SIMDLoadOp op, int bytes) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); @@ -1157,11 +1052,11 @@ makeSIMDLoad(Ctx& ctx, Index pos, SIMDLoadOp op, int bytes) { } template<typename Ctx> -Result<typename Ctx::InstrT> +Result<> makeSIMDLoadStoreLane(Ctx& ctx, Index pos, SIMDLoadStoreLaneOp op, int bytes) { auto reset = ctx.in.getPos(); - auto retry = [&]() -> Result<typename Ctx::InstrT> { + auto retry = [&]() -> Result<> { // We failed to parse. Maybe the lane index was accidentally parsed as the // optional memory index. Try again without parsing a memory index. WithPosition with(ctx, reset); @@ -1187,11 +1082,10 @@ makeSIMDLoadStoreLane(Ctx& ctx, Index pos, SIMDLoadStoreLaneOp op, int bytes) { return ctx.makeSIMDLoadStoreLane(pos, op, mem.getPtr(), *arg, *lane); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeMemoryInit(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeMemoryInit(Ctx& ctx, Index pos) { auto reset = ctx.in.getPos(); - auto retry = [&]() -> Result<typename Ctx::InstrT> { + auto retry = [&]() -> Result<> { // We failed to parse. Maybe the data index was accidentally parsed as the // optional memory index. Try again without parsing a memory index. WithPosition with(ctx, reset); @@ -1211,15 +1105,13 @@ Result<typename Ctx::InstrT> makeMemoryInit(Ctx& ctx, Index pos) { return ctx.makeMemoryInit(pos, mem.getPtr(), *data); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeDataDrop(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeDataDrop(Ctx& ctx, Index pos) { auto data = dataidx(ctx); CHECK_ERR(data); return ctx.makeDataDrop(pos, *data); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeMemoryCopy(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeMemoryCopy(Ctx& ctx, Index pos) { auto destMem = maybeMemidx(ctx); CHECK_ERR(destMem); std::optional<typename Ctx::MemoryIdxT> srcMem = std::nullopt; @@ -1231,175 +1123,144 @@ Result<typename Ctx::InstrT> makeMemoryCopy(Ctx& ctx, Index pos) { return ctx.makeMemoryCopy(pos, destMem.getPtr(), srcMem ? &*srcMem : nullptr); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeMemoryFill(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeMemoryFill(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); return ctx.makeMemoryFill(pos, mem.getPtr()); } -template<typename Ctx> -Result<typename Ctx::InstrT> makePop(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makePop(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeIf(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeIf(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeMaybeBlock(Ctx& ctx, Index pos, size_t i, Type type) { +Result<> makeMaybeBlock(Ctx& ctx, Index pos, size_t i, Type type) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeLoop(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeLoop(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeCall(Ctx& ctx, Index pos, bool isReturn) { +template<typename Ctx> Result<> makeCall(Ctx& ctx, Index pos, bool isReturn) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { +Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeBreak(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeBreak(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeBreakTable(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeBreakTable(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeReturn(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeReturn(Ctx& ctx, Index pos) { return ctx.makeReturn(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefNull(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefNull(Ctx& ctx, Index pos) { auto t = heaptype(ctx); CHECK_ERR(t); return ctx.makeRefNull(pos, *t); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefIsNull(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefIsNull(Ctx& ctx, Index pos) { return ctx.makeRefIsNull(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefFunc(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefFunc(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefEq(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefEq(Ctx& ctx, Index pos) { return ctx.makeRefEq(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTableGet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTableGet(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTableSet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTableSet(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTableSize(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTableSize(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTableGrow(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTableGrow(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTableFill(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTableFill(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTry(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTry(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeTryOrCatchBody(Ctx& ctx, Index pos, Type type, bool isTry) { +Result<> makeTryOrCatchBody(Ctx& ctx, Index pos, Type type, bool isTry) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeThrow(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeThrow(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRethrow(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRethrow(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTupleMake(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTupleMake(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeTupleExtract(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeTupleExtract(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> makeCallRef(Ctx& ctx, Index pos, bool isReturn) { +Result<> makeCallRef(Ctx& ctx, Index pos, bool isReturn) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefI31(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefI31(Ctx& ctx, Index pos) { return ctx.makeRefI31(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeI31Get(Ctx& ctx, Index pos, bool signed_) { +template<typename Ctx> Result<> makeI31Get(Ctx& ctx, Index pos, bool signed_) { return ctx.makeI31Get(pos, signed_); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefTest(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefTest(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefCast(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeRefCast(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { +template<typename Ctx> Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { +template<typename Ctx> Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> makeStructNew(Ctx& ctx, Index pos, bool default_) { +Result<> makeStructNew(Ctx& ctx, Index pos, bool default_) { auto type = typeidx(ctx); CHECK_ERR(type); if (default_) { @@ -1409,7 +1270,7 @@ Result<typename Ctx::InstrT> makeStructNew(Ctx& ctx, Index pos, bool default_) { } template<typename Ctx> -Result<typename Ctx::InstrT> makeStructGet(Ctx& ctx, Index pos, bool signed_) { +Result<> makeStructGet(Ctx& ctx, Index pos, bool signed_) { auto type = typeidx(ctx); CHECK_ERR(type); auto field = fieldidx(ctx, *type); @@ -1417,8 +1278,7 @@ Result<typename Ctx::InstrT> makeStructGet(Ctx& ctx, Index pos, bool signed_) { return ctx.makeStructGet(pos, *type, *field, signed_); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStructSet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStructSet(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); auto field = fieldidx(ctx, *type); @@ -1427,7 +1287,7 @@ Result<typename Ctx::InstrT> makeStructSet(Ctx& ctx, Index pos) { } template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNew(Ctx& ctx, Index pos, bool default_) { +Result<> makeArrayNew(Ctx& ctx, Index pos, bool default_) { auto type = typeidx(ctx); CHECK_ERR(type); if (default_) { @@ -1436,8 +1296,7 @@ Result<typename Ctx::InstrT> makeArrayNew(Ctx& ctx, Index pos, bool default_) { return ctx.makeArrayNew(pos, *type); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNewData(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayNewData(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); auto data = dataidx(ctx); @@ -1445,8 +1304,7 @@ Result<typename Ctx::InstrT> makeArrayNewData(Ctx& ctx, Index pos) { return ctx.makeArrayNewData(pos, *type, *data); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNewElem(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayNewElem(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); auto data = dataidx(ctx); @@ -1454,32 +1312,28 @@ Result<typename Ctx::InstrT> makeArrayNewElem(Ctx& ctx, Index pos) { return ctx.makeArrayNewElem(pos, *type, *data); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayNewFixed(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayNewFixed(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayGet(Ctx& ctx, Index pos, bool signed_) { +Result<> makeArrayGet(Ctx& ctx, Index pos, bool signed_) { auto type = typeidx(ctx); CHECK_ERR(type); return ctx.makeArrayGet(pos, *type, signed_); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArraySet(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArraySet(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); return ctx.makeArraySet(pos, *type); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayLen(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayLen(Ctx& ctx, Index pos) { return ctx.makeArrayLen(pos); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayCopy(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayCopy(Ctx& ctx, Index pos) { auto destType = typeidx(ctx); CHECK_ERR(destType); auto srcType = typeidx(ctx); @@ -1487,95 +1341,80 @@ Result<typename Ctx::InstrT> makeArrayCopy(Ctx& ctx, Index pos) { return ctx.makeArrayCopy(pos, *destType, *srcType); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayFill(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayFill(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); return ctx.makeArrayFill(pos, *type); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayInitData(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayInitData(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeArrayInitElem(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeArrayInitElem(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { +template<typename Ctx> Result<> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringNew(Ctx& ctx, Index pos, StringNewOp op, bool try_) { +Result<> makeStringNew(Ctx& ctx, Index pos, StringNewOp op, bool try_) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringConst(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStringConst(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) { +Result<> makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) { +Result<> makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringConcat(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStringConcat(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) { +Result<> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> makeStringAs(Ctx& ctx, Index pos, StringAsOp op) { +Result<> makeStringAs(Ctx& ctx, Index pos, StringAsOp op) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringWTF8Advance(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStringWTF8Advance(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringWTF16Get(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStringWTF16Get(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringIterNext(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStringIterNext(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) { +Result<> makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) { return ctx.in.err("unimplemented instruction"); } template<typename Ctx> -Result<typename Ctx::InstrT> -makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) { +Result<> makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) { return ctx.in.err("unimplemented instruction"); } -template<typename Ctx> -Result<typename Ctx::InstrT> makeStringSliceIter(Ctx& ctx, Index pos) { +template<typename Ctx> Result<> makeStringSliceIter(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } @@ -1905,13 +1744,7 @@ template<typename Ctx> MaybeResult<> func(Ctx& ctx) { CHECK_ERR(l); localVars = *l; } - } - - std::optional<typename Ctx::InstrsT> insts; - if (!import) { - auto i = instrs(ctx); - CHECK_ERR(i); - insts = *i; + CHECK_ERR(instrs(ctx)); } if (!ctx.in.takeRParen()) { @@ -1919,7 +1752,7 @@ template<typename Ctx> MaybeResult<> func(Ctx& ctx) { } CHECK_ERR( - ctx.addFunc(name, *exports, import.getPtr(), *type, localVars, insts, pos)); + ctx.addFunc(name, *exports, import.getPtr(), *type, localVars, pos)); return Ok{}; } @@ -2050,9 +1883,8 @@ template<typename Ctx> MaybeResult<> data(Ctx& ctx) { } offset = *e; } else if (ctx.in.takeLParen()) { - auto inst = instr(ctx); - CHECK_ERR(inst); - auto offsetExpr = ctx.instrToExpr(*inst); + CHECK_ERR(instr(ctx)); + auto offsetExpr = ctx.makeExpr(); CHECK_ERR(offsetExpr); offset = *offsetExpr; if (!ctx.in.takeRParen()) { |