diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index c8425aa4be6..265fc465afd 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -465,13 +465,13 @@ struct CodeScanner } else if (auto* contNew = curr->dynCast()) { info.note(contNew->type); } else if (auto* resume = curr->dynCast()) { - info.note(resume->contType); + info.note(resume->cont->type); info.note(resume->type); } else if (auto* resumeThrow = curr->dynCast()) { - info.note(resumeThrow->contType); + info.note(resumeThrow->cont->type); info.note(resumeThrow->type); } else if (auto* switch_ = curr->dynCast()) { - info.note(switch_->contType); + info.note(switch_->cont->type); info.note(switch_->type); } else if (Properties::isControlFlowStructure(curr)) { info.noteControlFlow(Signature(Type::none, curr->type)); diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index c5983e733bc..7dc81afdc7d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -386,29 +386,25 @@ struct PrintSExpression : public UnifiedExpressionVisitor { } } void visitContBind(ContBind* curr) { - if (!maybePrintUnreachableOrNullReplacement( - curr, Type(curr->sourceType, Nullable)) && + if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) && !maybePrintUnreachableOrNullReplacement(curr, curr->type)) { visitExpression(curr); } } void visitResume(Resume* curr) { - if (!maybePrintUnreachableOrNullReplacement( - curr, Type(curr->contType, Nullable)) && + if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) && !maybePrintUnreachableOrNullReplacement(curr, curr->type)) { visitExpression(curr); } } void visitResumeThrow(ResumeThrow* curr) { - if (!maybePrintUnreachableOrNullReplacement( - curr, Type(curr->contType, Nullable)) && + if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) && !maybePrintUnreachableOrNullReplacement(curr, curr->type)) { visitExpression(curr); } } void visitStackSwitch(StackSwitch* curr) { - if (!maybePrintUnreachableOrNullReplacement( - curr, Type(curr->contType, Nullable)) && + if (!maybePrintUnreachableOrNullReplacement(curr, curr->cont->type) && !maybePrintUnreachableOrNullReplacement(curr, curr->type)) { visitExpression(curr); } @@ -2461,12 +2457,14 @@ struct PrintExpressionContents printMedium(o, "stringview_wtf16.slice"); } void visitContNew(ContNew* curr) { + assert(curr->type.isContinuation()); printMedium(o, "cont.new "); printHeapType(curr->type.getHeapType()); } void visitContBind(ContBind* curr) { + assert(curr->cont->type.isContinuation() && curr->type.isContinuation()); printMedium(o, "cont.bind "); - printHeapType(curr->sourceType); + printHeapType(curr->cont->type.getHeapType()); o << ' '; printHeapType(curr->type.getHeapType()); } @@ -2492,28 +2490,31 @@ struct PrintExpressionContents } } void visitResume(Resume* curr) { + assert(curr->cont->type.isContinuation()); printMedium(o, "resume"); o << ' '; - printHeapType(curr->contType); + printHeapType(curr->cont->type.getHeapType()); handleResumeTable(o, curr); } void visitResumeThrow(ResumeThrow* curr) { + assert(curr->cont->type.isContinuation()); printMedium(o, "resume_throw"); o << ' '; - printHeapType(curr->contType); + printHeapType(curr->cont->type.getHeapType()); o << ' '; curr->tag.print(o); handleResumeTable(o, curr); } void visitStackSwitch(StackSwitch* curr) { + assert(curr->cont->type.isContinuation()); printMedium(o, "switch"); o << ' '; - printHeapType(curr->contType); + printHeapType(curr->cont->type.getHeapType()); o << ' '; curr->tag.print(o); } diff --git a/src/wasm-builder.h b/src/wasm-builder.h index d06ba1c6edd..08193381253 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1207,7 +1207,7 @@ class Builder { ret->sentTypes.set(sentTypes); ret->operands.set(operands); ret->cont = cont; - ret->finalize(&wasm); + ret->finalize(); return ret; } ResumeThrow* makeResumeThrow(HeapType contType, @@ -1225,7 +1225,7 @@ class Builder { ret->sentTypes.set(sentTypes); ret->operands.set(operands); ret->cont = cont; - ret->finalize(&wasm); + ret->finalize(); return ret; } StackSwitch* makeStackSwitch(HeapType contType, @@ -1237,7 +1237,7 @@ class Builder { ret->tag = tag; ret->operands.set(operands); ret->cont = cont; - ret->finalize(&wasm); + ret->finalize(); return ret; } diff --git a/src/wasm.h b/src/wasm.h index 8afa5c39d13..d5e4f3a2e5f 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1983,10 +1983,7 @@ class Resume : public SpecificExpression { ExpressionList operands; Expression* cont; - // When 'Module*' parameter is given, we populate the 'sentTypes' array, so - // that the types can be accessed in other analyses without accessing the - // module. - void finalize(Module* wasm = nullptr); + void finalize(); // sentTypes[i] contains the type of the values that will be sent to the block // handlerBlocks[i] if suspending with tag handlerTags[i]. Not part of the @@ -2011,10 +2008,7 @@ class ResumeThrow : public SpecificExpression { ExpressionList operands; Expression* cont; - // When 'Module*' parameter is given, we populate the 'sentTypes' array, so - // that the types can be accessed in other analyses without accessing the - // module. - void finalize(Module* wasm = nullptr); + void finalize(); // sentTypes[i] contains the type of the values that will be sent to the block // handlerBlocks[i] if suspending with tag handlerTags[i]. Not part of the @@ -2035,7 +2029,7 @@ class StackSwitch : public SpecificExpression { Expression* cont; // We need access to the module to obtain the signature of the tag. - void finalize(Module* wasm = nullptr); + void finalize(); }; // Globals diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 9f93a8e628d..5f15394244d 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -8019,7 +8019,6 @@ static void readResumeTable(WasmBinaryReader* reader, ResumeType* curr) { } void WasmBinaryReader::visitResume(Resume* curr) { - curr->contType = getIndexedHeapType(); if (!curr->contType.isContinuation()) { throwError("non-continuation type in resume instruction " + @@ -8037,7 +8036,7 @@ void WasmBinaryReader::visitResume(Resume* curr) { curr->operands[numArgs - i - 1] = popNonVoidExpression(); } - curr->finalize(&wasm); + curr->finalize(); } void WasmBinaryReader::visitResumeThrow(ResumeThrow* curr) { @@ -8061,7 +8060,7 @@ void WasmBinaryReader::visitResumeThrow(ResumeThrow* curr) { curr->operands[numArgs - i - 1] = popNonVoidExpression(); } - curr->finalize(&wasm); + curr->finalize(); } void WasmBinaryReader::visitStackSwitch(StackSwitch* curr) { @@ -8086,7 +8085,7 @@ void WasmBinaryReader::visitStackSwitch(StackSwitch* curr) { curr->operands[numArgs - i - 1] = popNonVoidExpression(); } - curr->finalize(&wasm); + curr->finalize(); } void WasmBinaryReader::throwError(std::string text) { diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 3ceb721d0a3..ca611975328 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2618,14 +2618,16 @@ void BinaryInstWriter::visitSuspend(Suspend* curr) { } void BinaryInstWriter::visitContBind(ContBind* curr) { + assert(curr->cont->type.isContinuation() && curr->type.isContinuation()); o << int8_t(BinaryConsts::ContBind); - parent.writeIndexedHeapType(curr->sourceType); + parent.writeIndexedHeapType(curr->cont->type.getHeapType()); parent.writeIndexedHeapType(curr->type.getHeapType()); } void BinaryInstWriter::visitResume(Resume* curr) { + assert(curr->cont->type.isContinuation()); o << int8_t(BinaryConsts::Resume); - parent.writeIndexedHeapType(curr->contType); + parent.writeIndexedHeapType(curr->cont->type.getHeapType()); size_t handlerNum = curr->handlerTags.size(); o << U32LEB(handlerNum); @@ -2644,8 +2646,9 @@ void BinaryInstWriter::visitResume(Resume* curr) { } void BinaryInstWriter::visitResumeThrow(ResumeThrow* curr) { + assert(curr->cont->type.isContinuation()); o << int8_t(BinaryConsts::ResumeThrow); - parent.writeIndexedHeapType(curr->contType); + parent.writeIndexedHeapType(curr->cont->type.getHeapType()); o << U32LEB(parent.getTagIndex(curr->tag)); size_t handlerNum = curr->handlerTags.size(); @@ -2665,8 +2668,9 @@ void BinaryInstWriter::visitResumeThrow(ResumeThrow* curr) { } void BinaryInstWriter::visitStackSwitch(StackSwitch* curr) { + assert(curr->cont->type.isContinuation()); o << int8_t(BinaryConsts::Switch); - parent.writeIndexedHeapType(curr->contType); + parent.writeIndexedHeapType(curr->cont->type.getHeapType()); o << U32LEB(parent.getTagIndex(curr->tag)); } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index b34b84af3a8..dc3a9fce6d8 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3502,9 +3502,9 @@ void FunctionValidator::visitContBind(ContBind* curr) { "cont.bind requires stack-switching [--enable-stack-switching]"); shouldBeTrue( - (curr->sourceType.isContinuation() && - curr->sourceType.getContinuation().type.isSignature()) || - Type(curr->sourceType, Nullable) == Type::unreachable, + (curr->cont->type.isContinuation() && + curr->cont->type.getHeapType().getContinuation().type.isSignature()) || + curr->cont->type == Type::unreachable, curr, "the first type annotation on cont.bind must be a continuation type"); @@ -3534,11 +3534,12 @@ void FunctionValidator::visitResume(Resume* curr) { curr, "sentTypes cache in resume instruction has not been initialized"); - shouldBeTrue((curr->contType.isContinuation() && - curr->contType.getContinuation().type.isSignature()) || - curr->type == Type::unreachable, - curr, - "resume must be annotated with a continuation type"); + shouldBeTrue( + (curr->cont->type.isContinuation() && + curr->cont->type.getHeapType().getContinuation().type.isSignature()) || + curr->type == Type::unreachable, + curr, + "resume must be annotated with a continuation type"); } void FunctionValidator::visitResumeThrow(ResumeThrow* curr) { @@ -3555,11 +3556,12 @@ void FunctionValidator::visitResumeThrow(ResumeThrow* curr) { curr, "sentTypes cache in resume_throw instruction has not been initialized"); - shouldBeTrue((curr->contType.isContinuation() && - curr->contType.getContinuation().type.isSignature()) || - curr->type == Type::unreachable, - curr, - "resume_throw must be annotated with a continuation type"); + shouldBeTrue( + (curr->cont->type.isContinuation() && + curr->cont->type.getHeapType().getContinuation().type.isSignature()) || + curr->type == Type::unreachable, + curr, + "resume_throw must be annotated with a continuation type"); auto* tag = getModule()->getTagOrNull(curr->tag); if (!shouldBeTrue(!!tag, curr, "resume_throw must be annotated with a tag")) { @@ -3573,11 +3575,12 @@ void FunctionValidator::visitStackSwitch(StackSwitch* curr) { curr, "switch requires stack-switching [--enable-stack-switching]"); - shouldBeTrue((curr->contType.isContinuation() && - curr->contType.getContinuation().type.isSignature()) || - curr->type == Type::unreachable, - curr, - "switch must be annotated with a continuation type"); + shouldBeTrue( + (curr->cont->type.isContinuation() && + curr->cont->type.getHeapType().getContinuation().type.isSignature()) || + curr->type == Type::unreachable, + curr, + "switch must be annotated with a continuation type"); auto* tag = getModule()->getTagOrNull(curr->tag); if (!shouldBeTrue(!!tag, curr, "switch must be annotated with a tag")) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 2a5050642c1..cbbfc2f369e 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1375,8 +1375,12 @@ void ContNew::finalize() { } void ContBind::finalize() { - if (handleUnreachableOperands(this)) { + if (cont->type == Type::unreachable) { type = Type::unreachable; + return; + } + if (handleUnreachableOperands(this)) { + return; } } @@ -1387,32 +1391,45 @@ void Suspend::finalize(Module* wasm) { } } -void Resume::finalize(Module* wasm) { +void Resume::finalize() { if (cont->type == Type::unreachable) { type = Type::unreachable; - } else if (!handleUnreachableOperands(this)) { - const Signature& contSig = - this->contType.getContinuation().type.getSignature(); - type = contSig.results; + return; } + if (handleUnreachableOperands(this)) { + return; + } + + const Signature& contSig = + this->cont->type.getHeapType().getContinuation().type.getSignature(); + type = contSig.results; } -void ResumeThrow::finalize(Module* wasm) { +void ResumeThrow::finalize() { if (cont->type == Type::unreachable) { type = Type::unreachable; - } else if (!handleUnreachableOperands(this)) { - const Signature& contSig = - this->contType.getContinuation().type.getSignature(); - type = contSig.results; + return; } + if (handleUnreachableOperands(this)) { + return; + } + + const Signature& contSig = + this->cont->type.getHeapType().getContinuation().type.getSignature(); + type = contSig.results; } -void StackSwitch::finalize(Module* wasm) { +void StackSwitch::finalize() { if (cont->type == Type::unreachable) { type = Type::unreachable; - } else if (!handleUnreachableOperands(this) && wasm) { - type = this->contType.getContinuation().type.getSignature().params; + return; } + if (handleUnreachableOperands(this)) { + return; + } + + type = + this->cont->type.getHeapType().getContinuation().type.getSignature().params; } size_t Function::getNumParams() { return getParams().size(); } diff --git a/test/lit/basic/stack_switching_contbind.wast b/test/lit/basic/stack_switching_contbind.wast index d559ad86359..f19cd270ec4 100644 --- a/test/lit/basic/stack_switching_contbind.wast +++ b/test/lit/basic/stack_switching_contbind.wast @@ -76,7 +76,10 @@ ) ;; CHECK-TEXT: (func $k (type $6) (result (ref $ct1)) - ;; CHECK-TEXT-NEXT: (cont.bind $ct1 $ct1 + ;; CHECK-TEXT-NEXT: (block ;; (replaces unreachable ContBind we can't emit) + ;; CHECK-TEXT-NEXT: (drop + ;; CHECK-TEXT-NEXT: (unreachable) + ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: (unreachable) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: )