diff options
Diffstat (limited to 'src/wasm/wasm-ir-builder.cpp')
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 67 |
1 files changed, 54 insertions, 13 deletions
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index fbb116aa9..9ee7a2a18 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -107,17 +107,17 @@ Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted, auto type = scope.exprStack.back()->type; - if (type.size() == sizeHint) { + if (type.size() == sizeHint || type.size() <= 1) { if (hoisted.get) { packageAsBlock(type); } return Ok{}; } - // We need to break up the hoisted tuple. Create and push a block setting the - // tuple to a local and returning its first element, then push additional gets - // of each of its subsequent elements. Reuse the scratch local we used for - // hoisting, if it exists. + // We need to break up the hoisted tuple. Create and push an expression + // setting the tuple to a local and returning its first element, then push + // additional gets of each of its subsequent elements. Reuse the scratch local + // we used for hoisting, if it exists. Index scratchIdx; if (hoisted.get) { // Update the get on top of the stack to just return the first element. @@ -127,12 +127,8 @@ Result<> IRBuilder::packageHoistedValue(const HoistedVal& hoisted, } else { auto scratch = addScratchLocal(type); CHECK_ERR(scratch); - auto* block = builder.makeSequence( - builder.makeLocalSet(*scratch, scope.exprStack.back()), - builder.makeTupleExtract(builder.makeLocalGet(*scratch, type), 0), - type[0]); - scope.exprStack.pop_back(); - push(block); + scope.exprStack.back() = builder.makeTupleExtract( + builder.makeLocalTee(*scratch, scope.exprStack.back(), type), 0); scratchIdx = *scratch; } for (Index i = 1, size = type.size(); i < size; ++i) { @@ -560,6 +556,33 @@ Result<> IRBuilder::visitStringEncode(StringEncode* curr) { WASM_UNREACHABLE("unexpected op"); } +Result<> IRBuilder::visitTupleMake(TupleMake* curr) { + assert(curr->operands.size() >= 2); + for (size_t i = 0, size = curr->operands.size(); i < size; ++i) { + auto elem = pop(); + CHECK_ERR(elem); + curr->operands[size - 1 - i] = *elem; + } + return Ok{}; +} + +Result<> IRBuilder::visitTupleExtract(TupleExtract* curr, + std::optional<uint32_t> arity) { + if (!arity) { + if (curr->tuple->type == Type::unreachable) { + // Fallback to an arbitrary valid arity. + arity = 2; + } else { + arity = curr->tuple->type.size(); + } + } + assert(*arity >= 2); + auto tuple = pop(*arity); + CHECK_ERR(tuple); + curr->tuple = *tuple; + return Ok{}; +} + Result<> IRBuilder::visitFunctionStart(Function* func) { if (!scopeStack.empty()) { return Err{"unexpected start of function"}; @@ -1332,9 +1355,27 @@ Result<> IRBuilder::makeRethrow(Index label) { return Ok{}; } -// Result<> IRBuilder::makeTupleMake() {} +Result<> IRBuilder::makeTupleMake(uint32_t arity) { + TupleMake curr(wasm.allocator); + curr.operands.resize(arity); + CHECK_ERR(visitTupleMake(&curr)); + push(builder.makeTupleMake(curr.operands)); + return Ok{}; +} + +Result<> IRBuilder::makeTupleExtract(uint32_t arity, uint32_t index) { + TupleExtract curr; + CHECK_ERR(visitTupleExtract(&curr, arity)); + push(builder.makeTupleExtract(curr.tuple, index)); + return Ok{}; +} -// Result<> IRBuilder::makeTupleExtract() {} +Result<> IRBuilder::makeTupleDrop(uint32_t arity) { + Drop curr; + CHECK_ERR(visitDrop(&curr, arity)); + push(builder.makeDrop(curr.value)); + return Ok{}; +} Result<> IRBuilder::makeRefI31() { RefI31 curr; |