diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm/wat-parser.cpp | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 82f8368af..abcff8c43 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -725,6 +725,7 @@ struct NullInstrParserCtx { InstrT makeMemoryCopy(Index, MemoryT*, MemoryT*) { return Ok{}; } InstrT makeMemoryFill(Index, MemoryT*) { return Ok{}; } + InstrT makeReturn(Index) { return Ok{}; } template<typename HeapTypeT> InstrT makeRefNull(Index, HeapTypeT) { return {}; } @@ -1253,12 +1254,23 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { // instructions and reset the context for the next sequence. if (type.isTuple()) { std::vector<Expression*> elems(type.size()); + bool hadUnreachableElem = false; for (size_t i = 0; i < elems.size(); ++i) { auto elem = pop(self().in.getPos()); CHECK_ERR(elem); elems[elems.size() - 1 - i] = *elem; + if ((*elem)->type == Type::unreachable) { + // We don't want to pop back past an unreachable here. Push the + // unreachable back and throw away any post-unreachable values we have + // popped. + exprStack.push_back(*elem); + hadUnreachableElem = true; + break; + } + } + if (!hadUnreachableElem) { + exprStack.push_back(builder.makeTupleMake(std::move(elems))); } - exprStack.push_back(builder.makeTupleMake(std::move(elems))); } else if (type != Type::none) { // Ensure the last expression produces the value. auto expr = pop(self().in.getPos()); @@ -1727,6 +1739,28 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return push(pos, builder.makeMemoryFill(*dest, *val, *size, *m)); } + Result<> makeReturn(Index pos) { + if (!func) { + return in.err("cannot return outside of a function"); + } + size_t n = func->getResults().size(); + if (n == 0) { + return push(pos, builder.makeReturn()); + } + if (n == 1) { + auto val = pop(pos); + CHECK_ERR(val); + return push(pos, builder.makeReturn(*val)); + } + std::vector<Expression*> vals(n); + for (size_t i = 0; i < n; ++i) { + auto val = pop(pos); + CHECK_ERR(val); + vals[n - i - 1] = *val; + } + return push(pos, builder.makeReturn(builder.makeTupleMake(vals))); + } + Result<> makeRefNull(Index pos, HeapType type) { return push(pos, builder.makeRefNull(type)); } @@ -2709,7 +2743,7 @@ Result<typename Ctx::InstrT> makeBreakTable(Ctx& ctx, Index pos) { template<typename Ctx> Result<typename Ctx::InstrT> makeReturn(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + return ctx.makeReturn(pos); } template<typename Ctx> |