diff options
Diffstat (limited to 'src/ir')
-rw-r--r-- | src/ir/ReFinalize.cpp | 2 | ||||
-rw-r--r-- | src/ir/branch-utils.h | 11 | ||||
-rw-r--r-- | src/ir/cost.h | 5 | ||||
-rw-r--r-- | src/ir/effects.h | 13 | ||||
-rw-r--r-- | src/ir/module-utils.cpp | 2 | ||||
-rw-r--r-- | src/ir/possible-contents.cpp | 5 | ||||
-rw-r--r-- | src/ir/subtype-exprs.h | 2 |
7 files changed, 40 insertions, 0 deletions
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 65f5c4724..0338f630c 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -182,6 +182,8 @@ void ReFinalize::visitStringSliceIter(StringSliceIter* curr) { curr->finalize(); } +void ReFinalize::visitResume(Resume* curr) { curr->finalize(); } + void ReFinalize::visitExport(Export* curr) { WASM_UNREACHABLE("unimp"); } void ReFinalize::visitGlobal(Global* curr) { WASM_UNREACHABLE("unimp"); } void ReFinalize::visitTable(Table* curr) { WASM_UNREACHABLE("unimp"); } diff --git a/src/ir/branch-utils.h b/src/ir/branch-utils.h index 3c0275701..28e29ede4 100644 --- a/src/ir/branch-utils.h +++ b/src/ir/branch-utils.h @@ -82,6 +82,13 @@ void operateOnScopeNameUsesAndSentTypes(Expression* expr, T func) { func(name, tt->sentTypes[i]); } } + } else if (auto* r = expr->dynCast<Resume>()) { + for (Index i = 0; i < r->handlerTags.size(); i++) { + auto dest = r->handlerTags[i]; + if (dest == name) { + func(name, r->sentTypes[i]); + } + } } else { assert(expr->is<Try>() || expr->is<Rethrow>()); // delegate or rethrow } @@ -106,6 +113,10 @@ void operateOnScopeNameUsesAndSentValues(Expression* expr, T func) { // The values are supplied by throwing instructions, so we are unable to // know what they will be here. func(name, nullptr); + } else if (auto* res = expr->dynCast<Resume>()) { + // The values are supplied by suspend instructions executed while running + // the continuation, so we are unable to know what they will be here. + func(name, nullptr); } else { assert(expr->is<Try>() || expr->is<Rethrow>()); // delegate or rethrow } diff --git a/src/ir/cost.h b/src/ir/cost.h index 0e87317a6..821e46524 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -726,6 +726,11 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> { return 8 + visit(curr->ref) + visit(curr->num); } + CostType visitResume(Resume* curr) { + // Inspired by indirect calls, but twice the cost. + return 12 + visit(curr->cont); + } + private: CostType nullCheckCost(Expression* ref) { // A nullable type requires a bounds check in most VMs. diff --git a/src/ir/effects.h b/src/ir/effects.h index 1156cd823..3ff320a88 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -973,6 +973,19 @@ private: // traps when ref is null. parent.implicitTrap = true; } + + void visitResume(Resume* curr) { + // This acts as a kitchen sink effect. + parent.calls = true; + + // resume instructions accept nullable continuation references and trap + // on null. + parent.implicitTrap = true; + + if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) { + parent.throws_ = true; + } + } }; public: diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index afe4a4c54..304ddb04d 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -341,6 +341,8 @@ struct CodeScanner counts.include(get->type); } else if (auto* set = curr->dynCast<ArraySet>()) { counts.note(set->ref->type); + } else if (auto* resume = curr->dynCast<Resume>()) { + counts.note(resume->contType); } else if (Properties::isControlFlowStructure(curr)) { counts.noteControlFlow(Signature(Type::none, curr->type)); } diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 67b33553d..2f900f0ed 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1199,6 +1199,11 @@ struct InfoCollector void visitReturn(Return* curr) { addResult(curr->value); } + void visitResume(Resume* curr) { + // TODO: optimize when possible + addRoot(curr); + } + void visitFunction(Function* func) { // Functions with a result can flow a value out from their body. addResult(func->body); diff --git a/src/ir/subtype-exprs.h b/src/ir/subtype-exprs.h index 86805f88a..65558b430 100644 --- a/src/ir/subtype-exprs.h +++ b/src/ir/subtype-exprs.h @@ -333,6 +333,8 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> { void visitStringIterMove(StringIterMove* curr) {} void visitStringSliceWTF(StringSliceWTF* curr) {} void visitStringSliceIter(StringSliceIter* curr) {} + + void visitResume(Resume* curr) { WASM_UNREACHABLE("not implemented"); } }; } // namespace wasm |