diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 6f41c3c87..efb65bb50 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -4046,6 +4046,10 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) { visitCallRef(call); break; } + case BinaryConsts::ContBind: { + visitContBind((curr = allocator.alloc<ContBind>())->cast<ContBind>()); + break; + } case BinaryConsts::ContNew: { auto contNew = allocator.alloc<ContNew>(); curr = contNew; @@ -7768,6 +7772,43 @@ void WasmBinaryReader::visitRefAs(RefAs* curr, uint8_t code) { curr->finalize(); } +void WasmBinaryReader::visitContBind(ContBind* curr) { + BYN_TRACE("zz node: ContBind\n"); + + auto contTypeBeforeIndex = getU32LEB(); + curr->contTypeBefore = getTypeByIndex(contTypeBeforeIndex); + + auto contTypeAfterIndex = getU32LEB(); + curr->contTypeAfter = getTypeByIndex(contTypeAfterIndex); + + for (auto& ct : {curr->contTypeBefore, curr->contTypeAfter}) { + if (!ct.isContinuation()) { + throwError("non-continuation type in cont.bind instruction " + + ct.toString()); + } + } + + curr->cont = popNonVoidExpression(); + + size_t paramsBefore = + curr->contTypeBefore.getContinuation().type.getSignature().params.size(); + size_t paramsAfter = + curr->contTypeAfter.getContinuation().type.getSignature().params.size(); + if (paramsBefore < paramsAfter) { + throwError("incompatible continuation types in cont.bind: source type " + + curr->contTypeBefore.toString() + + " has fewer parameters than destination " + + curr->contTypeAfter.toString()); + } + size_t numArgs = paramsBefore - paramsAfter; + curr->operands.resize(numArgs); + for (size_t i = 0; i < numArgs; i++) { + curr->operands[numArgs - i - 1] = popNonVoidExpression(); + } + + curr->finalize(); +} + void WasmBinaryReader::visitContNew(ContNew* curr) { BYN_TRACE("zz node: ContNew\n"); |