diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/parser/contexts.h | 42 | ||||
-rw-r--r-- | src/parser/parsers.h | 20 | ||||
-rw-r--r-- | src/wasm-ir-builder.h | 8 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 38 |
4 files changed, 97 insertions, 11 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 544851859..ab82f3963 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -310,6 +310,7 @@ struct NullInstrParserCtx { using ExprT = Ok; using CatchT = Ok; using CatchListT = Ok; + using TagLabelListT = Ok; using FieldIdxT = Ok; using FuncIdxT = Ok; @@ -386,6 +387,9 @@ struct NullInstrParserCtx { 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{}; } @@ -566,6 +570,10 @@ struct NullInstrParserCtx { Result<> makeStringIterMove(Index, StringIterMoveOp) { return Ok{}; } Result<> makeStringSliceWTF(Index, StringSliceWTFOp) { return Ok{}; } Result<> makeStringSliceIter(Index) { return Ok{}; } + template<typename HeapTypeT> + Result<> makeResume(Index, HeapTypeT, const TagLabelListT&) { + return Ok{}; + } }; struct NullCtx : NullTypeParserCtx, NullInstrParserCtx { @@ -1069,13 +1077,6 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { using TableTypeT = Ok; using TypeUseT = HeapType; - using ExprT = Expression*; - using ElemListT = std::vector<Expression*>; - - struct CatchInfo; - using CatchT = CatchInfo; - using CatchListT = std::vector<CatchInfo>; - using FieldIdxT = Index; using FuncIdxT = Name; using LocalIdxT = Index; @@ -1089,6 +1090,15 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { using MemargT = Memarg; + using ExprT = Expression*; + using ElemListT = std::vector<Expression*>; + + struct CatchInfo; + using CatchT = CatchInfo; + using CatchListT = std::vector<CatchInfo>; + + using TagLabelListT = std::vector<std::pair<TagIdxT, LabelIdxT>>; + ParseInput in; Module& wasm; @@ -1179,6 +1189,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { CatchInfo makeCatchAll(Index label) { return {{}, label, false}; } CatchInfo makeCatchAllRef(Index label) { return {{}, label, true}; } + TagLabelListT makeTagLabelList() { return {}; } + void appendTagLabel(TagLabelListT& tagLabels, Name tag, Index label) { + tagLabels.push_back({tag, label}); + } + Result<HeapTypeT> getHeapTypeFromIdx(Index idx) { if (idx >= types.size()) { return in.err("type index out of bounds"); @@ -1994,6 +2009,19 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { Result<> makeStringSliceIter(Index pos) { return withLoc(pos, irBuilder.makeStringSliceIter()); } + + Result<> + makeResume(Index pos, HeapType type, const TagLabelListT& tagLabels) { + std::vector<Name> tags; + std::vector<Index> labels; + tags.reserve(tagLabels.size()); + labels.reserve(tagLabels.size()); + for (auto& [tag, label] : tagLabels) { + tags.push_back(tag); + labels.push_back(label); + } + return withLoc(pos, irBuilder.makeResume(type, tags, labels)); + } }; } // namespace wasm::WATParser diff --git a/src/parser/parsers.h b/src/parser/parsers.h index db4c716f1..960ccb26d 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1228,7 +1228,7 @@ template<typename Ctx> MaybeResult<typename Ctx::CatchT> catchinstr(Ctx& ctx) { return result; } -// trytable ::= 'try_table' label blocktype catchinstr* instr* end id? +// trytable ::= 'try_table' label blocktype catchinstr* instr* 'end' id? // | '(' 'try_table' label blocktype catchinstr* instr* ')' template<typename Ctx> MaybeResult<> trytable(Ctx& ctx, bool folded) { auto pos = ctx.in.getPos(); @@ -1992,8 +1992,24 @@ template<typename Ctx> Result<> makeStringSliceIter(Ctx& ctx, Index pos) { return ctx.makeStringSliceIter(pos); } +// resume ::= 'resume' typeidx ('(' 'tag' tagidx labelidx ')')* template<typename Ctx> Result<> makeResume(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto type = typeidx(ctx); + CHECK_ERR(type); + + auto tagLabels = ctx.makeTagLabelList(); + while (ctx.in.takeSExprStart("tag"sv)) { + auto tag = tagidx(ctx); + CHECK_ERR(tag); + auto label = labelidx(ctx); + CHECK_ERR(label); + ctx.appendTagLabel(tagLabels, *tag, *label); + if (!ctx.in.takeRParen()) { + return ctx.in.err("expected ')' at end of handler clause"); + } + } + + return ctx.makeResume(pos, *type, tagLabels); } // ======= diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index d32dfebf2..66dfd6dbe 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -65,11 +65,11 @@ public: [[nodiscard]] Result<> visitElse(); [[nodiscard]] Result<> visitLoopStart(Loop* iff); [[nodiscard]] Result<> visitTryStart(Try* tryy, Name label = {}); - [[nodiscard]] Result<> visitTryTableStart(TryTable* trytable, - Name label = {}); [[nodiscard]] Result<> visitCatch(Name tag); [[nodiscard]] Result<> visitCatchAll(); [[nodiscard]] Result<> visitDelegate(Index label); + [[nodiscard]] Result<> visitTryTableStart(TryTable* trytable, + Name label = {}); [[nodiscard]] Result<> visitEnd(); // Binaryen IR uses names to refer to branch targets, but in general there may @@ -206,6 +206,9 @@ public: [[nodiscard]] Result<> makeStringIterMove(StringIterMoveOp op); [[nodiscard]] Result<> makeStringSliceWTF(StringSliceWTFOp op); [[nodiscard]] Result<> makeStringSliceIter(); + [[nodiscard]] Result<> makeResume(HeapType ct, + const std::vector<Name>& tags, + const std::vector<Index>& labels); // Private functions that must be public for technical reasons. [[nodiscard]] Result<> visitExpression(Expression*); @@ -228,6 +231,7 @@ public: [[nodiscard]] Result<> visitThrow(Throw*); [[nodiscard]] Result<> visitStringNew(StringNew*); [[nodiscard]] Result<> visitStringEncode(StringEncode*); + [[nodiscard]] Result<> visitResume(Resume*); [[nodiscard]] Result<> visitTupleMake(TupleMake*); [[nodiscard]] Result<> visitTupleExtract(TupleExtract*, diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index dadda0f25..bd3a3ad11 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -576,6 +576,22 @@ Result<> IRBuilder::visitStringEncode(StringEncode* curr) { WASM_UNREACHABLE("unexpected op"); } +Result<> IRBuilder::visitResume(Resume* curr) { + auto cont = pop(); + CHECK_ERR(cont); + curr->cont = *cont; + + auto sig = curr->contType.getContinuation().type.getSignature(); + auto size = sig.params.size(); + curr->operands.resize(size); + for (size_t i = 0; i < size; ++i) { + auto val = pop(); + CHECK_ERR(val); + curr->operands[size - i - 1] = *val; + } + return Ok{}; +} + Result<> IRBuilder::visitTupleMake(TupleMake* curr) { assert(curr->operands.size() >= 2); for (size_t i = 0, size = curr->operands.size(); i < size; ++i) { @@ -1767,4 +1783,26 @@ Result<> IRBuilder::makeStringSliceIter() { return Ok{}; } +Result<> IRBuilder::makeResume(HeapType ct, + const std::vector<Name>& tags, + const std::vector<Index>& labels) { + if (!ct.isContinuation()) { + return Err{"expected continuation type"}; + } + Resume curr(wasm.allocator); + curr.contType = ct; + CHECK_ERR(visitResume(&curr)); + + std::vector<Name> labelNames; + labelNames.reserve(labels.size()); + for (auto label : labels) { + auto name = getLabelName(label); + CHECK_ERR(name); + labelNames.push_back(*name); + } + std::vector<Expression*> operands(curr.operands.begin(), curr.operands.end()); + push(builder.makeResume(ct, tags, labelNames, operands, curr.cont)); + return Ok{}; +} + } // namespace wasm |