summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parser/contexts.h42
-rw-r--r--src/parser/parsers.h20
-rw-r--r--src/wasm-ir-builder.h8
-rw-r--r--src/wasm/wasm-ir-builder.cpp38
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