From 2c09a60ecbb0ba0276982204d8788b4343356417 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 21 Sep 2023 13:46:51 -0700 Subject: [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. --- src/parser/parsers.h | 736 ++++++++++++++++++++------------------------------- 1 file changed, 284 insertions(+), 452 deletions(-) (limited to 'src/parser/parsers.h') 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 Result memtype(Ctx&); template Result globaltype(Ctx&); // Instructions -template MaybeResult foldedBlockinstr(Ctx&); -template -MaybeResult unfoldedBlockinstr(Ctx&); -template MaybeResult blockinstr(Ctx&); -template MaybeResult plaininstr(Ctx&); -template MaybeResult instr(Ctx&); -template -Result instrs(Ctx&, bool requireFolded = false); -template Result foldedinstrs(Ctx&); +template MaybeResult<> foldedBlockinstr(Ctx&); +template MaybeResult<> unfoldedBlockinstr(Ctx&); +template MaybeResult<> blockinstr(Ctx&); +template MaybeResult<> plaininstr(Ctx&); +template MaybeResult<> instr(Ctx&); +template Result<> foldedinstrs(Ctx&); +template Result<> instrs(Ctx&); template Result expr(Ctx&); template Result memarg(Ctx&, uint32_t); template Result blocktype(Ctx&); -template MaybeResult block(Ctx&, bool); -template MaybeResult ifelse(Ctx&, bool); -template -Result makeUnreachable(Ctx&, Index); -template Result makeNop(Ctx&, Index); -template -Result makeBinary(Ctx&, Index, BinaryOp op); -template -Result makeUnary(Ctx&, Index, UnaryOp op); -template Result makeSelect(Ctx&, Index); -template Result makeDrop(Ctx&, Index); -template Result makeMemorySize(Ctx&, Index); -template Result makeMemoryGrow(Ctx&, Index); -template Result makeLocalGet(Ctx&, Index); -template Result makeLocalTee(Ctx&, Index); -template Result makeLocalSet(Ctx&, Index); -template Result makeGlobalGet(Ctx&, Index); -template Result makeGlobalSet(Ctx&, Index); -template Result makeBlock(Ctx&, Index); -template Result makeThenOrElse(Ctx&, Index); -template -Result makeConst(Ctx&, Index, Type type); -template -Result +template MaybeResult<> block(Ctx&, bool); +template MaybeResult<> ifelse(Ctx&, bool); +template Result<> makeUnreachable(Ctx&, Index); +template Result<> makeNop(Ctx&, Index); +template Result<> makeBinary(Ctx&, Index, BinaryOp op); +template Result<> makeUnary(Ctx&, Index, UnaryOp op); +template Result<> makeSelect(Ctx&, Index); +template Result<> makeDrop(Ctx&, Index); +template Result<> makeMemorySize(Ctx&, Index); +template Result<> makeMemoryGrow(Ctx&, Index); +template Result<> makeLocalGet(Ctx&, Index); +template Result<> makeLocalTee(Ctx&, Index); +template Result<> makeLocalSet(Ctx&, Index); +template Result<> makeGlobalGet(Ctx&, Index); +template Result<> makeGlobalSet(Ctx&, Index); +template Result<> makeBlock(Ctx&, Index); +template Result<> makeThenOrElse(Ctx&, Index); +template Result<> makeConst(Ctx&, Index, Type type); +template +Result<> makeLoad(Ctx&, Index, Type type, bool signed_, int bytes, bool isAtomic); template -Result -makeStore(Ctx&, Index, Type type, int bytes, bool isAtomic); -template -Result -makeAtomicRMW(Ctx&, Index, AtomicRMWOp op, Type type, uint8_t bytes); -template -Result -makeAtomicCmpxchg(Ctx&, Index, Type type, uint8_t bytes); -template -Result makeAtomicWait(Ctx&, Index, Type type); -template -Result makeAtomicNotify(Ctx&, Index); -template -Result makeAtomicFence(Ctx&, Index); -template -Result -makeSIMDExtract(Ctx&, Index, SIMDExtractOp op, size_t lanes); -template -Result -makeSIMDReplace(Ctx&, Index, SIMDReplaceOp op, size_t lanes); -template -Result makeSIMDShuffle(Ctx&, Index); -template -Result makeSIMDTernary(Ctx&, Index, SIMDTernaryOp op); -template -Result makeSIMDShift(Ctx&, Index, SIMDShiftOp op); -template -Result -makeSIMDLoad(Ctx&, Index, SIMDLoadOp op, int bytes); -template -Result -makeSIMDLoadStoreLane(Ctx&, Index, SIMDLoadStoreLaneOp op, int bytes); -template Result makeMemoryInit(Ctx&, Index); -template Result makeDataDrop(Ctx&, Index); -template Result makeMemoryCopy(Ctx&, Index); -template Result makeMemoryFill(Ctx&, Index); -template Result makePop(Ctx&, Index); -template Result makeIf(Ctx&, Index); -template -Result makeMaybeBlock(Ctx&, Index, size_t i, Type type); -template Result makeLoop(Ctx&, Index); -template -Result makeCall(Ctx&, Index, bool isReturn); -template -Result makeCallIndirect(Ctx&, Index, bool isReturn); -template Result makeBreak(Ctx&, Index); -template Result makeBreakTable(Ctx&, Index); -template Result makeReturn(Ctx&, Index); -template Result makeRefNull(Ctx&, Index); -template Result makeRefIsNull(Ctx&, Index); -template Result makeRefFunc(Ctx&, Index); -template Result makeRefEq(Ctx&, Index); -template Result makeTableGet(Ctx&, Index); -template Result makeTableSet(Ctx&, Index); -template Result makeTableSize(Ctx&, Index); -template Result makeTableGrow(Ctx&, Index); -template Result makeTableFill(Ctx&, Index); -template Result makeTry(Ctx&, Index); -template -Result -makeTryOrCatchBody(Ctx&, Index, Type type, bool isTry); -template Result makeThrow(Ctx&, Index); -template Result makeRethrow(Ctx&, Index); -template Result makeTupleMake(Ctx&, Index); -template -Result makeTupleExtract(Ctx&, Index); -template -Result makeCallRef(Ctx&, Index, bool isReturn); -template Result makeRefI31(Ctx&, Index); -template -Result makeI31Get(Ctx&, Index, bool signed_); -template Result makeRefTest(Ctx&, Index); -template Result makeRefCast(Ctx&, Index); -template -Result makeBrOnNull(Ctx&, Index, bool onFail = false); -template -Result makeBrOnCast(Ctx&, Index, bool onFail = false); -template -Result makeStructNew(Ctx&, Index, bool default_); -template -Result makeStructGet(Ctx&, Index, bool signed_ = false); -template Result makeStructSet(Ctx&, Index); -template -Result makeArrayNew(Ctx&, Index, bool default_); -template -Result makeArrayNewData(Ctx&, Index); -template -Result makeArrayNewElem(Ctx&, Index); -template -Result makeArrayNewFixed(Ctx&, Index); -template -Result makeArrayGet(Ctx&, Index, bool signed_ = false); -template Result makeArraySet(Ctx&, Index); -template Result makeArrayLen(Ctx&, Index); -template Result makeArrayCopy(Ctx&, Index); -template Result makeArrayFill(Ctx&, Index); -template -Result makeArrayInitData(Ctx&, Index); -template -Result makeArrayInitElem(Ctx&, Index); -template -Result makeRefAs(Ctx&, Index, RefAsOp op); -template -Result -makeStringNew(Ctx&, Index, StringNewOp op, bool try_); -template -Result makeStringConst(Ctx&, Index); -template -Result makeStringMeasure(Ctx&, Index, StringMeasureOp op); -template -Result makeStringEncode(Ctx&, Index, StringEncodeOp op); -template -Result makeStringConcat(Ctx&, Index); -template -Result makeStringEq(Ctx&, Index, StringEqOp); -template -Result makeStringAs(Ctx&, Index, StringAsOp op); -template -Result makeStringWTF8Advance(Ctx&, Index); -template -Result makeStringWTF16Get(Ctx&, Index); -template -Result makeStringIterNext(Ctx&, Index); -template -Result -makeStringIterMove(Ctx&, Index, StringIterMoveOp op); -template -Result -makeStringSliceWTF(Ctx&, Index, StringSliceWTFOp op); -template -Result makeStringSliceIter(Ctx&, Index); +Result<> makeStore(Ctx&, Index, Type type, int bytes, bool isAtomic); +template +Result<> makeAtomicRMW(Ctx&, Index, AtomicRMWOp op, Type type, uint8_t bytes); +template +Result<> makeAtomicCmpxchg(Ctx&, Index, Type type, uint8_t bytes); +template Result<> makeAtomicWait(Ctx&, Index, Type type); +template Result<> makeAtomicNotify(Ctx&, Index); +template Result<> makeAtomicFence(Ctx&, Index); +template +Result<> makeSIMDExtract(Ctx&, Index, SIMDExtractOp op, size_t lanes); +template +Result<> makeSIMDReplace(Ctx&, Index, SIMDReplaceOp op, size_t lanes); +template Result<> makeSIMDShuffle(Ctx&, Index); +template Result<> makeSIMDTernary(Ctx&, Index, SIMDTernaryOp op); +template Result<> makeSIMDShift(Ctx&, Index, SIMDShiftOp op); +template +Result<> makeSIMDLoad(Ctx&, Index, SIMDLoadOp op, int bytes); +template +Result<> makeSIMDLoadStoreLane(Ctx&, Index, SIMDLoadStoreLaneOp op, int bytes); +template Result<> makeMemoryInit(Ctx&, Index); +template Result<> makeDataDrop(Ctx&, Index); +template Result<> makeMemoryCopy(Ctx&, Index); +template Result<> makeMemoryFill(Ctx&, Index); +template Result<> makePop(Ctx&, Index); +template Result<> makeIf(Ctx&, Index); +template +Result<> makeMaybeBlock(Ctx&, Index, size_t i, Type type); +template Result<> makeLoop(Ctx&, Index); +template Result<> makeCall(Ctx&, Index, bool isReturn); +template Result<> makeCallIndirect(Ctx&, Index, bool isReturn); +template Result<> makeBreak(Ctx&, Index); +template Result<> makeBreakTable(Ctx&, Index); +template Result<> makeReturn(Ctx&, Index); +template Result<> makeRefNull(Ctx&, Index); +template Result<> makeRefIsNull(Ctx&, Index); +template Result<> makeRefFunc(Ctx&, Index); +template Result<> makeRefEq(Ctx&, Index); +template Result<> makeTableGet(Ctx&, Index); +template Result<> makeTableSet(Ctx&, Index); +template Result<> makeTableSize(Ctx&, Index); +template Result<> makeTableGrow(Ctx&, Index); +template Result<> makeTableFill(Ctx&, Index); +template Result<> makeTry(Ctx&, Index); +template +Result<> makeTryOrCatchBody(Ctx&, Index, Type type, bool isTry); +template Result<> makeThrow(Ctx&, Index); +template Result<> makeRethrow(Ctx&, Index); +template Result<> makeTupleMake(Ctx&, Index); +template Result<> makeTupleExtract(Ctx&, Index); +template Result<> makeCallRef(Ctx&, Index, bool isReturn); +template Result<> makeRefI31(Ctx&, Index); +template Result<> makeI31Get(Ctx&, Index, bool signed_); +template Result<> makeRefTest(Ctx&, Index); +template Result<> makeRefCast(Ctx&, Index); +template Result<> makeBrOnNull(Ctx&, Index, bool onFail = false); +template Result<> makeBrOnCast(Ctx&, Index, bool onFail = false); +template Result<> makeStructNew(Ctx&, Index, bool default_); +template +Result<> makeStructGet(Ctx&, Index, bool signed_ = false); +template Result<> makeStructSet(Ctx&, Index); +template Result<> makeArrayNew(Ctx&, Index, bool default_); +template Result<> makeArrayNewData(Ctx&, Index); +template Result<> makeArrayNewElem(Ctx&, Index); +template Result<> makeArrayNewFixed(Ctx&, Index); +template Result<> makeArrayGet(Ctx&, Index, bool signed_ = false); +template Result<> makeArraySet(Ctx&, Index); +template Result<> makeArrayLen(Ctx&, Index); +template Result<> makeArrayCopy(Ctx&, Index); +template Result<> makeArrayFill(Ctx&, Index); +template Result<> makeArrayInitData(Ctx&, Index); +template Result<> makeArrayInitElem(Ctx&, Index); +template Result<> makeRefAs(Ctx&, Index, RefAsOp op); +template +Result<> makeStringNew(Ctx&, Index, StringNewOp op, bool try_); +template Result<> makeStringConst(Ctx&, Index); +template +Result<> makeStringMeasure(Ctx&, Index, StringMeasureOp op); +template +Result<> makeStringEncode(Ctx&, Index, StringEncodeOp op); +template Result<> makeStringConcat(Ctx&, Index); +template Result<> makeStringEq(Ctx&, Index, StringEqOp); +template Result<> makeStringAs(Ctx&, Index, StringAsOp op); +template Result<> makeStringWTF8Advance(Ctx&, Index); +template Result<> makeStringWTF16Get(Ctx&, Index); +template Result<> makeStringIterNext(Ctx&, Index); +template +Result<> makeStringIterMove(Ctx&, Index, StringIterMoveOp op); +template +Result<> makeStringSliceWTF(Ctx&, Index, StringSliceWTFOp op); +template Result<> makeStringSliceIter(Ctx&, Index); // Modules template MaybeResult maybeTypeidx(Ctx& ctx); @@ -592,8 +545,7 @@ template Result globaltype(Ctx& ctx) { // ============ // blockinstr ::= block | loop | if-else | try-catch -template -MaybeResult foldedBlockinstr(Ctx& ctx) { +template MaybeResult<> foldedBlockinstr(Ctx& ctx) { if (auto i = block(ctx, true)) { return i; } @@ -604,8 +556,7 @@ MaybeResult foldedBlockinstr(Ctx& ctx) { return {}; } -template -MaybeResult unfoldedBlockinstr(Ctx& ctx) { +template MaybeResult<> unfoldedBlockinstr(Ctx& ctx) { if (auto i = block(ctx, false)) { return i; } @@ -616,7 +567,7 @@ MaybeResult unfoldedBlockinstr(Ctx& ctx) { return {}; } -template MaybeResult blockinstr(Ctx& ctx) { +template MaybeResult<> blockinstr(Ctx& ctx) { if (auto i = foldedBlockinstr(ctx)) { return i; } @@ -627,7 +578,7 @@ template MaybeResult blockinstr(Ctx& ctx) { } // plaininstr ::= ... all plain instructions ... -template MaybeResult plaininstr(Ctx& ctx) { +template MaybeResult<> plaininstr(Ctx& ctx) { auto pos = ctx.in.getPos(); auto keyword = ctx.in.takeKeyword(); if (!keyword) { @@ -640,7 +591,7 @@ template MaybeResult plaininstr(Ctx& ctx) { } // instr ::= plaininstr | blockinstr -template MaybeResult instr(Ctx& ctx) { +template 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 MaybeResult instr(Ctx& ctx) { return {}; } -template -Result instrs(Ctx& ctx, bool requireFolded) { - auto insts = ctx.makeInstrs(); - bool parsedFolded = false; +template 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>> 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>> 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 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 Result foldedinstrs(Ctx& ctx) { - return instrs(ctx, true); + return Ok{}; } template Result 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 Result blocktype(Ctx& ctx) { // block ::= 'block' label blocktype instr* 'end' id? if id = {} or id = label // | '(' 'block' label blocktype instr* ')' -template -MaybeResult block(Ctx& ctx, bool folded) { +template MaybeResult<> block(Ctx& ctx, bool folded) { auto pos = ctx.in.getPos(); if (folded) { @@ -825,8 +750,7 @@ MaybeResult 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 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 -MaybeResult ifelse(Ctx& ctx, bool folded) { +template MaybeResult<> ifelse(Ctx& ctx, bool folded) { auto pos = ctx.in.getPos(); if (folded) { @@ -877,8 +800,7 @@ MaybeResult 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 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 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 -Result makeUnreachable(Ctx& ctx, Index pos) { +template Result<> makeUnreachable(Ctx& ctx, Index pos) { return ctx.makeUnreachable(pos); } -template -Result makeNop(Ctx& ctx, Index pos) { +template Result<> makeNop(Ctx& ctx, Index pos) { return ctx.makeNop(pos); } -template -Result makeBinary(Ctx& ctx, Index pos, BinaryOp op) { +template Result<> makeBinary(Ctx& ctx, Index pos, BinaryOp op) { return ctx.makeBinary(pos, op); } -template -Result makeUnary(Ctx& ctx, Index pos, UnaryOp op) { +template Result<> makeUnary(Ctx& ctx, Index pos, UnaryOp op) { return ctx.makeUnary(pos, op); } -template -Result makeSelect(Ctx& ctx, Index pos) { +template Result<> makeSelect(Ctx& ctx, Index pos) { auto res = results(ctx); CHECK_ERR(res); return ctx.makeSelect(pos, res.getPtr()); } -template -Result makeDrop(Ctx& ctx, Index pos) { +template Result<> makeDrop(Ctx& ctx, Index pos) { return ctx.makeDrop(pos); } -template -Result makeMemorySize(Ctx& ctx, Index pos) { +template Result<> makeMemorySize(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); return ctx.makeMemorySize(pos, mem.getPtr()); } -template -Result makeMemoryGrow(Ctx& ctx, Index pos) { +template Result<> makeMemoryGrow(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); return ctx.makeMemoryGrow(pos, mem.getPtr()); } -template -Result makeLocalGet(Ctx& ctx, Index pos) { +template Result<> makeLocalGet(Ctx& ctx, Index pos) { auto local = localidx(ctx); CHECK_ERR(local); return ctx.makeLocalGet(pos, *local); } -template -Result makeLocalTee(Ctx& ctx, Index pos) { +template Result<> makeLocalTee(Ctx& ctx, Index pos) { auto local = localidx(ctx); CHECK_ERR(local); return ctx.makeLocalTee(pos, *local); } -template -Result makeLocalSet(Ctx& ctx, Index pos) { +template Result<> makeLocalSet(Ctx& ctx, Index pos) { auto local = localidx(ctx); CHECK_ERR(local); return ctx.makeLocalSet(pos, *local); } -template -Result makeGlobalGet(Ctx& ctx, Index pos) { +template Result<> makeGlobalGet(Ctx& ctx, Index pos) { auto global = globalidx(ctx); CHECK_ERR(global); return ctx.makeGlobalGet(pos, *global); } -template -Result makeGlobalSet(Ctx& ctx, Index pos) { +template Result<> makeGlobalSet(Ctx& ctx, Index pos) { auto global = globalidx(ctx); CHECK_ERR(global); return ctx.makeGlobalSet(pos, *global); } -template -Result makeBlock(Ctx& ctx, Index pos) { +template Result<> makeBlock(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeConst(Ctx& ctx, Index pos, Type type) { +template Result<> makeConst(Ctx& ctx, Index pos, Type type) { assert(type.isBasic()); switch (type.getBasic()) { case Type::i32: @@ -1039,7 +945,7 @@ Result makeConst(Ctx& ctx, Index pos, Type type) { } template -Result 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 makeLoad( } template -Result -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 -Result +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 -Result -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 -Result makeAtomicWait(Ctx& ctx, Index pos, Type type) { +template 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 makeAtomicWait(Ctx& ctx, Index pos, Type type) { return ctx.makeAtomicWait(pos, type, mem.getPtr(), *arg); } -template -Result makeAtomicNotify(Ctx& ctx, Index pos) { +template Result<> makeAtomicNotify(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, 4); @@ -1096,14 +998,12 @@ Result makeAtomicNotify(Ctx& ctx, Index pos) { return ctx.makeAtomicNotify(pos, mem.getPtr(), *arg); } -template -Result makeAtomicFence(Ctx& ctx, Index pos) { +template Result<> makeAtomicFence(Ctx& ctx, Index pos) { return ctx.makeAtomicFence(pos); } template -Result -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 -Result -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 -Result makeSIMDShuffle(Ctx& ctx, Index pos) { +template Result<> makeSIMDShuffle(Ctx& ctx, Index pos) { std::array lanes; for (int i = 0; i < 16; ++i) { auto lane = ctx.in.takeU8(); @@ -1135,20 +1033,17 @@ Result makeSIMDShuffle(Ctx& ctx, Index pos) { } template -Result -makeSIMDTernary(Ctx& ctx, Index pos, SIMDTernaryOp op) { +Result<> makeSIMDTernary(Ctx& ctx, Index pos, SIMDTernaryOp op) { return ctx.makeSIMDTernary(pos, op); } template -Result -makeSIMDShift(Ctx& ctx, Index pos, SIMDShiftOp op) { +Result<> makeSIMDShift(Ctx& ctx, Index pos, SIMDShiftOp op) { return ctx.makeSIMDShift(pos, op); } template -Result -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 -Result +Result<> makeSIMDLoadStoreLane(Ctx& ctx, Index pos, SIMDLoadStoreLaneOp op, int bytes) { auto reset = ctx.in.getPos(); - auto retry = [&]() -> Result { + 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 -Result makeMemoryInit(Ctx& ctx, Index pos) { +template Result<> makeMemoryInit(Ctx& ctx, Index pos) { auto reset = ctx.in.getPos(); - auto retry = [&]() -> Result { + 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 makeMemoryInit(Ctx& ctx, Index pos) { return ctx.makeMemoryInit(pos, mem.getPtr(), *data); } -template -Result makeDataDrop(Ctx& ctx, Index pos) { +template Result<> makeDataDrop(Ctx& ctx, Index pos) { auto data = dataidx(ctx); CHECK_ERR(data); return ctx.makeDataDrop(pos, *data); } -template -Result makeMemoryCopy(Ctx& ctx, Index pos) { +template Result<> makeMemoryCopy(Ctx& ctx, Index pos) { auto destMem = maybeMemidx(ctx); CHECK_ERR(destMem); std::optional srcMem = std::nullopt; @@ -1231,175 +1123,144 @@ Result makeMemoryCopy(Ctx& ctx, Index pos) { return ctx.makeMemoryCopy(pos, destMem.getPtr(), srcMem ? &*srcMem : nullptr); } -template -Result makeMemoryFill(Ctx& ctx, Index pos) { +template Result<> makeMemoryFill(Ctx& ctx, Index pos) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); return ctx.makeMemoryFill(pos, mem.getPtr()); } -template -Result makePop(Ctx& ctx, Index pos) { +template Result<> makePop(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeIf(Ctx& ctx, Index pos) { +template Result<> makeIf(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result -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 -Result makeLoop(Ctx& ctx, Index pos) { +template Result<> makeLoop(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeCall(Ctx& ctx, Index pos, bool isReturn) { +template Result<> makeCall(Ctx& ctx, Index pos, bool isReturn) { return ctx.in.err("unimplemented instruction"); } template -Result -makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { +Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { return ctx.in.err("unimplemented instruction"); } -template -Result makeBreak(Ctx& ctx, Index pos) { +template Result<> makeBreak(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeBreakTable(Ctx& ctx, Index pos) { +template Result<> makeBreakTable(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeReturn(Ctx& ctx, Index pos) { +template Result<> makeReturn(Ctx& ctx, Index pos) { return ctx.makeReturn(pos); } -template -Result makeRefNull(Ctx& ctx, Index pos) { +template Result<> makeRefNull(Ctx& ctx, Index pos) { auto t = heaptype(ctx); CHECK_ERR(t); return ctx.makeRefNull(pos, *t); } -template -Result makeRefIsNull(Ctx& ctx, Index pos) { +template Result<> makeRefIsNull(Ctx& ctx, Index pos) { return ctx.makeRefIsNull(pos); } -template -Result makeRefFunc(Ctx& ctx, Index pos) { +template Result<> makeRefFunc(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeRefEq(Ctx& ctx, Index pos) { +template Result<> makeRefEq(Ctx& ctx, Index pos) { return ctx.makeRefEq(pos); } -template -Result makeTableGet(Ctx& ctx, Index pos) { +template Result<> makeTableGet(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTableSet(Ctx& ctx, Index pos) { +template Result<> makeTableSet(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTableSize(Ctx& ctx, Index pos) { +template Result<> makeTableSize(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTableGrow(Ctx& ctx, Index pos) { +template Result<> makeTableGrow(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTableFill(Ctx& ctx, Index pos) { +template Result<> makeTableFill(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTry(Ctx& ctx, Index pos) { +template Result<> makeTry(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result -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 -Result makeThrow(Ctx& ctx, Index pos) { +template Result<> makeThrow(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeRethrow(Ctx& ctx, Index pos) { +template Result<> makeRethrow(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTupleMake(Ctx& ctx, Index pos) { +template Result<> makeTupleMake(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeTupleExtract(Ctx& ctx, Index pos) { +template Result<> makeTupleExtract(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result makeCallRef(Ctx& ctx, Index pos, bool isReturn) { +Result<> makeCallRef(Ctx& ctx, Index pos, bool isReturn) { return ctx.in.err("unimplemented instruction"); } -template -Result makeRefI31(Ctx& ctx, Index pos) { +template Result<> makeRefI31(Ctx& ctx, Index pos) { return ctx.makeRefI31(pos); } -template -Result makeI31Get(Ctx& ctx, Index pos, bool signed_) { +template Result<> makeI31Get(Ctx& ctx, Index pos, bool signed_) { return ctx.makeI31Get(pos, signed_); } -template -Result makeRefTest(Ctx& ctx, Index pos) { +template Result<> makeRefTest(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeRefCast(Ctx& ctx, Index pos) { +template Result<> makeRefCast(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { +template Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { return ctx.in.err("unimplemented instruction"); } -template -Result makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { +template Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { return ctx.in.err("unimplemented instruction"); } template -Result 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 makeStructNew(Ctx& ctx, Index pos, bool default_) { } template -Result 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 makeStructGet(Ctx& ctx, Index pos, bool signed_) { return ctx.makeStructGet(pos, *type, *field, signed_); } -template -Result makeStructSet(Ctx& ctx, Index pos) { +template Result<> makeStructSet(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); auto field = fieldidx(ctx, *type); @@ -1427,7 +1287,7 @@ Result makeStructSet(Ctx& ctx, Index pos) { } template -Result 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 makeArrayNew(Ctx& ctx, Index pos, bool default_) { return ctx.makeArrayNew(pos, *type); } -template -Result makeArrayNewData(Ctx& ctx, Index pos) { +template Result<> makeArrayNewData(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); auto data = dataidx(ctx); @@ -1445,8 +1304,7 @@ Result makeArrayNewData(Ctx& ctx, Index pos) { return ctx.makeArrayNewData(pos, *type, *data); } -template -Result makeArrayNewElem(Ctx& ctx, Index pos) { +template Result<> makeArrayNewElem(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); auto data = dataidx(ctx); @@ -1454,32 +1312,28 @@ Result makeArrayNewElem(Ctx& ctx, Index pos) { return ctx.makeArrayNewElem(pos, *type, *data); } -template -Result makeArrayNewFixed(Ctx& ctx, Index pos) { +template Result<> makeArrayNewFixed(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result 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 -Result makeArraySet(Ctx& ctx, Index pos) { +template Result<> makeArraySet(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); return ctx.makeArraySet(pos, *type); } -template -Result makeArrayLen(Ctx& ctx, Index pos) { +template Result<> makeArrayLen(Ctx& ctx, Index pos) { return ctx.makeArrayLen(pos); } -template -Result makeArrayCopy(Ctx& ctx, Index pos) { +template Result<> makeArrayCopy(Ctx& ctx, Index pos) { auto destType = typeidx(ctx); CHECK_ERR(destType); auto srcType = typeidx(ctx); @@ -1487,95 +1341,80 @@ Result makeArrayCopy(Ctx& ctx, Index pos) { return ctx.makeArrayCopy(pos, *destType, *srcType); } -template -Result makeArrayFill(Ctx& ctx, Index pos) { +template Result<> makeArrayFill(Ctx& ctx, Index pos) { auto type = typeidx(ctx); CHECK_ERR(type); return ctx.makeArrayFill(pos, *type); } -template -Result makeArrayInitData(Ctx& ctx, Index pos) { +template Result<> makeArrayInitData(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeArrayInitElem(Ctx& ctx, Index pos) { +template Result<> makeArrayInitElem(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { +template Result<> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { return ctx.in.err("unimplemented instruction"); } template -Result -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 -Result makeStringConst(Ctx& ctx, Index pos) { +template Result<> makeStringConst(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result -makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) { +Result<> makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) { return ctx.in.err("unimplemented instruction"); } template -Result -makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) { +Result<> makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) { return ctx.in.err("unimplemented instruction"); } -template -Result makeStringConcat(Ctx& ctx, Index pos) { +template Result<> makeStringConcat(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result makeStringEq(Ctx& ctx, Index pos, StringEqOp op) { +Result<> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) { return ctx.in.err("unimplemented instruction"); } template -Result makeStringAs(Ctx& ctx, Index pos, StringAsOp op) { +Result<> makeStringAs(Ctx& ctx, Index pos, StringAsOp op) { return ctx.in.err("unimplemented instruction"); } -template -Result makeStringWTF8Advance(Ctx& ctx, Index pos) { +template Result<> makeStringWTF8Advance(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeStringWTF16Get(Ctx& ctx, Index pos) { +template Result<> makeStringWTF16Get(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } -template -Result makeStringIterNext(Ctx& ctx, Index pos) { +template Result<> makeStringIterNext(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } template -Result -makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) { +Result<> makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) { return ctx.in.err("unimplemented instruction"); } template -Result -makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) { +Result<> makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) { return ctx.in.err("unimplemented instruction"); } -template -Result makeStringSliceIter(Ctx& ctx, Index pos) { +template Result<> makeStringSliceIter(Ctx& ctx, Index pos) { return ctx.in.err("unimplemented instruction"); } @@ -1905,13 +1744,7 @@ template MaybeResult<> func(Ctx& ctx) { CHECK_ERR(l); localVars = *l; } - } - - std::optional 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 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 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()) { -- cgit v1.2.3