Skip to content

Commit 7e20a3b

Browse files
authored
[Parser] Parse resume (#6295)
1 parent 90087f0 commit 7e20a3b

File tree

5 files changed

+299
-153
lines changed

5 files changed

+299
-153
lines changed

src/parser/contexts.h

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ struct NullInstrParserCtx {
310310
using ExprT = Ok;
311311
using CatchT = Ok;
312312
using CatchListT = Ok;
313+
using TagLabelListT = Ok;
313314

314315
using FieldIdxT = Ok;
315316
using FuncIdxT = Ok;
@@ -386,6 +387,9 @@ struct NullInstrParserCtx {
386387
return Ok{};
387388
}
388389

390+
TagLabelListT makeTagLabelList() { return Ok{}; }
391+
void appendTagLabel(TagLabelListT&, TagIdxT, LabelIdxT) {}
392+
389393
Result<> makeUnreachable(Index) { return Ok{}; }
390394
Result<> makeNop(Index) { return Ok{}; }
391395
Result<> makeBinary(Index, BinaryOp) { return Ok{}; }
@@ -566,6 +570,10 @@ struct NullInstrParserCtx {
566570
Result<> makeStringIterMove(Index, StringIterMoveOp) { return Ok{}; }
567571
Result<> makeStringSliceWTF(Index, StringSliceWTFOp) { return Ok{}; }
568572
Result<> makeStringSliceIter(Index) { return Ok{}; }
573+
template<typename HeapTypeT>
574+
Result<> makeResume(Index, HeapTypeT, const TagLabelListT&) {
575+
return Ok{};
576+
}
569577
};
570578

571579
struct NullCtx : NullTypeParserCtx, NullInstrParserCtx {
@@ -1069,13 +1077,6 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
10691077
using TableTypeT = Ok;
10701078
using TypeUseT = HeapType;
10711079

1072-
using ExprT = Expression*;
1073-
using ElemListT = std::vector<Expression*>;
1074-
1075-
struct CatchInfo;
1076-
using CatchT = CatchInfo;
1077-
using CatchListT = std::vector<CatchInfo>;
1078-
10791080
using FieldIdxT = Index;
10801081
using FuncIdxT = Name;
10811082
using LocalIdxT = Index;
@@ -1089,6 +1090,15 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
10891090

10901091
using MemargT = Memarg;
10911092

1093+
using ExprT = Expression*;
1094+
using ElemListT = std::vector<Expression*>;
1095+
1096+
struct CatchInfo;
1097+
using CatchT = CatchInfo;
1098+
using CatchListT = std::vector<CatchInfo>;
1099+
1100+
using TagLabelListT = std::vector<std::pair<TagIdxT, LabelIdxT>>;
1101+
10921102
ParseInput in;
10931103

10941104
Module& wasm;
@@ -1179,6 +1189,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
11791189
CatchInfo makeCatchAll(Index label) { return {{}, label, false}; }
11801190
CatchInfo makeCatchAllRef(Index label) { return {{}, label, true}; }
11811191

1192+
TagLabelListT makeTagLabelList() { return {}; }
1193+
void appendTagLabel(TagLabelListT& tagLabels, Name tag, Index label) {
1194+
tagLabels.push_back({tag, label});
1195+
}
1196+
11821197
Result<HeapTypeT> getHeapTypeFromIdx(Index idx) {
11831198
if (idx >= types.size()) {
11841199
return in.err("type index out of bounds");
@@ -1994,6 +2009,19 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
19942009
Result<> makeStringSliceIter(Index pos) {
19952010
return withLoc(pos, irBuilder.makeStringSliceIter());
19962011
}
2012+
2013+
Result<>
2014+
makeResume(Index pos, HeapType type, const TagLabelListT& tagLabels) {
2015+
std::vector<Name> tags;
2016+
std::vector<Index> labels;
2017+
tags.reserve(tagLabels.size());
2018+
labels.reserve(tagLabels.size());
2019+
for (auto& [tag, label] : tagLabels) {
2020+
tags.push_back(tag);
2021+
labels.push_back(label);
2022+
}
2023+
return withLoc(pos, irBuilder.makeResume(type, tags, labels));
2024+
}
19972025
};
19982026

19992027
} // namespace wasm::WATParser

src/parser/parsers.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,7 @@ template<typename Ctx> MaybeResult<typename Ctx::CatchT> catchinstr(Ctx& ctx) {
12281228
return result;
12291229
}
12301230

1231-
// trytable ::= 'try_table' label blocktype catchinstr* instr* end id?
1231+
// trytable ::= 'try_table' label blocktype catchinstr* instr* 'end' id?
12321232
// | '(' 'try_table' label blocktype catchinstr* instr* ')'
12331233
template<typename Ctx> MaybeResult<> trytable(Ctx& ctx, bool folded) {
12341234
auto pos = ctx.in.getPos();
@@ -1992,8 +1992,24 @@ template<typename Ctx> Result<> makeStringSliceIter(Ctx& ctx, Index pos) {
19921992
return ctx.makeStringSliceIter(pos);
19931993
}
19941994

1995+
// resume ::= 'resume' typeidx ('(' 'tag' tagidx labelidx ')')*
19951996
template<typename Ctx> Result<> makeResume(Ctx& ctx, Index pos) {
1996-
return ctx.in.err("unimplemented instruction");
1997+
auto type = typeidx(ctx);
1998+
CHECK_ERR(type);
1999+
2000+
auto tagLabels = ctx.makeTagLabelList();
2001+
while (ctx.in.takeSExprStart("tag"sv)) {
2002+
auto tag = tagidx(ctx);
2003+
CHECK_ERR(tag);
2004+
auto label = labelidx(ctx);
2005+
CHECK_ERR(label);
2006+
ctx.appendTagLabel(tagLabels, *tag, *label);
2007+
if (!ctx.in.takeRParen()) {
2008+
return ctx.in.err("expected ')' at end of handler clause");
2009+
}
2010+
}
2011+
2012+
return ctx.makeResume(pos, *type, tagLabels);
19972013
}
19982014

19992015
// =======

src/wasm-ir-builder.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
6565
[[nodiscard]] Result<> visitElse();
6666
[[nodiscard]] Result<> visitLoopStart(Loop* iff);
6767
[[nodiscard]] Result<> visitTryStart(Try* tryy, Name label = {});
68-
[[nodiscard]] Result<> visitTryTableStart(TryTable* trytable,
69-
Name label = {});
7068
[[nodiscard]] Result<> visitCatch(Name tag);
7169
[[nodiscard]] Result<> visitCatchAll();
7270
[[nodiscard]] Result<> visitDelegate(Index label);
71+
[[nodiscard]] Result<> visitTryTableStart(TryTable* trytable,
72+
Name label = {});
7373
[[nodiscard]] Result<> visitEnd();
7474

7575
// Binaryen IR uses names to refer to branch targets, but in general there may
@@ -206,6 +206,9 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
206206
[[nodiscard]] Result<> makeStringIterMove(StringIterMoveOp op);
207207
[[nodiscard]] Result<> makeStringSliceWTF(StringSliceWTFOp op);
208208
[[nodiscard]] Result<> makeStringSliceIter();
209+
[[nodiscard]] Result<> makeResume(HeapType ct,
210+
const std::vector<Name>& tags,
211+
const std::vector<Index>& labels);
209212

210213
// Private functions that must be public for technical reasons.
211214
[[nodiscard]] Result<> visitExpression(Expression*);
@@ -228,6 +231,7 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
228231
[[nodiscard]] Result<> visitThrow(Throw*);
229232
[[nodiscard]] Result<> visitStringNew(StringNew*);
230233
[[nodiscard]] Result<> visitStringEncode(StringEncode*);
234+
[[nodiscard]] Result<> visitResume(Resume*);
231235
[[nodiscard]] Result<> visitTupleMake(TupleMake*);
232236
[[nodiscard]] Result<>
233237
visitTupleExtract(TupleExtract*,

src/wasm/wasm-ir-builder.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,22 @@ Result<> IRBuilder::visitStringEncode(StringEncode* curr) {
576576
WASM_UNREACHABLE("unexpected op");
577577
}
578578

579+
Result<> IRBuilder::visitResume(Resume* curr) {
580+
auto cont = pop();
581+
CHECK_ERR(cont);
582+
curr->cont = *cont;
583+
584+
auto sig = curr->contType.getContinuation().type.getSignature();
585+
auto size = sig.params.size();
586+
curr->operands.resize(size);
587+
for (size_t i = 0; i < size; ++i) {
588+
auto val = pop();
589+
CHECK_ERR(val);
590+
curr->operands[size - i - 1] = *val;
591+
}
592+
return Ok{};
593+
}
594+
579595
Result<> IRBuilder::visitTupleMake(TupleMake* curr) {
580596
assert(curr->operands.size() >= 2);
581597
for (size_t i = 0, size = curr->operands.size(); i < size; ++i) {
@@ -1767,4 +1783,26 @@ Result<> IRBuilder::makeStringSliceIter() {
17671783
return Ok{};
17681784
}
17691785

1786+
Result<> IRBuilder::makeResume(HeapType ct,
1787+
const std::vector<Name>& tags,
1788+
const std::vector<Index>& labels) {
1789+
if (!ct.isContinuation()) {
1790+
return Err{"expected continuation type"};
1791+
}
1792+
Resume curr(wasm.allocator);
1793+
curr.contType = ct;
1794+
CHECK_ERR(visitResume(&curr));
1795+
1796+
std::vector<Name> labelNames;
1797+
labelNames.reserve(labels.size());
1798+
for (auto label : labels) {
1799+
auto name = getLabelName(label);
1800+
CHECK_ERR(name);
1801+
labelNames.push_back(*name);
1802+
}
1803+
std::vector<Expression*> operands(curr.operands.begin(), curr.operands.end());
1804+
push(builder.makeResume(ct, tags, labelNames, operands, curr.cont));
1805+
return Ok{};
1806+
}
1807+
17701808
} // namespace wasm

0 commit comments

Comments
 (0)