diff options
Diffstat (limited to 'src/parser')
-rw-r--r-- | src/parser/contexts.h | 954 | ||||
-rw-r--r-- | src/parser/lexer.cpp | 153 | ||||
-rw-r--r-- | src/parser/lexer.h | 28 | ||||
-rw-r--r-- | src/parser/parsers.h | 1148 |
4 files changed, 1700 insertions, 583 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index d2f0ea2d0..6505d11a4 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -355,20 +355,32 @@ struct NullInstrParserCtx { MemargT getMemarg(uint64_t, uint32_t) { return Ok{}; } template<typename BlockTypeT> - Result<> makeBlock(Index, std::optional<Name>, BlockTypeT) { + Result<> makeBlock(Index, + const std::vector<Annotation>&, + std::optional<Name>, + BlockTypeT) { return Ok{}; } template<typename BlockTypeT> - Result<> makeIf(Index, std::optional<Name>, BlockTypeT) { + Result<> makeIf(Index, + const std::vector<Annotation>&, + std::optional<Name>, + BlockTypeT) { return Ok{}; } Result<> visitElse() { return Ok{}; } template<typename BlockTypeT> - Result<> makeLoop(Index, std::optional<Name>, BlockTypeT) { + Result<> makeLoop(Index, + const std::vector<Annotation>&, + std::optional<Name>, + BlockTypeT) { return Ok{}; } template<typename BlockTypeT> - Result<> makeTry(Index, std::optional<Name>, BlockTypeT) { + Result<> makeTry(Index, + const std::vector<Annotation>&, + std::optional<Name>, + BlockTypeT) { return Ok{}; } Result<> visitCatch(Index, TagIdxT) { return Ok{}; } @@ -383,198 +395,427 @@ struct NullInstrParserCtx { CatchT makeCatchAll(LabelIdxT) { return Ok{}; } CatchT makeCatchAllRef(LabelIdxT) { return Ok{}; } template<typename BlockTypeT> - Result<> makeTryTable(Index, std::optional<Name>, BlockTypeT, CatchListT) { + Result<> makeTryTable(Index, + const std::vector<Annotation>&, + std::optional<Name>, + BlockTypeT, + CatchListT) { return Ok{}; } TagLabelListT makeTagLabelList() { return Ok{}; } void appendTagLabel(TagLabelListT&, TagIdxT, LabelIdxT) {} - Result<> makeUnreachable(Index) { return Ok{}; } - Result<> makeNop(Index) { return Ok{}; } - Result<> makeBinary(Index, BinaryOp) { return Ok{}; } - Result<> makeUnary(Index, UnaryOp) { return Ok{}; } - template<typename ResultsT> Result<> makeSelect(Index, ResultsT*) { + void setSrcLoc(const Annotation&) {} + + Result<> makeUnreachable(Index, const std::vector<Annotation>&) { + return Ok{}; + } + Result<> makeNop(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> makeBinary(Index, const std::vector<Annotation>&, BinaryOp) { + return Ok{}; + } + Result<> makeUnary(Index, const std::vector<Annotation>&, UnaryOp) { + return Ok{}; + } + template<typename ResultsT> + Result<> makeSelect(Index, const std::vector<Annotation>&, ResultsT*) { + return Ok{}; + } + Result<> makeDrop(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> makeMemorySize(Index, const std::vector<Annotation>&, MemoryIdxT*) { + return Ok{}; + } + Result<> makeMemoryGrow(Index, const std::vector<Annotation>&, MemoryIdxT*) { + return Ok{}; + } + Result<> makeLocalGet(Index, const std::vector<Annotation>&, LocalIdxT) { + return Ok{}; + } + Result<> makeLocalTee(Index, const std::vector<Annotation>&, LocalIdxT) { + return Ok{}; + } + Result<> makeLocalSet(Index, const std::vector<Annotation>&, LocalIdxT) { + return Ok{}; + } + Result<> makeGlobalGet(Index, const std::vector<Annotation>&, GlobalIdxT) { + return Ok{}; + } + Result<> makeGlobalSet(Index, const std::vector<Annotation>&, GlobalIdxT) { return Ok{}; } - Result<> makeDrop(Index) { return Ok{}; } - Result<> makeMemorySize(Index, MemoryIdxT*) { return Ok{}; } - Result<> makeMemoryGrow(Index, MemoryIdxT*) { return Ok{}; } - Result<> makeLocalGet(Index, LocalIdxT) { return Ok{}; } - Result<> makeLocalTee(Index, LocalIdxT) { return Ok{}; } - Result<> makeLocalSet(Index, LocalIdxT) { return Ok{}; } - Result<> makeGlobalGet(Index, GlobalIdxT) { return Ok{}; } - Result<> makeGlobalSet(Index, GlobalIdxT) { return Ok{}; } - Result<> makeI32Const(Index, uint32_t) { return Ok{}; } - Result<> makeI64Const(Index, uint64_t) { return Ok{}; } - Result<> makeF32Const(Index, float) { return Ok{}; } - Result<> makeF64Const(Index, double) { return Ok{}; } - Result<> makeI8x16Const(Index, const std::array<uint8_t, 16>&) { + Result<> makeI32Const(Index, const std::vector<Annotation>&, uint32_t) { + return Ok{}; + } + Result<> makeI64Const(Index, const std::vector<Annotation>&, uint64_t) { return Ok{}; } - Result<> makeI16x8Const(Index, const std::array<uint16_t, 8>&) { + Result<> makeF32Const(Index, const std::vector<Annotation>&, float) { return Ok{}; } - Result<> makeI32x4Const(Index, const std::array<uint32_t, 4>&) { + Result<> makeF64Const(Index, const std::vector<Annotation>&, double) { return Ok{}; } - Result<> makeI64x2Const(Index, const std::array<uint64_t, 2>&) { + Result<> makeI8x16Const(Index, + const std::vector<Annotation>&, + const std::array<uint8_t, 16>&) { return Ok{}; } - Result<> makeF32x4Const(Index, const std::array<float, 4>&) { return Ok{}; } - Result<> makeF64x2Const(Index, const std::array<double, 2>&) { return Ok{}; } - Result<> makeLoad(Index, Type, bool, int, bool, MemoryIdxT*, MemargT) { + Result<> makeI16x8Const(Index, + const std::vector<Annotation>&, + const std::array<uint16_t, 8>&) { return Ok{}; } - Result<> makeStore(Index, Type, int, bool, MemoryIdxT*, MemargT) { + Result<> makeI32x4Const(Index, + const std::vector<Annotation>&, + const std::array<uint32_t, 4>&) { return Ok{}; } - Result<> makeAtomicRMW(Index, AtomicRMWOp, Type, int, MemoryIdxT*, MemargT) { + Result<> makeI64x2Const(Index, + const std::vector<Annotation>&, + const std::array<uint64_t, 2>&) { return Ok{}; } - Result<> makeAtomicCmpxchg(Index, Type, int, MemoryIdxT*, MemargT) { + Result<> makeF32x4Const(Index, + const std::vector<Annotation>&, + const std::array<float, 4>&) { return Ok{}; } - Result<> makeAtomicWait(Index, Type, MemoryIdxT*, MemargT) { return Ok{}; } - Result<> makeAtomicNotify(Index, MemoryIdxT*, MemargT) { return Ok{}; } - Result<> makeAtomicFence(Index) { return Ok{}; } - Result<> makeSIMDExtract(Index, SIMDExtractOp, uint8_t) { return Ok{}; } - Result<> makeSIMDReplace(Index, SIMDReplaceOp, uint8_t) { return Ok{}; } - Result<> makeSIMDShuffle(Index, const std::array<uint8_t, 16>&) { + Result<> makeF64x2Const(Index, + const std::vector<Annotation>&, + const std::array<double, 2>&) { return Ok{}; } - Result<> makeSIMDTernary(Index, SIMDTernaryOp) { return Ok{}; } - Result<> makeSIMDShift(Index, SIMDShiftOp) { return Ok{}; } - Result<> makeSIMDLoad(Index, SIMDLoadOp, MemoryIdxT*, MemargT) { + Result<> makeLoad(Index, + const std::vector<Annotation>&, + Type, + bool, + int, + bool, + MemoryIdxT*, + MemargT) { return Ok{}; } - Result<> makeSIMDLoadStoreLane( - Index, SIMDLoadStoreLaneOp, MemoryIdxT*, MemargT, uint8_t) { + Result<> makeStore(Index, + const std::vector<Annotation>&, + Type, + int, + bool, + MemoryIdxT*, + MemargT) { + return Ok{}; + } + Result<> makeAtomicRMW(Index, + const std::vector<Annotation>&, + AtomicRMWOp, + Type, + int, + MemoryIdxT*, + MemargT) { + return Ok{}; + } + Result<> makeAtomicCmpxchg( + Index, const std::vector<Annotation>&, Type, int, MemoryIdxT*, MemargT) { + return Ok{}; + } + Result<> makeAtomicWait( + Index, const std::vector<Annotation>&, Type, MemoryIdxT*, MemargT) { + return Ok{}; + } + Result<> makeAtomicNotify(Index, + const std::vector<Annotation>&, + MemoryIdxT*, + MemargT) { + return Ok{}; + } + Result<> makeAtomicFence(Index, const std::vector<Annotation>&) { + return Ok{}; + } + Result<> makeSIMDExtract(Index, + const std::vector<Annotation>&, + SIMDExtractOp, + uint8_t) { + return Ok{}; + } + Result<> makeSIMDReplace(Index, + const std::vector<Annotation>&, + SIMDReplaceOp, + uint8_t) { + return Ok{}; + } + Result<> makeSIMDShuffle(Index, + const std::vector<Annotation>&, + const std::array<uint8_t, 16>&) { + return Ok{}; + } + Result<> + makeSIMDTernary(Index, const std::vector<Annotation>&, SIMDTernaryOp) { + return Ok{}; + } + Result<> makeSIMDShift(Index, const std::vector<Annotation>&, SIMDShiftOp) { + return Ok{}; + } + Result<> makeSIMDLoad( + Index, const std::vector<Annotation>&, SIMDLoadOp, MemoryIdxT*, MemargT) { + return Ok{}; + } + Result<> makeSIMDLoadStoreLane(Index, + const std::vector<Annotation>&, + SIMDLoadStoreLaneOp, + MemoryIdxT*, + MemargT, + uint8_t) { + return Ok{}; + } + Result<> + makeMemoryInit(Index, const std::vector<Annotation>&, MemoryIdxT*, DataIdxT) { + return Ok{}; + } + Result<> makeDataDrop(Index, const std::vector<Annotation>&, DataIdxT) { return Ok{}; } - Result<> makeMemoryInit(Index, MemoryIdxT*, DataIdxT) { return Ok{}; } - Result<> makeDataDrop(Index, DataIdxT) { return Ok{}; } - Result<> makeMemoryCopy(Index, MemoryIdxT*, MemoryIdxT*) { return Ok{}; } - Result<> makeMemoryFill(Index, MemoryIdxT*) { return Ok{}; } - template<typename TypeT> Result<> makePop(Index, TypeT) { return Ok{}; } - Result<> makeCall(Index, FuncIdxT, bool) { return Ok{}; } + Result<> makeMemoryCopy(Index, + const std::vector<Annotation>&, + MemoryIdxT*, + MemoryIdxT*) { + return Ok{}; + } + Result<> makeMemoryFill(Index, const std::vector<Annotation>&, MemoryIdxT*) { + return Ok{}; + } + template<typename TypeT> + Result<> makePop(Index, const std::vector<Annotation>&, TypeT) { + return Ok{}; + } + Result<> makeCall(Index, const std::vector<Annotation>&, FuncIdxT, bool) { + return Ok{}; + } template<typename TypeUseT> - Result<> makeCallIndirect(Index, TableIdxT*, TypeUseT, bool) { + Result<> makeCallIndirect( + Index, const std::vector<Annotation>&, TableIdxT*, TypeUseT, bool) { + return Ok{}; + } + Result<> makeBreak(Index, const std::vector<Annotation>&, LabelIdxT, bool) { + return Ok{}; + } + Result<> makeSwitch(Index, + const std::vector<Annotation>&, + const std::vector<LabelIdxT>&, + LabelIdxT) { + return Ok{}; + } + Result<> makeReturn(Index, const std::vector<Annotation>&) { return Ok{}; } + template<typename HeapTypeT> + Result<> makeRefNull(Index, const std::vector<Annotation>&, HeapTypeT) { + return Ok{}; + } + Result<> makeRefIsNull(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> makeRefFunc(Index, const std::vector<Annotation>&, FuncIdxT) { + return Ok{}; + } + Result<> makeRefEq(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> makeTableGet(Index, const std::vector<Annotation>&, TableIdxT*) { + return Ok{}; + } + Result<> makeTableSet(Index, const std::vector<Annotation>&, TableIdxT*) { + return Ok{}; + } + Result<> makeTableSize(Index, const std::vector<Annotation>&, TableIdxT*) { + return Ok{}; + } + Result<> makeTableGrow(Index, const std::vector<Annotation>&, TableIdxT*) { + return Ok{}; + } + Result<> makeTableFill(Index, const std::vector<Annotation>&, TableIdxT*) { + return Ok{}; + } + Result<> + makeTableCopy(Index, const std::vector<Annotation>&, TableIdxT*, TableIdxT*) { + return Ok{}; + } + Result<> makeThrow(Index, const std::vector<Annotation>&, TagIdxT) { + return Ok{}; + } + Result<> makeRethrow(Index, const std::vector<Annotation>&, LabelIdxT) { + return Ok{}; + } + Result<> makeThrowRef(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> makeTupleMake(Index, const std::vector<Annotation>&, uint32_t) { + return Ok{}; + } + Result<> + makeTupleExtract(Index, const std::vector<Annotation>&, uint32_t, uint32_t) { + return Ok{}; + } + Result<> makeTupleDrop(Index, const std::vector<Annotation>&, uint32_t) { return Ok{}; } - Result<> makeBreak(Index, LabelIdxT, bool) { return Ok{}; } - Result<> makeSwitch(Index, const std::vector<LabelIdxT>&, LabelIdxT) { + template<typename HeapTypeT> + Result<> makeCallRef(Index, const std::vector<Annotation>&, HeapTypeT, bool) { + return Ok{}; + } + Result<> makeRefI31(Index, const std::vector<Annotation>&) { return Ok{}; } + Result<> makeI31Get(Index, const std::vector<Annotation>&, bool) { return Ok{}; } - Result<> makeReturn(Index) { return Ok{}; } - template<typename HeapTypeT> Result<> makeRefNull(Index, HeapTypeT) { + template<typename TypeT> + Result<> makeRefTest(Index, const std::vector<Annotation>&, TypeT) { return Ok{}; } - Result<> makeRefIsNull(Index) { return Ok{}; } - Result<> makeRefFunc(Index, FuncIdxT) { return Ok{}; } - Result<> makeRefEq(Index) { return Ok{}; } - Result<> makeTableGet(Index, TableIdxT*) { return Ok{}; } - Result<> makeTableSet(Index, TableIdxT*) { return Ok{}; } - Result<> makeTableSize(Index, TableIdxT*) { return Ok{}; } - Result<> makeTableGrow(Index, TableIdxT*) { return Ok{}; } - Result<> makeTableFill(Index, TableIdxT*) { return Ok{}; } - Result<> makeTableCopy(Index, TableIdxT*, TableIdxT*) { return Ok{}; } - Result<> makeThrow(Index, TagIdxT) { return Ok{}; } - Result<> makeRethrow(Index, LabelIdxT) { return Ok{}; } - Result<> makeThrowRef(Index) { return Ok{}; } - Result<> makeTupleMake(Index, uint32_t) { return Ok{}; } - Result<> makeTupleExtract(Index, uint32_t, uint32_t) { return Ok{}; } - Result<> makeTupleDrop(Index, uint32_t) { return Ok{}; } - template<typename HeapTypeT> Result<> makeCallRef(Index, HeapTypeT, bool) { + template<typename TypeT> + Result<> makeRefCast(Index, const std::vector<Annotation>&, TypeT) { return Ok{}; } - Result<> makeRefI31(Index) { return Ok{}; } - Result<> makeI31Get(Index, bool) { return Ok{}; } - template<typename TypeT> Result<> makeRefTest(Index, TypeT) { return Ok{}; } - template<typename TypeT> Result<> makeRefCast(Index, TypeT) { return Ok{}; } - Result<> makeBrOn(Index, LabelIdxT, BrOnOp) { return Ok{}; } + Result<> makeBrOn(Index, const std::vector<Annotation>&, LabelIdxT, BrOnOp) { + return Ok{}; + } template<typename TypeT> - Result<> makeBrOn(Index, LabelIdxT, BrOnOp, TypeT, TypeT) { + Result<> makeBrOn( + Index, const std::vector<Annotation>&, LabelIdxT, BrOnOp, TypeT, TypeT) { return Ok{}; } - template<typename HeapTypeT> Result<> makeStructNew(Index, HeapTypeT) { + template<typename HeapTypeT> + Result<> makeStructNew(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } - template<typename HeapTypeT> Result<> makeStructNewDefault(Index, HeapTypeT) { + template<typename HeapTypeT> + Result<> + makeStructNewDefault(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeStructGet(Index, HeapTypeT, FieldIdxT, bool) { + Result<> makeStructGet( + Index, const std::vector<Annotation>&, HeapTypeT, FieldIdxT, bool) { return Ok{}; } template<typename HeapTypeT> - Result<> makeStructSet(Index, HeapTypeT, FieldIdxT) { + Result<> + makeStructSet(Index, const std::vector<Annotation>&, HeapTypeT, FieldIdxT) { return Ok{}; } - template<typename HeapTypeT> Result<> makeArrayNew(Index, HeapTypeT) { + template<typename HeapTypeT> + Result<> makeArrayNew(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } - template<typename HeapTypeT> Result<> makeArrayNewDefault(Index, HeapTypeT) { + template<typename HeapTypeT> + Result<> + makeArrayNewDefault(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeArrayNewData(Index, HeapTypeT, DataIdxT) { + Result<> + makeArrayNewData(Index, const std::vector<Annotation>&, HeapTypeT, DataIdxT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeArrayNewElem(Index, HeapTypeT, ElemIdxT) { + Result<> + makeArrayNewElem(Index, const std::vector<Annotation>&, HeapTypeT, ElemIdxT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeArrayNewFixed(Index, HeapTypeT, uint32_t) { + Result<> makeArrayNewFixed(Index, + const std::vector<Annotation>&, + HeapTypeT, + uint32_t) { return Ok{}; } - template<typename HeapTypeT> Result<> makeArrayGet(Index, HeapTypeT, bool) { + template<typename HeapTypeT> + Result<> + makeArrayGet(Index, const std::vector<Annotation>&, HeapTypeT, bool) { return Ok{}; } - template<typename HeapTypeT> Result<> makeArraySet(Index, HeapTypeT) { + template<typename HeapTypeT> + Result<> makeArraySet(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } - Result<> makeArrayLen(Index) { return Ok{}; } + Result<> makeArrayLen(Index, const std::vector<Annotation>&) { return Ok{}; } template<typename HeapTypeT> - Result<> makeArrayCopy(Index, HeapTypeT, HeapTypeT) { + Result<> + makeArrayCopy(Index, const std::vector<Annotation>&, HeapTypeT, HeapTypeT) { return Ok{}; } - template<typename HeapTypeT> Result<> makeArrayFill(Index, HeapTypeT) { + template<typename HeapTypeT> + Result<> makeArrayFill(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeArrayInitData(Index, HeapTypeT, DataIdxT) { + Result<> makeArrayInitData(Index, + const std::vector<Annotation>&, + HeapTypeT, + DataIdxT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeArrayInitElem(Index, HeapTypeT, ElemIdxT) { - return Ok{}; - } - Result<> makeRefAs(Index, RefAsOp) { return Ok{}; } - Result<> makeStringNew(Index, StringNewOp, bool, MemoryIdxT*) { return Ok{}; } - Result<> makeStringConst(Index, std::string_view) { return Ok{}; } - Result<> makeStringMeasure(Index, StringMeasureOp) { return Ok{}; } - Result<> makeStringEncode(Index, StringEncodeOp, MemoryIdxT*) { return Ok{}; } - Result<> makeStringConcat(Index) { return Ok{}; } - Result<> makeStringEq(Index, StringEqOp) { return Ok{}; } - Result<> makeStringAs(Index, StringAsOp) { return Ok{}; } - Result<> makeStringWTF8Advance(Index) { return Ok{}; } - Result<> makeStringWTF16Get(Index) { return Ok{}; } - Result<> makeStringIterNext(Index) { return Ok{}; } - Result<> makeStringIterMove(Index, StringIterMoveOp) { return Ok{}; } - Result<> makeStringSliceWTF(Index, StringSliceWTFOp) { return Ok{}; } - Result<> makeStringSliceIter(Index) { return Ok{}; } - template<typename HeapTypeT> Result<> makeContNew(Index, HeapTypeT) { + Result<> makeArrayInitElem(Index, + const std::vector<Annotation>&, + HeapTypeT, + ElemIdxT) { + return Ok{}; + } + Result<> makeRefAs(Index, const std::vector<Annotation>&, RefAsOp) { + return Ok{}; + } + Result<> makeStringNew( + Index, const std::vector<Annotation>&, StringNewOp, bool, MemoryIdxT*) { + return Ok{}; + } + Result<> + makeStringConst(Index, const std::vector<Annotation>&, std::string_view) { + return Ok{}; + } + Result<> + makeStringMeasure(Index, const std::vector<Annotation>&, StringMeasureOp) { + return Ok{}; + } + Result<> makeStringEncode(Index, + const std::vector<Annotation>&, + StringEncodeOp, + MemoryIdxT*) { + return Ok{}; + } + Result<> makeStringConcat(Index, const std::vector<Annotation>&) { + return Ok{}; + } + Result<> makeStringEq(Index, const std::vector<Annotation>&, StringEqOp) { + return Ok{}; + } + Result<> makeStringAs(Index, const std::vector<Annotation>&, StringAsOp) { + return Ok{}; + } + Result<> makeStringWTF8Advance(Index, const std::vector<Annotation>&) { + return Ok{}; + } + Result<> makeStringWTF16Get(Index, const std::vector<Annotation>&) { + return Ok{}; + } + Result<> makeStringIterNext(Index, const std::vector<Annotation>&) { + return Ok{}; + } + Result<> + makeStringIterMove(Index, const std::vector<Annotation>&, StringIterMoveOp) { + return Ok{}; + } + Result<> + makeStringSliceWTF(Index, const std::vector<Annotation>&, StringSliceWTFOp) { + return Ok{}; + } + Result<> makeStringSliceIter(Index, const std::vector<Annotation>&) { + return Ok{}; + } + template<typename HeapTypeT> + Result<> makeContNew(Index, const std::vector<Annotation>&, HeapTypeT) { return Ok{}; } template<typename HeapTypeT> - Result<> makeResume(Index, HeapTypeT, const TagLabelListT&) { + Result<> makeResume(Index, + const std::vector<Annotation>&, + HeapTypeT, + const TagLabelListT&) { return Ok{}; } }; @@ -1113,6 +1354,8 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { typeNames; const std::unordered_map<Index, Index>& implicitElemIndices; + std::unordered_map<std::string_view, Index> debugFileIndices; + // The index of the current module element. Index index = 0; @@ -1444,7 +1687,51 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return wasm.memories[0]->name; } - Result<> makeBlock(Index pos, std::optional<Name> label, HeapType type) { + void setSrcLoc(const Annotation& annotation) { + assert(annotation.kind == srcAnnotationKind); + Lexer lexer(annotation.contents); + auto contents = lexer.takeKeyword(); + if (!contents || !lexer.empty()) { + return; + } + + auto fileSize = contents->find(':'); + if (fileSize == contents->npos) { + return; + } + auto file = contents->substr(0, fileSize); + contents = contents->substr(fileSize + 1); + + auto lineSize = contents->find(':'); + if (fileSize == contents->npos) { + return; + } + auto line = Lexer(contents->substr(0, lineSize)).takeU32(); + if (!line) { + return; + } + contents = contents->substr(lineSize + 1); + + auto col = Lexer(*contents).takeU32(); + if (!col) { + return; + } + + // TODO: If we ever parallelize the parse, access to + // `wasm.debugInfoFileNames` will have to be protected by a lock. + auto [it, inserted] = + debugFileIndices.insert({file, debugFileIndices.size()}); + if (inserted) { + assert(wasm.debugInfoFileNames.size() == it->second); + wasm.debugInfoFileNames.push_back(std::string(file)); + } + irBuilder.setDebugLocation({it->second, *line, *col}); + } + + Result<> makeBlock(Index pos, + const std::vector<Annotation>& annotations, + std::optional<Name> label, + HeapType type) { // TODO: validate labels? // TODO: Move error on input types to here? return withLoc(pos, @@ -1452,7 +1739,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { type.getSignature().results)); } - Result<> makeIf(Index pos, std::optional<Name> label, HeapType type) { + Result<> makeIf(Index pos, + const std::vector<Annotation>& annotations, + std::optional<Name> label, + HeapType type) { // TODO: validate labels? // TODO: Move error on input types to here? return withLoc( @@ -1462,7 +1752,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { Result<> visitElse() { return withLoc(irBuilder.visitElse()); } - Result<> makeLoop(Index pos, std::optional<Name> label, HeapType type) { + Result<> makeLoop(Index pos, + const std::vector<Annotation>& annotations, + std::optional<Name> label, + HeapType type) { // TODO: validate labels? // TODO: Move error on input types to here? return withLoc( @@ -1470,7 +1763,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { irBuilder.makeLoop(label ? *label : Name{}, type.getSignature().results)); } - Result<> makeTry(Index pos, std::optional<Name> label, HeapType type) { + Result<> makeTry(Index pos, + const std::vector<Annotation>& annotations, + std::optional<Name> label, + HeapType type) { // TODO: validate labels? // TODO: Move error on input types to here? return withLoc( @@ -1479,6 +1775,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { } Result<> makeTryTable(Index pos, + const std::vector<Annotation>& annotations, std::optional<Name> label, HeapType type, const std::vector<CatchInfo>& info) { @@ -1512,21 +1809,29 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { Result<> visitEnd() { return withLoc(irBuilder.visitEnd()); } - Result<> makeUnreachable(Index pos) { + Result<> makeUnreachable(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeUnreachable()); } - Result<> makeNop(Index pos) { return withLoc(pos, irBuilder.makeNop()); } + Result<> makeNop(Index pos, const std::vector<Annotation>& annotations) { + return withLoc(pos, irBuilder.makeNop()); + } - Result<> makeBinary(Index pos, BinaryOp op) { + Result<> makeBinary(Index pos, + const std::vector<Annotation>& annotations, + BinaryOp op) { return withLoc(pos, irBuilder.makeBinary(op)); } - Result<> makeUnary(Index pos, UnaryOp op) { + Result<> + makeUnary(Index pos, const std::vector<Annotation>& annotations, UnaryOp op) { return withLoc(pos, irBuilder.makeUnary(op)); } - Result<> makeSelect(Index pos, std::vector<Type>* res) { + Result<> makeSelect(Index pos, + const std::vector<Annotation>& annotations, + std::vector<Type>* res) { if (res && res->size()) { if (res->size() > 1) { return in.err(pos, "select may not have more than one result type"); @@ -1536,58 +1841,83 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeSelect()); } - Result<> makeDrop(Index pos) { return withLoc(pos, irBuilder.makeDrop()); } + Result<> makeDrop(Index pos, const std::vector<Annotation>& annotations) { + return withLoc(pos, irBuilder.makeDrop()); + } - Result<> makeMemorySize(Index pos, Name* mem) { + Result<> makeMemorySize(Index pos, + const std::vector<Annotation>& annotations, + Name* mem) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeMemorySize(*m)); } - Result<> makeMemoryGrow(Index pos, Name* mem) { + Result<> makeMemoryGrow(Index pos, + const std::vector<Annotation>& annotations, + Name* mem) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeMemoryGrow(*m)); } - Result<> makeLocalGet(Index pos, Index local) { + Result<> makeLocalGet(Index pos, + const std::vector<Annotation>& annotations, + Index local) { return withLoc(pos, irBuilder.makeLocalGet(local)); } - Result<> makeLocalTee(Index pos, Index local) { + Result<> makeLocalTee(Index pos, + const std::vector<Annotation>& annotations, + Index local) { return withLoc(pos, irBuilder.makeLocalTee(local)); } - Result<> makeLocalSet(Index pos, Index local) { + Result<> makeLocalSet(Index pos, + const std::vector<Annotation>& annotations, + Index local) { return withLoc(pos, irBuilder.makeLocalSet(local)); } - Result<> makeGlobalGet(Index pos, Name global) { + Result<> makeGlobalGet(Index pos, + const std::vector<Annotation>& annotations, + Name global) { return withLoc(pos, irBuilder.makeGlobalGet(global)); } - Result<> makeGlobalSet(Index pos, Name global) { + Result<> makeGlobalSet(Index pos, + const std::vector<Annotation>& annotations, + Name global) { assert(wasm.getGlobalOrNull(global)); return withLoc(pos, irBuilder.makeGlobalSet(global)); } - Result<> makeI32Const(Index pos, uint32_t c) { + Result<> makeI32Const(Index pos, + const std::vector<Annotation>& annotations, + uint32_t c) { return withLoc(pos, irBuilder.makeConst(Literal(c))); } - Result<> makeI64Const(Index pos, uint64_t c) { + Result<> makeI64Const(Index pos, + const std::vector<Annotation>& annotations, + uint64_t c) { return withLoc(pos, irBuilder.makeConst(Literal(c))); } - Result<> makeF32Const(Index pos, float c) { + Result<> + makeF32Const(Index pos, const std::vector<Annotation>& annotations, float c) { return withLoc(pos, irBuilder.makeConst(Literal(c))); } - Result<> makeF64Const(Index pos, double c) { + Result<> makeF64Const(Index pos, + const std::vector<Annotation>& annotations, + double c) { return withLoc(pos, irBuilder.makeConst(Literal(c))); } - Result<> makeI8x16Const(Index pos, const std::array<uint8_t, 16>& vals) { + Result<> makeI8x16Const(Index pos, + const std::vector<Annotation>& annotations, + const std::array<uint8_t, 16>& vals) { std::array<Literal, 16> lanes; for (size_t i = 0; i < 16; ++i) { lanes[i] = Literal(uint32_t(vals[i])); @@ -1595,7 +1925,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeConst(Literal(lanes))); } - Result<> makeI16x8Const(Index pos, const std::array<uint16_t, 8>& vals) { + Result<> makeI16x8Const(Index pos, + const std::vector<Annotation>& annotations, + const std::array<uint16_t, 8>& vals) { std::array<Literal, 8> lanes; for (size_t i = 0; i < 8; ++i) { lanes[i] = Literal(uint32_t(vals[i])); @@ -1603,7 +1935,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeConst(Literal(lanes))); } - Result<> makeI32x4Const(Index pos, const std::array<uint32_t, 4>& vals) { + Result<> makeI32x4Const(Index pos, + const std::vector<Annotation>& annotations, + const std::array<uint32_t, 4>& vals) { std::array<Literal, 4> lanes; for (size_t i = 0; i < 4; ++i) { lanes[i] = Literal(vals[i]); @@ -1611,7 +1945,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeConst(Literal(lanes))); } - Result<> makeI64x2Const(Index pos, const std::array<uint64_t, 2>& vals) { + Result<> makeI64x2Const(Index pos, + const std::vector<Annotation>& annotations, + const std::array<uint64_t, 2>& vals) { std::array<Literal, 2> lanes; for (size_t i = 0; i < 2; ++i) { lanes[i] = Literal(vals[i]); @@ -1619,7 +1955,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeConst(Literal(lanes))); } - Result<> makeF32x4Const(Index pos, const std::array<float, 4>& vals) { + Result<> makeF32x4Const(Index pos, + const std::vector<Annotation>& annotations, + const std::array<float, 4>& vals) { std::array<Literal, 4> lanes; for (size_t i = 0; i < 4; ++i) { lanes[i] = Literal(vals[i]); @@ -1627,7 +1965,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeConst(Literal(lanes))); } - Result<> makeF64x2Const(Index pos, const std::array<double, 2>& vals) { + Result<> makeF64x2Const(Index pos, + const std::vector<Annotation>& annotations, + const std::array<double, 2>& vals) { std::array<Literal, 2> lanes; for (size_t i = 0; i < 2; ++i) { lanes[i] = Literal(vals[i]); @@ -1636,6 +1976,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { } Result<> makeLoad(Index pos, + const std::vector<Annotation>& annotations, Type type, bool signed_, int bytes, @@ -1653,8 +1994,13 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { bytes, signed_, memarg.offset, memarg.align, type, *m)); } - Result<> makeStore( - Index pos, Type type, int bytes, bool isAtomic, Name* mem, Memarg memarg) { + Result<> makeStore(Index pos, + const std::vector<Annotation>& annotations, + Type type, + int bytes, + bool isAtomic, + Name* mem, + Memarg memarg) { auto m = getMemory(pos, mem); CHECK_ERR(m); if (isAtomic) { @@ -1665,67 +2011,104 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { pos, irBuilder.makeStore(bytes, memarg.offset, memarg.align, type, *m)); } - Result<> makeAtomicRMW( - Index pos, AtomicRMWOp op, Type type, int bytes, Name* mem, Memarg memarg) { + Result<> makeAtomicRMW(Index pos, + const std::vector<Annotation>& annotations, + AtomicRMWOp op, + Type type, + int bytes, + Name* mem, + Memarg memarg) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeAtomicRMW(op, bytes, memarg.offset, type, *m)); } - Result<> - makeAtomicCmpxchg(Index pos, Type type, int bytes, Name* mem, Memarg memarg) { + Result<> makeAtomicCmpxchg(Index pos, + const std::vector<Annotation>& annotations, + Type type, + int bytes, + Name* mem, + Memarg memarg) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeAtomicCmpxchg(bytes, memarg.offset, type, *m)); } - Result<> makeAtomicWait(Index pos, Type type, Name* mem, Memarg memarg) { + Result<> makeAtomicWait(Index pos, + const std::vector<Annotation>& annotations, + Type type, + Name* mem, + Memarg memarg) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeAtomicWait(type, memarg.offset, *m)); } - Result<> makeAtomicNotify(Index pos, Name* mem, Memarg memarg) { + Result<> makeAtomicNotify(Index pos, + const std::vector<Annotation>& annotations, + Name* mem, + Memarg memarg) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeAtomicNotify(memarg.offset, *m)); } - Result<> makeAtomicFence(Index pos) { + Result<> makeAtomicFence(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeAtomicFence()); } - Result<> makeSIMDExtract(Index pos, SIMDExtractOp op, uint8_t lane) { + Result<> makeSIMDExtract(Index pos, + const std::vector<Annotation>& annotations, + SIMDExtractOp op, + uint8_t lane) { return withLoc(pos, irBuilder.makeSIMDExtract(op, lane)); } - Result<> makeSIMDReplace(Index pos, SIMDReplaceOp op, uint8_t lane) { + Result<> makeSIMDReplace(Index pos, + const std::vector<Annotation>& annotations, + SIMDReplaceOp op, + uint8_t lane) { return withLoc(pos, irBuilder.makeSIMDReplace(op, lane)); } - Result<> makeSIMDShuffle(Index pos, const std::array<uint8_t, 16>& lanes) { + Result<> makeSIMDShuffle(Index pos, + const std::vector<Annotation>& annotations, + const std::array<uint8_t, 16>& lanes) { return withLoc(pos, irBuilder.makeSIMDShuffle(lanes)); } - Result<> makeSIMDTernary(Index pos, SIMDTernaryOp op) { + Result<> makeSIMDTernary(Index pos, + const std::vector<Annotation>& annotations, + SIMDTernaryOp op) { return withLoc(pos, irBuilder.makeSIMDTernary(op)); } - Result<> makeSIMDShift(Index pos, SIMDShiftOp op) { + Result<> makeSIMDShift(Index pos, + const std::vector<Annotation>& annotations, + SIMDShiftOp op) { return withLoc(pos, irBuilder.makeSIMDShift(op)); } - Result<> makeSIMDLoad(Index pos, SIMDLoadOp op, Name* mem, Memarg memarg) { + Result<> makeSIMDLoad(Index pos, + const std::vector<Annotation>& annotations, + SIMDLoadOp op, + Name* mem, + Memarg memarg) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeSIMDLoad(op, memarg.offset, memarg.align, *m)); } - Result<> makeSIMDLoadStoreLane( - Index pos, SIMDLoadStoreLaneOp op, Name* mem, Memarg memarg, uint8_t lane) { + Result<> makeSIMDLoadStoreLane(Index pos, + const std::vector<Annotation>& annotations, + SIMDLoadStoreLaneOp op, + Name* mem, + Memarg memarg, + uint8_t lane) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, @@ -1733,17 +2116,25 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { op, memarg.offset, memarg.align, lane, *m)); } - Result<> makeMemoryInit(Index pos, Name* mem, Name data) { + Result<> makeMemoryInit(Index pos, + const std::vector<Annotation>& annotations, + Name* mem, + Name data) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeMemoryInit(data, *m)); } - Result<> makeDataDrop(Index pos, Name data) { + Result<> makeDataDrop(Index pos, + const std::vector<Annotation>& annotations, + Name data) { return withLoc(pos, irBuilder.makeDataDrop(data)); } - Result<> makeMemoryCopy(Index pos, Name* destMem, Name* srcMem) { + Result<> makeMemoryCopy(Index pos, + const std::vector<Annotation>& annotations, + Name* destMem, + Name* srcMem) { auto destMemory = getMemory(pos, destMem); CHECK_ERR(destMemory); auto srcMemory = getMemory(pos, srcMem); @@ -1751,85 +2142,119 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeMemoryCopy(*destMemory, *srcMemory)); } - Result<> makeMemoryFill(Index pos, Name* mem) { + Result<> makeMemoryFill(Index pos, + const std::vector<Annotation>& annotations, + Name* mem) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeMemoryFill(*m)); } - Result<> makePop(Index pos, Type type) { + Result<> + makePop(Index pos, const std::vector<Annotation>& annotations, Type type) { return withLoc(pos, irBuilder.makePop(type)); } - Result<> makeCall(Index pos, Name func, bool isReturn) { + Result<> makeCall(Index pos, + const std::vector<Annotation>& annotations, + Name func, + bool isReturn) { return withLoc(pos, irBuilder.makeCall(func, isReturn)); } - Result<> - makeCallIndirect(Index pos, Name* table, HeapType type, bool isReturn) { + Result<> makeCallIndirect(Index pos, + const std::vector<Annotation>& annotations, + Name* table, + HeapType type, + bool isReturn) { auto t = getTable(pos, table); CHECK_ERR(t); return withLoc(pos, irBuilder.makeCallIndirect(*t, type, isReturn)); } - Result<> makeBreak(Index pos, Index label, bool isConditional) { + Result<> makeBreak(Index pos, + const std::vector<Annotation>& annotations, + Index label, + bool isConditional) { return withLoc(pos, irBuilder.makeBreak(label, isConditional)); } - Result<> - makeSwitch(Index pos, const std::vector<Index> labels, Index defaultLabel) { + Result<> makeSwitch(Index pos, + const std::vector<Annotation>& annotations, + const std::vector<Index> labels, + Index defaultLabel) { return withLoc(pos, irBuilder.makeSwitch(labels, defaultLabel)); } - Result<> makeReturn(Index pos) { + Result<> makeReturn(Index pos, const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeReturn()); } - Result<> makeRefNull(Index pos, HeapType type) { + Result<> makeRefNull(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeRefNull(type)); } - Result<> makeRefIsNull(Index pos) { + Result<> makeRefIsNull(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeRefIsNull()); } - Result<> makeRefFunc(Index pos, Name func) { + Result<> makeRefFunc(Index pos, + const std::vector<Annotation>& annotations, + Name func) { return withLoc(pos, irBuilder.makeRefFunc(func)); } - Result<> makeRefEq(Index pos) { return withLoc(pos, irBuilder.makeRefEq()); } + Result<> makeRefEq(Index pos, const std::vector<Annotation>& annotations) { + return withLoc(pos, irBuilder.makeRefEq()); + } - Result<> makeTableGet(Index pos, Name* table) { + Result<> makeTableGet(Index pos, + const std::vector<Annotation>& annotations, + Name* table) { auto t = getTable(pos, table); CHECK_ERR(t); return withLoc(pos, irBuilder.makeTableGet(*t)); } - Result<> makeTableSet(Index pos, Name* table) { + Result<> makeTableSet(Index pos, + const std::vector<Annotation>& annotations, + Name* table) { auto t = getTable(pos, table); CHECK_ERR(t); return withLoc(pos, irBuilder.makeTableSet(*t)); } - Result<> makeTableSize(Index pos, Name* table) { + Result<> makeTableSize(Index pos, + const std::vector<Annotation>& annotations, + Name* table) { auto t = getTable(pos, table); CHECK_ERR(t); return withLoc(pos, irBuilder.makeTableSize(*t)); } - Result<> makeTableGrow(Index pos, Name* table) { + Result<> makeTableGrow(Index pos, + const std::vector<Annotation>& annotations, + Name* table) { auto t = getTable(pos, table); CHECK_ERR(t); return withLoc(pos, irBuilder.makeTableGrow(*t)); } - Result<> makeTableFill(Index pos, Name* table) { + Result<> makeTableFill(Index pos, + const std::vector<Annotation>& annotations, + Name* table) { auto t = getTable(pos, table); CHECK_ERR(t); return withLoc(pos, irBuilder.makeTableFill(*t)); } - Result<> makeTableCopy(Index pos, Name* destTable, Name* srcTable) { + Result<> makeTableCopy(Index pos, + const std::vector<Annotation>& annotations, + Name* destTable, + Name* srcTable) { auto dest = getTable(pos, destTable); CHECK_ERR(dest); auto src = getTable(pos, srcTable); @@ -1837,51 +2262,71 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeTableCopy(*dest, *src)); } - Result<> makeThrow(Index pos, Name tag) { + Result<> + makeThrow(Index pos, const std::vector<Annotation>& annotations, Name tag) { return withLoc(pos, irBuilder.makeThrow(tag)); } - Result<> makeRethrow(Index pos, Index label) { + Result<> makeRethrow(Index pos, + const std::vector<Annotation>& annotations, + Index label) { return withLoc(pos, irBuilder.makeRethrow(label)); } - Result<> makeThrowRef(Index pos) { + Result<> makeThrowRef(Index pos, const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeThrowRef()); } - Result<> makeTupleMake(Index pos, uint32_t arity) { + Result<> makeTupleMake(Index pos, + const std::vector<Annotation>& annotations, + uint32_t arity) { return withLoc(pos, irBuilder.makeTupleMake(arity)); } - Result<> makeTupleExtract(Index pos, uint32_t arity, uint32_t index) { + Result<> makeTupleExtract(Index pos, + const std::vector<Annotation>& annotations, + uint32_t arity, + uint32_t index) { return withLoc(pos, irBuilder.makeTupleExtract(arity, index)); } - Result<> makeTupleDrop(Index pos, uint32_t arity) { + Result<> makeTupleDrop(Index pos, + const std::vector<Annotation>& annotations, + uint32_t arity) { return withLoc(pos, irBuilder.makeTupleDrop(arity)); } - Result<> makeCallRef(Index pos, HeapType type, bool isReturn) { + Result<> makeCallRef(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + bool isReturn) { return withLoc(pos, irBuilder.makeCallRef(type, isReturn)); } - Result<> makeRefI31(Index pos) { + Result<> makeRefI31(Index pos, const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeRefI31()); } - Result<> makeI31Get(Index pos, bool signed_) { + Result<> makeI31Get(Index pos, + const std::vector<Annotation>& annotations, + bool signed_) { return withLoc(pos, irBuilder.makeI31Get(signed_)); } - Result<> makeRefTest(Index pos, Type type) { + Result<> makeRefTest(Index pos, + const std::vector<Annotation>& annotations, + Type type) { return withLoc(pos, irBuilder.makeRefTest(type)); } - Result<> makeRefCast(Index pos, Type type) { + Result<> makeRefCast(Index pos, + const std::vector<Annotation>& annotations, + Type type) { return withLoc(pos, irBuilder.makeRefCast(type)); } Result<> makeBrOn(Index pos, + const std::vector<Annotation>& annotations, Index label, BrOnOp op, Type in = Type::none, @@ -1889,136 +2334,205 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeBrOn(label, op, in, out)); } - Result<> makeStructNew(Index pos, HeapType type) { + Result<> makeStructNew(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeStructNew(type)); } - Result<> makeStructNewDefault(Index pos, HeapType type) { + Result<> makeStructNewDefault(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeStructNewDefault(type)); } - Result<> makeStructGet(Index pos, HeapType type, Index field, bool signed_) { + Result<> makeStructGet(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + Index field, + bool signed_) { return withLoc(pos, irBuilder.makeStructGet(type, field, signed_)); } - Result<> makeStructSet(Index pos, HeapType type, Index field) { + Result<> makeStructSet(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + Index field) { return withLoc(pos, irBuilder.makeStructSet(type, field)); } - Result<> makeArrayNew(Index pos, HeapType type) { + Result<> makeArrayNew(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeArrayNew(type)); } - Result<> makeArrayNewDefault(Index pos, HeapType type) { + Result<> makeArrayNewDefault(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeArrayNewDefault(type)); } - Result<> makeArrayNewData(Index pos, HeapType type, Name data) { + Result<> makeArrayNewData(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + Name data) { return withLoc(pos, irBuilder.makeArrayNewData(type, data)); } - Result<> makeArrayNewElem(Index pos, HeapType type, Name elem) { + Result<> makeArrayNewElem(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + Name elem) { return withLoc(pos, irBuilder.makeArrayNewElem(type, elem)); } - Result<> makeArrayNewFixed(Index pos, HeapType type, uint32_t arity) { + Result<> makeArrayNewFixed(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + uint32_t arity) { return withLoc(pos, irBuilder.makeArrayNewFixed(type, arity)); } - Result<> makeArrayGet(Index pos, HeapType type, bool signed_) { + Result<> makeArrayGet(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + bool signed_) { return withLoc(pos, irBuilder.makeArrayGet(type, signed_)); } - Result<> makeArraySet(Index pos, HeapType type) { + Result<> makeArraySet(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeArraySet(type)); } - Result<> makeArrayLen(Index pos) { + Result<> makeArrayLen(Index pos, const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeArrayLen()); } - Result<> makeArrayCopy(Index pos, HeapType destType, HeapType srcType) { + Result<> makeArrayCopy(Index pos, + const std::vector<Annotation>& annotations, + HeapType destType, + HeapType srcType) { return withLoc(pos, irBuilder.makeArrayCopy(destType, srcType)); } - Result<> makeArrayFill(Index pos, HeapType type) { + Result<> makeArrayFill(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeArrayFill(type)); } - Result<> makeArrayInitData(Index pos, HeapType type, Name data) { + Result<> makeArrayInitData(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + Name data) { return withLoc(pos, irBuilder.makeArrayInitData(type, data)); } - Result<> makeArrayInitElem(Index pos, HeapType type, Name elem) { + Result<> makeArrayInitElem(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + Name elem) { return withLoc(pos, irBuilder.makeArrayInitElem(type, elem)); } - Result<> makeRefAs(Index pos, RefAsOp op) { + Result<> + makeRefAs(Index pos, const std::vector<Annotation>& annotations, RefAsOp op) { return withLoc(pos, irBuilder.makeRefAs(op)); } - Result<> makeStringNew(Index pos, StringNewOp op, bool try_, Name* mem) { + Result<> makeStringNew(Index pos, + const std::vector<Annotation>& annotations, + StringNewOp op, + bool try_, + Name* mem) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeStringNew(op, try_, *m)); } - Result<> makeStringConst(Index pos, std::string_view str) { + Result<> makeStringConst(Index pos, + const std::vector<Annotation>& annotations, + std::string_view str) { return withLoc(pos, irBuilder.makeStringConst(Name(str))); } - Result<> makeStringMeasure(Index pos, StringMeasureOp op) { + Result<> makeStringMeasure(Index pos, + const std::vector<Annotation>& annotations, + StringMeasureOp op) { return withLoc(pos, irBuilder.makeStringMeasure(op)); } - Result<> makeStringEncode(Index pos, StringEncodeOp op, Name* mem) { + Result<> makeStringEncode(Index pos, + const std::vector<Annotation>& annotations, + StringEncodeOp op, + Name* mem) { auto m = getMemory(pos, mem); CHECK_ERR(m); return withLoc(pos, irBuilder.makeStringEncode(op, *m)); } - Result<> makeStringConcat(Index pos) { + Result<> makeStringConcat(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeStringConcat()); } - Result<> makeStringEq(Index pos, StringEqOp op) { + Result<> makeStringEq(Index pos, + const std::vector<Annotation>& annotations, + StringEqOp op) { return withLoc(pos, irBuilder.makeStringEq(op)); } - Result<> makeStringAs(Index pos, StringAsOp op) { + Result<> makeStringAs(Index pos, + const std::vector<Annotation>& annotations, + StringAsOp op) { return withLoc(pos, irBuilder.makeStringAs(op)); } - Result<> makeStringWTF8Advance(Index pos) { + Result<> makeStringWTF8Advance(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeStringWTF8Advance()); } - Result<> makeStringWTF16Get(Index pos) { + Result<> makeStringWTF16Get(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeStringWTF16Get()); } - Result<> makeStringIterNext(Index pos) { + Result<> makeStringIterNext(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeStringIterNext()); } - Result<> makeStringIterMove(Index pos, StringIterMoveOp op) { + Result<> makeStringIterMove(Index pos, + const std::vector<Annotation>& annotations, + StringIterMoveOp op) { return withLoc(pos, irBuilder.makeStringIterMove(op)); } - Result<> makeStringSliceWTF(Index pos, StringSliceWTFOp op) { + Result<> makeStringSliceWTF(Index pos, + const std::vector<Annotation>& annotations, + StringSliceWTFOp op) { return withLoc(pos, irBuilder.makeStringSliceWTF(op)); } - Result<> makeStringSliceIter(Index pos) { + Result<> makeStringSliceIter(Index pos, + const std::vector<Annotation>& annotations) { return withLoc(pos, irBuilder.makeStringSliceIter()); } - Result<> makeContNew(Index pos, HeapType type) { + Result<> makeContNew(Index pos, + const std::vector<Annotation>& annotations, + HeapType type) { return withLoc(pos, irBuilder.makeContNew(type)); } - Result<> - makeResume(Index pos, HeapType type, const TagLabelListT& tagLabels) { + Result<> makeResume(Index pos, + const std::vector<Annotation>& annotations, + HeapType type, + const TagLabelListT& tagLabels) { std::vector<Name> tags; std::vector<Index> labels; tags.reserve(tagLabels.size()); diff --git a/src/parser/lexer.cpp b/src/parser/lexer.cpp index 07931d69b..8c7542dd7 100644 --- a/src/parser/lexer.cpp +++ b/src/parser/lexer.cpp @@ -28,6 +28,8 @@ using namespace std::string_view_literals; namespace wasm::WATParser { +Name srcAnnotationKind("src"); + namespace { // ================ @@ -348,6 +350,47 @@ struct LexIdCtx : LexCtx { } }; +struct LexAnnotationResult : LexResult { + Annotation annotation; +}; + +struct LexAnnotationCtx : LexCtx { + std::string_view kind; + size_t kindSize = 0; + std::string_view contents; + size_t contentsSize = 0; + + explicit LexAnnotationCtx(std::string_view in) : LexCtx(in) {} + + void startKind() { kind = next(); } + + void takeKind(size_t size) { + kindSize += size; + take(size); + } + + void setKind(std::string_view kind) { + this->kind = kind; + kindSize = kind.size(); + } + + void startContents() { contents = next(); } + + void takeContents(size_t size) { + contentsSize += size; + take(size); + } + + std::optional<LexAnnotationResult> lexed() { + if (auto basic = LexCtx::lexed()) { + return LexAnnotationResult{ + *basic, + {Name(kind.substr(0, kindSize)), contents.substr(0, contentsSize)}}; + } + return std::nullopt; + } +}; + std::optional<LexResult> lparen(std::string_view in) { LexCtx ctx(in); ctx.takePrefix("("sv); @@ -360,6 +403,101 @@ std::optional<LexResult> rparen(std::string_view in) { return ctx.lexed(); } +std::optional<LexResult> idchar(std::string_view); +std::optional<LexResult> space(std::string_view); +std::optional<LexResult> keyword(std::string_view); +std::optional<LexIntResult> integer(std::string_view); +std::optional<LexFloatResult> float_(std::string_view); +std::optional<LexStrResult> str(std::string_view); +std::optional<LexIdResult> ident(std::string_view); + +// annotation ::= ';;@' [^\n]* | '(@'idchar+ annotelem* ')' +// annotelem ::= keyword | reserved | uN | sN | fN | string | id +// | '(' annotelem* ')' | '(@'idchar+ annotelem* ')' +std::optional<LexAnnotationResult> annotation(std::string_view in) { + LexAnnotationCtx ctx(in); + if (ctx.takePrefix(";;@"sv)) { + ctx.setKind(srcAnnotationKind.str); + ctx.startContents(); + if (auto size = ctx.next().find('\n'); size != ""sv.npos) { + ctx.takeContents(size); + } else { + ctx.takeContents(ctx.next().size()); + } + } else if (ctx.takePrefix("(@"sv)) { + ctx.startKind(); + bool hasIdchar = false; + while (auto lexed = idchar(ctx.next())) { + ctx.takeKind(1); + hasIdchar = true; + } + if (!hasIdchar) { + return std::nullopt; + } + ctx.startContents(); + size_t depth = 1; + while (true) { + if (ctx.empty()) { + return std::nullopt; + } + if (auto lexed = space(ctx.next())) { + ctx.takeContents(lexed->span.size()); + continue; + } + if (auto lexed = keyword(ctx.next())) { + ctx.takeContents(lexed->span.size()); + continue; + } + if (auto lexed = integer(ctx.next())) { + ctx.takeContents(lexed->span.size()); + continue; + } + if (auto lexed = float_(ctx.next())) { + ctx.takeContents(lexed->span.size()); + continue; + } + if (auto lexed = str(ctx.next())) { + ctx.takeContents(lexed->span.size()); + continue; + } + if (auto lexed = ident(ctx.next())) { + ctx.takeContents(lexed->span.size()); + continue; + } + if (ctx.startsWith("(@"sv)) { + ctx.takeContents(2); + bool hasIdchar = false; + while (auto lexed = idchar(ctx.next())) { + ctx.takeContents(1); + hasIdchar = true; + } + if (!hasIdchar) { + return std::nullopt; + } + ++depth; + continue; + } + if (ctx.startsWith("("sv)) { + ctx.takeContents(1); + ++depth; + continue; + } + if (ctx.startsWith(")"sv)) { + --depth; + if (depth == 0) { + ctx.take(1); + break; + } + ctx.takeContents(1); + continue; + } + // Unrecognized token. + return std::nullopt; + } + } + return ctx.lexed(); +} + // comment ::= linecomment | blockcomment // linecomment ::= ';;' linechar* ('\n' | eof) // linechar ::= c:char (if c != '\n') @@ -375,7 +513,7 @@ std::optional<LexResult> comment(std::string_view in) { } // Line comment - if (ctx.takePrefix(";;"sv)) { + if (!ctx.startsWith(";;@"sv) && ctx.takePrefix(";;"sv)) { if (auto size = ctx.next().find('\n'); size != ""sv.npos) { ctx.take(size); } else { @@ -934,8 +1072,17 @@ std::optional<std::string_view> Token::getID() const { } void Lexer::skipSpace() { - if (auto ctx = space(next())) { - index += ctx->span.size(); + while (true) { + if (auto ctx = annotation(next())) { + index += ctx->span.size(); + annotations.push_back(ctx->annotation); + continue; + } + if (auto ctx = space(next())) { + index += ctx->span.size(); + continue; + } + break; } } diff --git a/src/parser/lexer.h b/src/parser/lexer.h index aab074e6c..1a93d3e99 100644 --- a/src/parser/lexer.h +++ b/src/parser/lexer.h @@ -140,25 +140,29 @@ struct Token { friend std::ostream& operator<<(std::ostream& os, const Token&); }; +// =========== +// Annotations +// =========== + +struct Annotation { + Name kind; + std::string_view contents; +}; + +extern Name srcAnnotationKind; + // ===== // Lexer // ===== -// Lexer's purpose is twofold. First, it wraps a buffer to provide a tokenizing -// iterator over it. Second, it implements that iterator itself. Also provides -// utilities for locating the text position of tokens within the buffer. Text -// positions are computed on demand rather than eagerly because they are -// typically only needed when there is an error to report. struct Lexer { private: std::string_view buffer; size_t index = 0; std::optional<Token> curr; + std::vector<Annotation> annotations; public: - // The end sentinel. - Lexer() = default; - Lexer(std::string_view buffer) : buffer(buffer) { setIndex(0); } size_t getIndex() const { return index; } @@ -382,6 +386,7 @@ public: std::string_view next() const { return buffer.substr(index); } void advance() { + annotations.clear(); skipSpace(); lexToken(); } @@ -410,6 +415,13 @@ public: [[nodiscard]] Err err(std::string reason) { return err(getPos(), reason); } + const std::vector<Annotation> getAnnotations() { return annotations; } + std::vector<Annotation> takeAnnotations() { return std::move(annotations); } + + void setAnnotations(std::vector<Annotation>&& annotations) { + this->annotations = std::move(annotations); + } + private: void skipSpace(); void lexToken(); diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 007f815ac..987f0f5aa 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -46,10 +46,14 @@ template<typename Ctx> Result<typename Ctx::GlobalTypeT> globaltype(Ctx&); template<typename Ctx> Result<uint32_t> tupleArity(Ctx&); // Instructions -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<> foldedBlockinstr(Ctx&, const std::vector<Annotation>&); +template<typename Ctx> +MaybeResult<> unfoldedBlockinstr(Ctx&, const std::vector<Annotation>&); +template<typename Ctx> +MaybeResult<> blockinstr(Ctx&, const std::vector<Annotation>&); +template<typename Ctx> +MaybeResult<> plaininstr(Ctx&, const std::vector<Annotation>&); template<typename Ctx> MaybeResult<> instr(Ctx&); template<typename Ctx> MaybeResult<> foldedinstr(Ctx&); template<typename Ctx> Result<> instrs(Ctx&); @@ -57,118 +61,250 @@ template<typename Ctx> Result<> foldedinstrs(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<> block(Ctx&, bool); -template<typename Ctx> MaybeResult<> ifelse(Ctx&, bool); -template<typename Ctx> MaybeResult<> loop(Ctx&, bool); -template<typename Ctx> MaybeResult<> trycatch(Ctx&, bool); +template<typename Ctx> +MaybeResult<> block(Ctx&, const std::vector<Annotation>&, bool); +template<typename Ctx> +MaybeResult<> ifelse(Ctx&, const std::vector<Annotation>&, bool); +template<typename Ctx> +MaybeResult<> loop(Ctx&, const std::vector<Annotation>&, bool); +template<typename Ctx> +MaybeResult<> trycatch(Ctx&, const std::vector<Annotation>&, bool); template<typename Ctx> MaybeResult<typename Ctx::CatchT> catchinstr(Ctx&); -template<typename Ctx> MaybeResult<> trytable(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<> makeConst(Ctx&, Index, Type type); +template<typename Ctx> +MaybeResult<> trytable(Ctx&, const std::vector<Annotation>&, bool); +template<typename Ctx> +Result<> makeUnreachable(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeNop(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeBinary(Ctx&, Index, const std::vector<Annotation>&, BinaryOp op); +template<typename Ctx> +Result<> makeUnary(Ctx&, Index, const std::vector<Annotation>&, UnaryOp op); +template<typename Ctx> +Result<> makeSelect(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeDrop(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeMemorySize(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeMemoryGrow(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeLocalGet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeLocalTee(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeLocalSet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeGlobalGet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeGlobalSet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeConst(Ctx&, Index, const std::vector<Annotation>&, Type type); +template<typename Ctx> +Result<> makeLoad(Ctx&, + Index, + const std::vector<Annotation>&, + Type type, + bool signed_, + int bytes, + bool isAtomic); +template<typename Ctx> +Result<> makeStore(Ctx&, + Index, + const std::vector<Annotation>&, + Type type, + int bytes, + bool isAtomic); +template<typename Ctx> +Result<> makeAtomicRMW(Ctx&, + Index, + const std::vector<Annotation>&, + AtomicRMWOp op, + Type type, + uint8_t bytes); +template<typename Ctx> +Result<> makeAtomicCmpxchg( + Ctx&, Index, const std::vector<Annotation>&, Type type, uint8_t bytes); +template<typename Ctx> +Result<> makeAtomicWait(Ctx&, Index, const std::vector<Annotation>&, Type type); +template<typename Ctx> +Result<> makeAtomicNotify(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeAtomicFence(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeSIMDExtract( + Ctx&, Index, const std::vector<Annotation>&, SIMDExtractOp op, size_t lanes); +template<typename Ctx> +Result<> makeSIMDReplace( + Ctx&, Index, const std::vector<Annotation>&, SIMDReplaceOp op, size_t lanes); +template<typename Ctx> +Result<> makeSIMDShuffle(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> +makeSIMDTernary(Ctx&, Index, const std::vector<Annotation>&, SIMDTernaryOp op); +template<typename Ctx> +Result<> +makeSIMDShift(Ctx&, Index, const std::vector<Annotation>&, SIMDShiftOp op); +template<typename Ctx> +Result<> makeSIMDLoad( + Ctx&, Index, const std::vector<Annotation>&, SIMDLoadOp op, int bytes); +template<typename Ctx> +Result<> makeSIMDLoadStoreLane(Ctx&, + Index, + const std::vector<Annotation>&, + SIMDLoadStoreLaneOp op, + int bytes); +template<typename Ctx> +Result<> makeMemoryInit(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeDataDrop(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeMemoryCopy(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeMemoryFill(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makePop(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeCall(Ctx&, Index, const std::vector<Annotation>&, bool isReturn); +template<typename Ctx> +Result<> +makeCallIndirect(Ctx&, Index, const std::vector<Annotation>&, bool isReturn); +template<typename Ctx> +Result<> +makeBreak(Ctx&, Index, const std::vector<Annotation>&, bool isConditional); +template<typename Ctx> +Result<> makeBreakTable(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeReturn(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRefNull(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRefIsNull(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRefFunc(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRefEq(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTableGet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTableSet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTableSize(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTableGrow(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTableFill(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTableCopy(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeThrow(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRethrow(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeThrowRef(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTupleMake(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTupleExtract(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeTupleDrop(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> +makeCallRef(Ctx&, Index, const std::vector<Annotation>&, bool isReturn); +template<typename Ctx> +Result<> makeRefI31(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeI31Get(Ctx&, Index, const std::vector<Annotation>&, bool signed_); +template<typename Ctx> +Result<> makeRefTest(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRefCast(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> +makeBrOnNull(Ctx&, Index, const std::vector<Annotation>&, bool onFail = false); +template<typename Ctx> +Result<> +makeBrOnCast(Ctx&, Index, const std::vector<Annotation>&, bool onFail = false); +template<typename Ctx> +Result<> +makeStructNew(Ctx&, Index, const std::vector<Annotation>&, bool default_); +template<typename Ctx> +Result<> makeStructGet(Ctx&, + Index, + const std::vector<Annotation>&, + bool signed_ = false); +template<typename Ctx> +Result<> makeStructSet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> +makeArrayNew(Ctx&, Index, const std::vector<Annotation>&, bool default_); +template<typename Ctx> +Result<> makeArrayNewData(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayNewElem(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayNewFixed(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> +makeArrayGet(Ctx&, Index, const std::vector<Annotation>&, bool signed_ = false); +template<typename Ctx> +Result<> makeArraySet(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayLen(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayCopy(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayFill(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayInitData(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeArrayInitElem(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeRefAs(Ctx&, Index, const std::vector<Annotation>&, RefAsOp op); +template<typename Ctx> +Result<> makeStringNew( + Ctx&, Index, const std::vector<Annotation>&, StringNewOp op, bool try_); +template<typename Ctx> +Result<> makeStringConst(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeStringMeasure(Ctx&, + Index, + const std::vector<Annotation>&, + StringMeasureOp op); +template<typename Ctx> +Result<> makeStringEncode(Ctx&, + Index, + const std::vector<Annotation>&, + StringEncodeOp op); +template<typename Ctx> +Result<> makeStringConcat(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeStringEq(Ctx&, Index, const std::vector<Annotation>&, StringEqOp); template<typename Ctx> Result<> -makeLoad(Ctx&, Index, Type type, bool signed_, int bytes, bool isAtomic); -template<typename Ctx> -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<> makeCall(Ctx&, Index, bool isReturn); -template<typename Ctx> Result<> makeCallIndirect(Ctx&, Index, bool isReturn); -template<typename Ctx> Result<> makeBreak(Ctx&, Index, bool isConditional); -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<> makeTableCopy(Ctx&, Index); -template<typename Ctx> Result<> makeThrow(Ctx&, Index); -template<typename Ctx> Result<> makeRethrow(Ctx&, Index); -template<typename Ctx> Result<> makeThrowRef(Ctx&, Index); -template<typename Ctx> Result<> makeTupleMake(Ctx&, Index); -template<typename Ctx> Result<> makeTupleExtract(Ctx&, Index); -template<typename Ctx> Result<> makeTupleDrop(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); -template<typename Ctx> Result<> makeContNew(Ctx&, Index); -template<typename Ctx> Result<> makeResume(Ctx&, Index); +makeStringAs(Ctx&, Index, const std::vector<Annotation>&, StringAsOp op); +template<typename Ctx> +Result<> makeStringWTF8Advance(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeStringWTF16Get(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeStringIterNext(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeStringIterMove(Ctx&, + Index, + const std::vector<Annotation>&, + StringIterMoveOp op); +template<typename Ctx> +Result<> makeStringSliceWTF(Ctx&, + Index, + const std::vector<Annotation>&, + StringSliceWTFOp op); +template<typename Ctx> +Result<> makeStringSliceIter(Ctx&, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeContNew(Ctx*, Index, const std::vector<Annotation>&); +template<typename Ctx> +Result<> makeResume(Ctx&, Index, const std::vector<Annotation>&); // Modules template<typename Ctx> MaybeResult<Index> maybeTypeidx(Ctx& ctx); @@ -222,12 +358,18 @@ template<typename Ctx> Result<> module(Ctx&); template<typename Ctx> struct WithPosition { Ctx& ctx; Index original; + std::vector<Annotation> annotations; - WithPosition(Ctx& ctx, Index pos) : ctx(ctx), original(ctx.in.getPos()) { + WithPosition(Ctx& ctx, Index pos) + : ctx(ctx), original(ctx.in.getPos()), + annotations(ctx.in.takeAnnotations()) { ctx.in.setIndex(pos); } - ~WithPosition() { ctx.in.setIndex(original); } + ~WithPosition() { + ctx.in.setIndex(original); + ctx.in.setAnnotations(std::move(annotations)); + } }; // Deduction guide to satisfy -Wctad-maybe-unsupported. @@ -690,57 +832,75 @@ template<typename Ctx> Result<uint32_t> tupleArity(Ctx& ctx) { // Instructions // ============ +template<typename Ctx> +void setSrcLoc(Ctx& ctx, const std::vector<Annotation>& annotations) { + for (const auto& annotation : annotations) { + if (annotation.kind == srcAnnotationKind) { + ctx.setSrcLoc(annotation); + } + } +} + // blockinstr ::= block | loop | if-else | try-catch | try_table -template<typename Ctx> MaybeResult<> foldedBlockinstr(Ctx& ctx) { - if (auto i = block(ctx, true)) { +template<typename Ctx> +MaybeResult<> foldedBlockinstr(Ctx& ctx, + const std::vector<Annotation>& annotations) { + setSrcLoc(ctx, annotations); + if (auto i = block(ctx, annotations, true)) { return i; } - if (auto i = ifelse(ctx, true)) { + if (auto i = ifelse(ctx, annotations, true)) { return i; } - if (auto i = loop(ctx, true)) { + if (auto i = loop(ctx, annotations, true)) { return i; } - if (auto i = trycatch(ctx, true)) { + if (auto i = trycatch(ctx, annotations, true)) { return i; } - if (auto i = trytable(ctx, true)) { + if (auto i = trytable(ctx, annotations, true)) { return i; } return {}; } -template<typename Ctx> MaybeResult<> unfoldedBlockinstr(Ctx& ctx) { - if (auto i = block(ctx, false)) { +template<typename Ctx> +MaybeResult<> unfoldedBlockinstr(Ctx& ctx, + const std::vector<Annotation>& annotations) { + setSrcLoc(ctx, annotations); + if (auto i = block(ctx, annotations, false)) { return i; } - if (auto i = ifelse(ctx, false)) { + if (auto i = ifelse(ctx, annotations, false)) { return i; } - if (auto i = loop(ctx, false)) { + if (auto i = loop(ctx, annotations, false)) { return i; } - if (auto i = trycatch(ctx, false)) { + if (auto i = trycatch(ctx, annotations, false)) { return i; } - if (auto i = trytable(ctx, false)) { + if (auto i = trytable(ctx, annotations, false)) { return i; } return {}; } -template<typename Ctx> MaybeResult<> blockinstr(Ctx& ctx) { - if (auto i = foldedBlockinstr(ctx)) { +template<typename Ctx> +MaybeResult<> blockinstr(Ctx& ctx, const std::vector<Annotation>& annotations) { + if (auto i = foldedBlockinstr(ctx, annotations)) { return i; } - if (auto i = unfoldedBlockinstr(ctx)) { + if (auto i = unfoldedBlockinstr(ctx, annotations)) { return i; } return {}; } // plaininstr ::= ... all plain instructions ... -template<typename Ctx> MaybeResult<> plaininstr(Ctx& ctx) { +template<typename Ctx> +MaybeResult<> plaininstr(Ctx& ctx, const std::vector<Annotation>& annotations) { + setSrcLoc(ctx, annotations); auto pos = ctx.in.getPos(); auto keyword = ctx.in.takeKeyword(); if (!keyword) { @@ -762,10 +922,10 @@ template<typename Ctx> MaybeResult<> instr(Ctx& ctx) { return {}; } } - if (auto inst = blockinstr(ctx)) { + if (auto inst = blockinstr(ctx, ctx.in.getAnnotations())) { return inst; } - if (auto inst = plaininstr(ctx)) { + if (auto inst = plaininstr(ctx, ctx.in.getAnnotations())) { return inst; } // TODO: Handle folded plain instructions as well. @@ -785,28 +945,35 @@ template<typename Ctx> MaybeResult<> foldedinstr(Ctx& ctx) { // 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<size_t, std::optional<size_t>>> foldedInstrs; + struct InstrInfo { + size_t start; + std::optional<size_t> end; + std::vector<Annotation> annotations; + }; + std::vector<InstrInfo> foldedInstrs; do { if (ctx.in.takeRParen()) { // We've reached the end of a folded instruction. Parse it for real. - auto [start, end] = foldedInstrs.back(); - if (!end) { + auto info = std::move(foldedInstrs.back()); + if (!info.end) { return ctx.in.err("unexpected end of folded instruction"); } foldedInstrs.pop_back(); - WithPosition with(ctx, start); - auto inst = plaininstr(ctx); + WithPosition with(ctx, info.start); + auto inst = plaininstr(ctx, std::move(info.annotations)); assert(inst && "unexpectedly failed to parse instruction"); CHECK_ERR(inst); - assert(ctx.in.getPos() == *end && "expected end of instruction"); + assert(ctx.in.getPos() == *info.end && "expected end of instruction"); continue; } + auto annotations = ctx.in.takeAnnotations(); + // We're not ending an instruction, so we must be starting a new one. Maybe // it is a block instruction. - if (auto blockinst = foldedBlockinstr(ctx)) { + if (auto blockinst = foldedBlockinstr(ctx, annotations)) { CHECK_ERR(blockinst); continue; } @@ -815,13 +982,13 @@ template<typename Ctx> MaybeResult<> foldedinstr(Ctx& ctx) { if (!ctx.in.takeLParen()) { return ctx.in.err("expected folded instruction"); } - foldedInstrs.push_back({ctx.in.getPos(), {}}); + foldedInstrs.push_back({ctx.in.getPos(), {}, std::move(annotations)}); // Consume the span for the instruction without meaningfully parsing it yet. // It will be parsed for real using the real context after its s-expression // children have been found and parsed. NullCtx nullCtx(ctx.in); - if (auto inst = plaininstr(nullCtx)) { + if (auto inst = plaininstr(nullCtx, {})) { CHECK_ERR(inst); ctx.in = nullCtx.in; } else { @@ -829,8 +996,8 @@ template<typename Ctx> MaybeResult<> foldedinstr(Ctx& ctx) { } // The folded instruction we just started ends here. - assert(!foldedInstrs.back().second); - foldedInstrs.back().second = ctx.in.getPos(); + assert(!foldedInstrs.back().end); + foldedInstrs.back().end = ctx.in.getPos(); } while (!foldedInstrs.empty()); return Ok{}; @@ -903,7 +1070,9 @@ 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<> block(Ctx& ctx, bool folded) { +template<typename Ctx> +MaybeResult<> +block(Ctx& ctx, const std::vector<Annotation>& annotations, bool folded) { auto pos = ctx.in.getPos(); if ((folded && !ctx.in.takeSExprStart("block"sv)) || @@ -916,7 +1085,7 @@ template<typename Ctx> MaybeResult<> block(Ctx& ctx, bool folded) { auto type = blocktype(ctx); CHECK_ERR(type); - ctx.makeBlock(pos, label, *type); + ctx.makeBlock(pos, annotations, label, *type); CHECK_ERR(instrs(ctx)); @@ -940,7 +1109,9 @@ template<typename Ctx> MaybeResult<> block(Ctx& ctx, bool folded) { // if ::= 'if' label blocktype instr1* ('else' id1? instr2*)? 'end' id2? // | '(' 'if' label blocktype foldedinstr* '(' 'then' instr1* ')' // ('(' 'else' instr2* ')')? ')' -template<typename Ctx> MaybeResult<> ifelse(Ctx& ctx, bool folded) { +template<typename Ctx> +MaybeResult<> +ifelse(Ctx& ctx, const std::vector<Annotation>& annotations, bool folded) { auto pos = ctx.in.getPos(); if ((folded && !ctx.in.takeSExprStart("if"sv)) || @@ -957,7 +1128,7 @@ template<typename Ctx> MaybeResult<> ifelse(Ctx& ctx, bool folded) { CHECK_ERR(foldedinstrs(ctx)); } - ctx.makeIf(pos, label, *type); + ctx.makeIf(pos, annotations, label, *type); if (folded && !ctx.in.takeSExprStart("then"sv)) { return ctx.in.err("expected 'then' before if instructions"); @@ -1004,7 +1175,9 @@ template<typename Ctx> MaybeResult<> ifelse(Ctx& ctx, bool folded) { // loop ::= 'loop' label blocktype instr* 'end' id? // | '(' 'loop' label blocktype instr* ')' -template<typename Ctx> MaybeResult<> loop(Ctx& ctx, bool folded) { +template<typename Ctx> +MaybeResult<> +loop(Ctx& ctx, const std::vector<Annotation>& annotations, bool folded) { auto pos = ctx.in.getPos(); if ((folded && !ctx.in.takeSExprStart("loop"sv)) || @@ -1017,7 +1190,7 @@ template<typename Ctx> MaybeResult<> loop(Ctx& ctx, bool folded) { auto type = blocktype(ctx); CHECK_ERR(type); - ctx.makeLoop(pos, label, *type); + ctx.makeLoop(pos, annotations, label, *type); CHECK_ERR(instrs(ctx)); @@ -1045,7 +1218,9 @@ template<typename Ctx> MaybeResult<> loop(Ctx& ctx, bool folded) { // | 'try' label blocktype instr* 'deledate' label // | '(' 'try' label blocktype '(' 'do' instr* ')' // '(' 'delegate' label ')' ')' -template<typename Ctx> MaybeResult<> trycatch(Ctx& ctx, bool folded) { +template<typename Ctx> +MaybeResult<> +trycatch(Ctx& ctx, const std::vector<Annotation>& annotations, bool folded) { auto pos = ctx.in.getPos(); if ((folded && !ctx.in.takeSExprStart("try"sv)) || @@ -1058,7 +1233,7 @@ template<typename Ctx> MaybeResult<> trycatch(Ctx& ctx, bool folded) { auto type = blocktype(ctx); CHECK_ERR(type); - CHECK_ERR(ctx.makeTry(pos, label, *type)); + CHECK_ERR(ctx.makeTry(pos, annotations, label, *type)); if (folded) { if (!ctx.in.takeSExprStart("do"sv)) { @@ -1229,7 +1404,9 @@ template<typename Ctx> MaybeResult<typename Ctx::CatchT> catchinstr(Ctx& ctx) { // trytable ::= 'try_table' label blocktype catchinstr* instr* 'end' id? // | '(' 'try_table' label blocktype catchinstr* instr* ')' -template<typename Ctx> MaybeResult<> trytable(Ctx& ctx, bool folded) { +template<typename Ctx> +MaybeResult<> +trytable(Ctx& ctx, const std::vector<Annotation>& annotations, bool folded) { auto pos = ctx.in.getPos(); if ((folded && !ctx.in.takeSExprStart("try_table"sv)) || @@ -1248,7 +1425,7 @@ template<typename Ctx> MaybeResult<> trytable(Ctx& ctx, bool folded) { ctx.appendCatch(catches, *c); } - CHECK_ERR(ctx.makeTryTable(pos, label, *type, catches)); + CHECK_ERR(ctx.makeTryTable(pos, annotations, label, *type, catches)); CHECK_ERR(instrs(ctx)); @@ -1269,95 +1446,132 @@ template<typename Ctx> MaybeResult<> trytable(Ctx& ctx, bool folded) { return ctx.visitEnd(); } -template<typename Ctx> Result<> makeUnreachable(Ctx& ctx, Index pos) { - return ctx.makeUnreachable(pos); +template<typename Ctx> +Result<> makeUnreachable(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeUnreachable(pos, annotations); } -template<typename Ctx> Result<> makeNop(Ctx& ctx, Index pos) { - return ctx.makeNop(pos); +template<typename Ctx> +Result<> +makeNop(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeNop(pos, annotations); } -template<typename Ctx> Result<> makeBinary(Ctx& ctx, Index pos, BinaryOp op) { - return ctx.makeBinary(pos, op); +template<typename Ctx> +Result<> makeBinary(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + BinaryOp op) { + return ctx.makeBinary(pos, annotations, op); } -template<typename Ctx> Result<> makeUnary(Ctx& ctx, Index pos, UnaryOp op) { - return ctx.makeUnary(pos, op); +template<typename Ctx> +Result<> makeUnary(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + UnaryOp op) { + return ctx.makeUnary(pos, annotations, op); } -template<typename Ctx> Result<> makeSelect(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeSelect(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto res = results(ctx); CHECK_ERR(res); - return ctx.makeSelect(pos, res.getPtr()); + return ctx.makeSelect(pos, annotations, res.getPtr()); } -template<typename Ctx> Result<> makeDrop(Ctx& ctx, Index pos) { - return ctx.makeDrop(pos); +template<typename Ctx> +Result<> +makeDrop(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeDrop(pos, annotations); } -template<typename Ctx> Result<> makeMemorySize(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeMemorySize(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); - return ctx.makeMemorySize(pos, mem.getPtr()); + return ctx.makeMemorySize(pos, annotations, mem.getPtr()); } -template<typename Ctx> Result<> makeMemoryGrow(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeMemoryGrow(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); - return ctx.makeMemoryGrow(pos, mem.getPtr()); + return ctx.makeMemoryGrow(pos, annotations, mem.getPtr()); } -template<typename Ctx> Result<> makeLocalGet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeLocalGet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto local = localidx(ctx); CHECK_ERR(local); - return ctx.makeLocalGet(pos, *local); + return ctx.makeLocalGet(pos, annotations, *local); } -template<typename Ctx> Result<> makeLocalTee(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeLocalTee(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto local = localidx(ctx); CHECK_ERR(local); - return ctx.makeLocalTee(pos, *local); + return ctx.makeLocalTee(pos, annotations, *local); } -template<typename Ctx> Result<> makeLocalSet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeLocalSet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto local = localidx(ctx); CHECK_ERR(local); - return ctx.makeLocalSet(pos, *local); + return ctx.makeLocalSet(pos, annotations, *local); } -template<typename Ctx> Result<> makeGlobalGet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeGlobalGet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto global = globalidx(ctx); CHECK_ERR(global); - return ctx.makeGlobalGet(pos, *global); + return ctx.makeGlobalGet(pos, annotations, *global); } -template<typename Ctx> Result<> makeGlobalSet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeGlobalSet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto global = globalidx(ctx); CHECK_ERR(global); - return ctx.makeGlobalSet(pos, *global); + return ctx.makeGlobalSet(pos, annotations, *global); } -template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { +template<typename Ctx> +Result<> makeConst(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + Type type) { assert(type.isBasic()); switch (type.getBasic()) { case Type::i32: if (auto c = ctx.in.takeI32()) { - return ctx.makeI32Const(pos, *c); + return ctx.makeI32Const(pos, annotations, *c); } return ctx.in.err("expected i32"); case Type::i64: if (auto c = ctx.in.takeI64()) { - return ctx.makeI64Const(pos, *c); + return ctx.makeI64Const(pos, annotations, *c); } return ctx.in.err("expected i64"); case Type::f32: if (auto c = ctx.in.takeF32()) { - return ctx.makeF32Const(pos, *c); + return ctx.makeF32Const(pos, annotations, *c); } return ctx.in.err("expected f32"); case Type::f64: if (auto c = ctx.in.takeF64()) { - return ctx.makeF64Const(pos, *c); + return ctx.makeF64Const(pos, annotations, *c); } return ctx.in.err("expected f64"); case Type::v128: @@ -1370,7 +1584,7 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } vals[i] = *val; } - return ctx.makeI8x16Const(pos, vals); + return ctx.makeI8x16Const(pos, annotations, vals); } if (ctx.in.takeKeyword("i16x8"sv)) { std::array<uint16_t, 8> vals; @@ -1381,7 +1595,7 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } vals[i] = *val; } - return ctx.makeI16x8Const(pos, vals); + return ctx.makeI16x8Const(pos, annotations, vals); } if (ctx.in.takeKeyword("i32x4"sv)) { std::array<uint32_t, 4> vals; @@ -1392,7 +1606,7 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } vals[i] = *val; } - return ctx.makeI32x4Const(pos, vals); + return ctx.makeI32x4Const(pos, annotations, vals); } if (ctx.in.takeKeyword("i64x2"sv)) { std::array<uint64_t, 2> vals; @@ -1403,7 +1617,7 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } vals[i] = *val; } - return ctx.makeI64x2Const(pos, vals); + return ctx.makeI64x2Const(pos, annotations, vals); } if (ctx.in.takeKeyword("f32x4"sv)) { std::array<float, 4> vals; @@ -1414,7 +1628,7 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } vals[i] = *val; } - return ctx.makeF32x4Const(pos, vals); + return ctx.makeF32x4Const(pos, annotations, vals); } if (ctx.in.takeKeyword("f64x2"sv)) { std::array<double, 2> vals; @@ -1425,7 +1639,7 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } vals[i] = *val; } - return ctx.makeF64x2Const(pos, vals); + return ctx.makeF64x2Const(pos, annotations, vals); } return ctx.in.err("expected SIMD vector shape"); case Type::none: @@ -1436,82 +1650,125 @@ template<typename Ctx> Result<> makeConst(Ctx& ctx, Index pos, Type type) { } template<typename Ctx> -Result<> makeLoad( - Ctx& ctx, Index pos, Type type, bool signed_, int bytes, bool isAtomic) { +Result<> makeLoad(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + Type type, + bool signed_, + int bytes, + bool isAtomic) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); CHECK_ERR(arg); - return ctx.makeLoad(pos, type, signed_, bytes, isAtomic, mem.getPtr(), *arg); + return ctx.makeLoad( + pos, annotations, type, signed_, bytes, isAtomic, mem.getPtr(), *arg); } template<typename Ctx> -Result<> makeStore(Ctx& ctx, Index pos, Type type, int bytes, bool isAtomic) { +Result<> makeStore(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + Type type, + int bytes, + bool isAtomic) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); CHECK_ERR(arg); - return ctx.makeStore(pos, type, bytes, isAtomic, mem.getPtr(), *arg); + return ctx.makeStore( + pos, annotations, type, bytes, isAtomic, mem.getPtr(), *arg); } template<typename Ctx> -Result<> -makeAtomicRMW(Ctx& ctx, Index pos, AtomicRMWOp op, Type type, uint8_t bytes) { +Result<> makeAtomicRMW(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + AtomicRMWOp op, + Type type, + uint8_t bytes) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); CHECK_ERR(arg); - return ctx.makeAtomicRMW(pos, op, type, bytes, mem.getPtr(), *arg); + return ctx.makeAtomicRMW( + pos, annotations, op, type, bytes, mem.getPtr(), *arg); } template<typename Ctx> -Result<> makeAtomicCmpxchg(Ctx& ctx, Index pos, Type type, uint8_t bytes) { +Result<> makeAtomicCmpxchg(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + Type type, + uint8_t bytes) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); CHECK_ERR(arg); - return ctx.makeAtomicCmpxchg(pos, type, bytes, mem.getPtr(), *arg); + return ctx.makeAtomicCmpxchg( + pos, annotations, type, bytes, mem.getPtr(), *arg); } -template<typename Ctx> Result<> makeAtomicWait(Ctx& ctx, Index pos, Type type) { +template<typename Ctx> +Result<> makeAtomicWait(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + Type type) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, type == Type::i32 ? 4 : 8); CHECK_ERR(arg); - return ctx.makeAtomicWait(pos, type, mem.getPtr(), *arg); + return ctx.makeAtomicWait(pos, annotations, type, mem.getPtr(), *arg); } -template<typename Ctx> Result<> makeAtomicNotify(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeAtomicNotify(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, 4); CHECK_ERR(arg); - return ctx.makeAtomicNotify(pos, mem.getPtr(), *arg); + return ctx.makeAtomicNotify(pos, annotations, mem.getPtr(), *arg); } -template<typename Ctx> Result<> makeAtomicFence(Ctx& ctx, Index pos) { - return ctx.makeAtomicFence(pos); +template<typename Ctx> +Result<> makeAtomicFence(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeAtomicFence(pos, annotations); } template<typename Ctx> -Result<> makeSIMDExtract(Ctx& ctx, Index pos, SIMDExtractOp op, size_t) { +Result<> makeSIMDExtract(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + SIMDExtractOp op, + size_t) { auto lane = ctx.in.takeU8(); if (!lane) { return ctx.in.err("expected lane index"); } - return ctx.makeSIMDExtract(pos, op, *lane); + return ctx.makeSIMDExtract(pos, annotations, op, *lane); } template<typename Ctx> -Result<> makeSIMDReplace(Ctx& ctx, Index pos, SIMDReplaceOp op, size_t lanes) { +Result<> makeSIMDReplace(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + SIMDReplaceOp op, + size_t lanes) { auto lane = ctx.in.takeU8(); if (!lane) { return ctx.in.err("expected lane index"); } - return ctx.makeSIMDReplace(pos, op, *lane); + return ctx.makeSIMDReplace(pos, annotations, op, *lane); } -template<typename Ctx> Result<> makeSIMDShuffle(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeSIMDShuffle(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { std::array<uint8_t, 16> lanes; for (int i = 0; i < 16; ++i) { auto lane = ctx.in.takeU8(); @@ -1520,31 +1777,44 @@ template<typename Ctx> Result<> makeSIMDShuffle(Ctx& ctx, Index pos) { } lanes[i] = *lane; } - return ctx.makeSIMDShuffle(pos, lanes); + return ctx.makeSIMDShuffle(pos, annotations, lanes); } template<typename Ctx> -Result<> makeSIMDTernary(Ctx& ctx, Index pos, SIMDTernaryOp op) { - return ctx.makeSIMDTernary(pos, op); +Result<> makeSIMDTernary(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + SIMDTernaryOp op) { + return ctx.makeSIMDTernary(pos, annotations, op); } template<typename Ctx> -Result<> makeSIMDShift(Ctx& ctx, Index pos, SIMDShiftOp op) { - return ctx.makeSIMDShift(pos, op); +Result<> makeSIMDShift(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + SIMDShiftOp op) { + return ctx.makeSIMDShift(pos, annotations, op); } template<typename Ctx> -Result<> makeSIMDLoad(Ctx& ctx, Index pos, SIMDLoadOp op, int bytes) { +Result<> makeSIMDLoad(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + SIMDLoadOp op, + int bytes) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); auto arg = memarg(ctx, bytes); CHECK_ERR(arg); - return ctx.makeSIMDLoad(pos, op, mem.getPtr(), *arg); + return ctx.makeSIMDLoad(pos, annotations, op, mem.getPtr(), *arg); } template<typename Ctx> -Result<> -makeSIMDLoadStoreLane(Ctx& ctx, Index pos, SIMDLoadStoreLaneOp op, int bytes) { +Result<> makeSIMDLoadStoreLane(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + SIMDLoadStoreLaneOp op, + int bytes) { auto reset = ctx.in.getPos(); auto retry = [&]() -> Result<> { @@ -1557,7 +1827,8 @@ makeSIMDLoadStoreLane(Ctx& ctx, Index pos, SIMDLoadStoreLaneOp op, int bytes) { if (!lane) { return ctx.in.err("expected lane index"); } - return ctx.makeSIMDLoadStoreLane(pos, op, nullptr, *arg, *lane); + return ctx.makeSIMDLoadStoreLane( + pos, annotations, op, nullptr, *arg, *lane); }; auto mem = maybeMemidx(ctx); @@ -1570,10 +1841,14 @@ makeSIMDLoadStoreLane(Ctx& ctx, Index pos, SIMDLoadStoreLaneOp op, int bytes) { if (!lane) { return retry(); } - return ctx.makeSIMDLoadStoreLane(pos, op, mem.getPtr(), *arg, *lane); + return ctx.makeSIMDLoadStoreLane( + pos, annotations, op, mem.getPtr(), *arg, *lane); } -template<typename Ctx> Result<> makeMemoryInit(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeMemoryInit(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto reset = ctx.in.getPos(); auto retry = [&]() -> Result<> { @@ -1582,7 +1857,7 @@ template<typename Ctx> Result<> makeMemoryInit(Ctx& ctx, Index pos) { WithPosition with(ctx, reset); auto data = dataidx(ctx); CHECK_ERR(data); - return ctx.makeMemoryInit(pos, nullptr, *data); + return ctx.makeMemoryInit(pos, annotations, nullptr, *data); }; auto mem = maybeMemidx(ctx); @@ -1593,16 +1868,21 @@ template<typename Ctx> Result<> makeMemoryInit(Ctx& ctx, Index pos) { if (data.getErr()) { return retry(); } - return ctx.makeMemoryInit(pos, mem.getPtr(), *data); + return ctx.makeMemoryInit(pos, annotations, mem.getPtr(), *data); } -template<typename Ctx> Result<> makeDataDrop(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeDataDrop(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto data = dataidx(ctx); CHECK_ERR(data); - return ctx.makeDataDrop(pos, *data); + return ctx.makeDataDrop(pos, annotations, *data); } -template<typename Ctx> Result<> makeMemoryCopy(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeMemoryCopy(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto destMem = maybeMemidx(ctx); CHECK_ERR(destMem); std::optional<typename Ctx::MemoryIdxT> srcMem = std::nullopt; @@ -1611,44 +1891,64 @@ template<typename Ctx> Result<> makeMemoryCopy(Ctx& ctx, Index pos) { CHECK_ERR(mem); srcMem = *mem; } - return ctx.makeMemoryCopy(pos, destMem.getPtr(), srcMem ? &*srcMem : nullptr); + return ctx.makeMemoryCopy( + pos, annotations, destMem.getPtr(), srcMem ? &*srcMem : nullptr); } -template<typename Ctx> Result<> makeMemoryFill(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeMemoryFill(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); - return ctx.makeMemoryFill(pos, mem.getPtr()); + return ctx.makeMemoryFill(pos, annotations, mem.getPtr()); } -template<typename Ctx> Result<> makePop(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makePop(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = valtype(ctx); CHECK_ERR(type); - return ctx.makePop(pos, *type); + return ctx.makePop(pos, annotations, *type); } -template<typename Ctx> Result<> makeCall(Ctx& ctx, Index pos, bool isReturn) { +template<typename Ctx> +Result<> makeCall(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool isReturn) { auto func = funcidx(ctx); CHECK_ERR(func); - return ctx.makeCall(pos, *func, isReturn); + return ctx.makeCall(pos, annotations, *func, isReturn); } template<typename Ctx> -Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { +Result<> makeCallIndirect(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool isReturn) { auto table = maybeTableidx(ctx); CHECK_ERR(table); auto type = typeuse(ctx); CHECK_ERR(type); - return ctx.makeCallIndirect(pos, table.getPtr(), *type, isReturn); + return ctx.makeCallIndirect( + pos, annotations, table.getPtr(), *type, isReturn); } template<typename Ctx> -Result<> makeBreak(Ctx& ctx, Index pos, bool isConditional) { +Result<> makeBreak(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool isConditional) { auto label = labelidx(ctx); CHECK_ERR(label); - return ctx.makeBreak(pos, *label, isConditional); + return ctx.makeBreak(pos, annotations, *label, isConditional); } -template<typename Ctx> Result<> makeBreakTable(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeBreakTable(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { std::vector<typename Ctx::LabelIdxT> labels; while (true) { // Parse at least one label; return an error only if we parse none. @@ -1662,64 +1962,86 @@ template<typename Ctx> Result<> makeBreakTable(Ctx& ctx, Index pos) { } auto defaultLabel = labels.back(); labels.pop_back(); - return ctx.makeSwitch(pos, labels, defaultLabel); + return ctx.makeSwitch(pos, annotations, labels, defaultLabel); } -template<typename Ctx> Result<> makeReturn(Ctx& ctx, Index pos) { - return ctx.makeReturn(pos); +template<typename Ctx> +Result<> +makeReturn(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeReturn(pos, annotations); } -template<typename Ctx> Result<> makeRefNull(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeRefNull(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto t = heaptype(ctx); CHECK_ERR(t); - return ctx.makeRefNull(pos, *t); + return ctx.makeRefNull(pos, annotations, *t); } -template<typename Ctx> Result<> makeRefIsNull(Ctx& ctx, Index pos) { - return ctx.makeRefIsNull(pos); +template<typename Ctx> +Result<> +makeRefIsNull(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeRefIsNull(pos, annotations); } -template<typename Ctx> Result<> makeRefFunc(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeRefFunc(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto func = funcidx(ctx); CHECK_ERR(func); - return ctx.makeRefFunc(pos, *func); + return ctx.makeRefFunc(pos, annotations, *func); } -template<typename Ctx> Result<> makeRefEq(Ctx& ctx, Index pos) { - return ctx.makeRefEq(pos); +template<typename Ctx> +Result<> +makeRefEq(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeRefEq(pos, annotations); } -template<typename Ctx> Result<> makeTableGet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTableGet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto table = maybeTableidx(ctx); CHECK_ERR(table); - return ctx.makeTableGet(pos, table.getPtr()); + return ctx.makeTableGet(pos, annotations, table.getPtr()); } -template<typename Ctx> Result<> makeTableSet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTableSet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto table = maybeTableidx(ctx); CHECK_ERR(table); - return ctx.makeTableSet(pos, table.getPtr()); + return ctx.makeTableSet(pos, annotations, table.getPtr()); } -template<typename Ctx> Result<> makeTableSize(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTableSize(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto table = maybeTableidx(ctx); CHECK_ERR(table); - return ctx.makeTableSize(pos, table.getPtr()); + return ctx.makeTableSize(pos, annotations, table.getPtr()); } -template<typename Ctx> Result<> makeTableGrow(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTableGrow(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto table = maybeTableidx(ctx); CHECK_ERR(table); - return ctx.makeTableGrow(pos, table.getPtr()); + return ctx.makeTableGrow(pos, annotations, table.getPtr()); } -template<typename Ctx> Result<> makeTableFill(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTableFill(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto table = maybeTableidx(ctx); CHECK_ERR(table); - return ctx.makeTableFill(pos, table.getPtr()); + return ctx.makeTableFill(pos, annotations, table.getPtr()); } -template<typename Ctx> Result<> makeTableCopy(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTableCopy(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto destTable = maybeTableidx(ctx); CHECK_ERR(destTable); auto srcTable = maybeTableidx(ctx); @@ -1727,279 +2049,401 @@ template<typename Ctx> Result<> makeTableCopy(Ctx& ctx, Index pos) { if (destTable && !srcTable) { return ctx.in.err("expected table index or identifier"); } - return ctx.makeTableCopy(pos, destTable.getPtr(), srcTable.getPtr()); + return ctx.makeTableCopy( + pos, annotations, destTable.getPtr(), srcTable.getPtr()); } -template<typename Ctx> Result<> makeThrow(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeThrow(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto tag = tagidx(ctx); CHECK_ERR(tag); - return ctx.makeThrow(pos, *tag); + return ctx.makeThrow(pos, annotations, *tag); } -template<typename Ctx> Result<> makeRethrow(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeRethrow(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto label = labelidx(ctx); CHECK_ERR(label); - return ctx.makeRethrow(pos, *label); + return ctx.makeRethrow(pos, annotations, *label); } -template<typename Ctx> Result<> makeThrowRef(Ctx& ctx, Index pos) { - return ctx.makeThrowRef(pos); +template<typename Ctx> +Result<> +makeThrowRef(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeThrowRef(pos, annotations); } -template<typename Ctx> Result<> makeTupleMake(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTupleMake(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto arity = tupleArity(ctx); CHECK_ERR(arity); - return ctx.makeTupleMake(pos, *arity); + return ctx.makeTupleMake(pos, annotations, *arity); } -template<typename Ctx> Result<> makeTupleExtract(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeTupleExtract(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto arity = tupleArity(ctx); CHECK_ERR(arity); auto index = ctx.in.takeU32(); if (!index) { return ctx.in.err("expected tuple index"); } - return ctx.makeTupleExtract(pos, *arity, *index); + return ctx.makeTupleExtract(pos, annotations, *arity, *index); } -template<typename Ctx> Result<> makeTupleDrop(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeTupleDrop(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto arity = tupleArity(ctx); CHECK_ERR(arity); - return ctx.makeTupleDrop(pos, *arity); + return ctx.makeTupleDrop(pos, annotations, *arity); } template<typename Ctx> -Result<> makeCallRef(Ctx& ctx, Index pos, bool isReturn) { +Result<> makeCallRef(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool isReturn) { auto type = typeidx(ctx); CHECK_ERR(type); - return ctx.makeCallRef(pos, *type, isReturn); + return ctx.makeCallRef(pos, annotations, *type, isReturn); } -template<typename Ctx> Result<> makeRefI31(Ctx& ctx, Index pos) { - return ctx.makeRefI31(pos); +template<typename Ctx> +Result<> +makeRefI31(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeRefI31(pos, annotations); } -template<typename Ctx> Result<> makeI31Get(Ctx& ctx, Index pos, bool signed_) { - return ctx.makeI31Get(pos, signed_); +template<typename Ctx> +Result<> makeI31Get(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool signed_) { + return ctx.makeI31Get(pos, annotations, signed_); } -template<typename Ctx> Result<> makeRefTest(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeRefTest(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = reftype(ctx); CHECK_ERR(type); - return ctx.makeRefTest(pos, *type); + return ctx.makeRefTest(pos, annotations, *type); } -template<typename Ctx> Result<> makeRefCast(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeRefCast(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = reftype(ctx); CHECK_ERR(type); - return ctx.makeRefCast(pos, *type); + return ctx.makeRefCast(pos, annotations, *type); } -template<typename Ctx> Result<> makeBrOnNull(Ctx& ctx, Index pos, bool onFail) { +template<typename Ctx> +Result<> makeBrOnNull(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool onFail) { auto label = labelidx(ctx); CHECK_ERR(label); - return ctx.makeBrOn(pos, *label, onFail ? BrOnNonNull : BrOnNull); + return ctx.makeBrOn( + pos, annotations, *label, onFail ? BrOnNonNull : BrOnNull); } -template<typename Ctx> Result<> makeBrOnCast(Ctx& ctx, Index pos, bool onFail) { +template<typename Ctx> +Result<> makeBrOnCast(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool onFail) { auto label = labelidx(ctx); CHECK_ERR(label); auto in = reftype(ctx); CHECK_ERR(in); auto out = reftype(ctx); CHECK_ERR(out); - return ctx.makeBrOn(pos, *label, onFail ? BrOnCastFail : BrOnCast, *in, *out); + return ctx.makeBrOn( + pos, annotations, *label, onFail ? BrOnCastFail : BrOnCast, *in, *out); } template<typename Ctx> -Result<> makeStructNew(Ctx& ctx, Index pos, bool default_) { +Result<> makeStructNew(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool default_) { auto type = typeidx(ctx); CHECK_ERR(type); if (default_) { - return ctx.makeStructNewDefault(pos, *type); + return ctx.makeStructNewDefault(pos, annotations, *type); } - return ctx.makeStructNew(pos, *type); + return ctx.makeStructNew(pos, annotations, *type); } template<typename Ctx> -Result<> makeStructGet(Ctx& ctx, Index pos, bool signed_) { +Result<> makeStructGet(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool signed_) { auto type = typeidx(ctx); CHECK_ERR(type); auto field = fieldidx(ctx, *type); CHECK_ERR(field); - return ctx.makeStructGet(pos, *type, *field, signed_); + return ctx.makeStructGet(pos, annotations, *type, *field, signed_); } -template<typename Ctx> Result<> makeStructSet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeStructSet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); auto field = fieldidx(ctx, *type); CHECK_ERR(field); - return ctx.makeStructSet(pos, *type, *field); + return ctx.makeStructSet(pos, annotations, *type, *field); } template<typename Ctx> -Result<> makeArrayNew(Ctx& ctx, Index pos, bool default_) { +Result<> makeArrayNew(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool default_) { auto type = typeidx(ctx); CHECK_ERR(type); if (default_) { - return ctx.makeArrayNewDefault(pos, *type); + return ctx.makeArrayNewDefault(pos, annotations, *type); } - return ctx.makeArrayNew(pos, *type); + return ctx.makeArrayNew(pos, annotations, *type); } -template<typename Ctx> Result<> makeArrayNewData(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeArrayNewData(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); auto data = dataidx(ctx); CHECK_ERR(data); - return ctx.makeArrayNewData(pos, *type, *data); + return ctx.makeArrayNewData(pos, annotations, *type, *data); } -template<typename Ctx> Result<> makeArrayNewElem(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeArrayNewElem(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); auto elem = elemidx(ctx); CHECK_ERR(elem); - return ctx.makeArrayNewElem(pos, *type, *elem); + return ctx.makeArrayNewElem(pos, annotations, *type, *elem); } -template<typename Ctx> Result<> makeArrayNewFixed(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeArrayNewFixed(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); auto arity = ctx.in.takeU32(); if (!arity) { return ctx.in.err(pos, "expected array.new_fixed arity"); } - return ctx.makeArrayNewFixed(pos, *type, *arity); + return ctx.makeArrayNewFixed(pos, annotations, *type, *arity); } template<typename Ctx> -Result<> makeArrayGet(Ctx& ctx, Index pos, bool signed_) { +Result<> makeArrayGet(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + bool signed_) { auto type = typeidx(ctx); CHECK_ERR(type); - return ctx.makeArrayGet(pos, *type, signed_); + return ctx.makeArrayGet(pos, annotations, *type, signed_); } -template<typename Ctx> Result<> makeArraySet(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeArraySet(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); - return ctx.makeArraySet(pos, *type); + return ctx.makeArraySet(pos, annotations, *type); } -template<typename Ctx> Result<> makeArrayLen(Ctx& ctx, Index pos) { - return ctx.makeArrayLen(pos); +template<typename Ctx> +Result<> +makeArrayLen(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { + return ctx.makeArrayLen(pos, annotations); } -template<typename Ctx> Result<> makeArrayCopy(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeArrayCopy(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto destType = typeidx(ctx); CHECK_ERR(destType); auto srcType = typeidx(ctx); CHECK_ERR(srcType); - return ctx.makeArrayCopy(pos, *destType, *srcType); + return ctx.makeArrayCopy(pos, annotations, *destType, *srcType); } -template<typename Ctx> Result<> makeArrayFill(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeArrayFill(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); - return ctx.makeArrayFill(pos, *type); + return ctx.makeArrayFill(pos, annotations, *type); } -template<typename Ctx> Result<> makeArrayInitData(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeArrayInitData(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); auto data = dataidx(ctx); CHECK_ERR(data); - return ctx.makeArrayInitData(pos, *type, *data); + return ctx.makeArrayInitData(pos, annotations, *type, *data); } -template<typename Ctx> Result<> makeArrayInitElem(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeArrayInitElem(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); auto elem = elemidx(ctx); - return ctx.makeArrayInitElem(pos, *type, *elem); + return ctx.makeArrayInitElem(pos, annotations, *type, *elem); } -template<typename Ctx> Result<> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) { - return ctx.makeRefAs(pos, op); +template<typename Ctx> +Result<> makeRefAs(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + RefAsOp op) { + return ctx.makeRefAs(pos, annotations, op); } template<typename Ctx> -Result<> makeStringNew(Ctx& ctx, Index pos, StringNewOp op, bool try_) { +Result<> makeStringNew(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringNewOp op, + bool try_) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); - return ctx.makeStringNew(pos, op, try_, mem.getPtr()); + return ctx.makeStringNew(pos, annotations, op, try_, mem.getPtr()); } -template<typename Ctx> Result<> makeStringConst(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> makeStringConst(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { auto str = ctx.in.takeString(); if (!str) { return ctx.in.err("expected string"); } - return ctx.makeStringConst(pos, *str); + return ctx.makeStringConst(pos, annotations, *str); } template<typename Ctx> -Result<> makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) { - return ctx.makeStringMeasure(pos, op); +Result<> makeStringMeasure(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringMeasureOp op) { + return ctx.makeStringMeasure(pos, annotations, op); } template<typename Ctx> -Result<> makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) { +Result<> makeStringEncode(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringEncodeOp op) { auto mem = maybeMemidx(ctx); CHECK_ERR(mem); - return ctx.makeStringEncode(pos, op, mem.getPtr()); + return ctx.makeStringEncode(pos, annotations, op, mem.getPtr()); } -template<typename Ctx> Result<> makeStringConcat(Ctx& ctx, Index pos) { - return ctx.makeStringConcat(pos); +template<typename Ctx> +Result<> makeStringConcat(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeStringConcat(pos, annotations); } template<typename Ctx> -Result<> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) { - return ctx.makeStringEq(pos, op); +Result<> makeStringEq(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringEqOp op) { + return ctx.makeStringEq(pos, annotations, op); } template<typename Ctx> -Result<> makeStringAs(Ctx& ctx, Index pos, StringAsOp op) { - return ctx.makeStringAs(pos, op); +Result<> makeStringAs(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringAsOp op) { + return ctx.makeStringAs(pos, annotations, op); } -template<typename Ctx> Result<> makeStringWTF8Advance(Ctx& ctx, Index pos) { - return ctx.makeStringWTF8Advance(pos); +template<typename Ctx> +Result<> makeStringWTF8Advance(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeStringWTF8Advance(pos, annotations); } -template<typename Ctx> Result<> makeStringWTF16Get(Ctx& ctx, Index pos) { - return ctx.makeStringWTF16Get(pos); +template<typename Ctx> +Result<> makeStringWTF16Get(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeStringWTF16Get(pos, annotations); } -template<typename Ctx> Result<> makeStringIterNext(Ctx& ctx, Index pos) { - return ctx.makeStringIterNext(pos); +template<typename Ctx> +Result<> makeStringIterNext(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeStringIterNext(pos, annotations); } template<typename Ctx> -Result<> makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) { - return ctx.makeStringIterMove(pos, op); +Result<> makeStringIterMove(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringIterMoveOp op) { + return ctx.makeStringIterMove(pos, annotations, op); } template<typename Ctx> -Result<> makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) { - return ctx.makeStringSliceWTF(pos, op); +Result<> makeStringSliceWTF(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations, + StringSliceWTFOp op) { + return ctx.makeStringSliceWTF(pos, annotations, op); } -template<typename Ctx> Result<> makeStringSliceIter(Ctx& ctx, Index pos) { - return ctx.makeStringSliceIter(pos); +template<typename Ctx> +Result<> makeStringSliceIter(Ctx& ctx, + Index pos, + const std::vector<Annotation>& annotations) { + return ctx.makeStringSliceIter(pos, annotations); } -template<typename Ctx> Result<> makeContNew(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeContNew(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); - return ctx.makeContNew(pos, *type); + return ctx.makeContNew(pos, annotations, *type); } // resume ::= 'resume' typeidx ('(' 'tag' tagidx labelidx ')')* -template<typename Ctx> Result<> makeResume(Ctx& ctx, Index pos) { +template<typename Ctx> +Result<> +makeResume(Ctx& ctx, Index pos, const std::vector<Annotation>& annotations) { auto type = typeidx(ctx); CHECK_ERR(type); @@ -2015,7 +2459,7 @@ template<typename Ctx> Result<> makeResume(Ctx& ctx, Index pos) { } } - return ctx.makeResume(pos, *type, tagLabels); + return ctx.makeResume(pos, annotations, *type, tagLabels); } // ======= |