Skip to content

[Parser] Parse resume #6295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ struct NullInstrParserCtx {
using ExprT = Ok;
using CatchT = Ok;
using CatchListT = Ok;
using TagLabelListT = Ok;

using FieldIdxT = Ok;
using FuncIdxT = Ok;
Expand Down Expand Up @@ -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{}; }
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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
Expand Down
20 changes: 18 additions & 2 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}

// =======
Expand Down
8 changes: 6 additions & 2 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
[[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
Expand Down Expand Up @@ -206,6 +206,9 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
[[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*);
Expand All @@ -228,6 +231,7 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
[[nodiscard]] Result<> visitThrow(Throw*);
[[nodiscard]] Result<> visitStringNew(StringNew*);
[[nodiscard]] Result<> visitStringEncode(StringEncode*);
[[nodiscard]] Result<> visitResume(Resume*);
[[nodiscard]] Result<> visitTupleMake(TupleMake*);
[[nodiscard]] Result<>
visitTupleExtract(TupleExtract*,
Expand Down
38 changes: 38 additions & 0 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Loading