Skip to content
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 numberDiff line numberDiff 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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 numberDiff line numberDiff 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 DownExpand 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