summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/ReFinalize.cpp1
-rw-r--r--src/ir/cost.h4
-rw-r--r--src/ir/effects.h4
-rw-r--r--src/ir/module-utils.cpp2
-rw-r--r--src/ir/possible-contents.cpp4
-rw-r--r--src/ir/subtype-exprs.h1
6 files changed, 16 insertions, 0 deletions
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 0338f630c..7c81b0d0d 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -182,6 +182,7 @@ void ReFinalize::visitStringSliceIter(StringSliceIter* curr) {
curr->finalize();
}
+void ReFinalize::visitContNew(ContNew* curr) { curr->finalize(); }
void ReFinalize::visitResume(Resume* curr) { curr->finalize(); }
void ReFinalize::visitExport(Export* curr) { WASM_UNREACHABLE("unimp"); }
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 821e46524..7a8776c00 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -726,6 +726,10 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
return 8 + visit(curr->ref) + visit(curr->num);
}
+ CostType visitContNew(ContNew* curr) {
+ // Some arbitrary "high" value, reflecting that this may allocate a stack
+ return 14 + visit(curr->func);
+ }
CostType visitResume(Resume* curr) {
// Inspired by indirect calls, but twice the cost.
return 12 + visit(curr->cont);
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 3ff320a88..d0af932bd 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -974,6 +974,10 @@ private:
parent.implicitTrap = true;
}
+ void visitContNew(ContNew* curr) {
+ // traps when curr->func is null ref.
+ parent.implicitTrap = true;
+ }
void visitResume(Resume* curr) {
// This acts as a kitchen sink effect.
parent.calls = true;
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp
index 304ddb04d..b61fddd8b 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* contNew = curr->dynCast<ContNew>()) {
+ counts.note(contNew->contType);
} else if (auto* resume = curr->dynCast<Resume>()) {
counts.note(resume->contType);
} else if (Properties::isControlFlowStructure(curr)) {
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index 8d6891017..d0b0ea3ae 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -1200,6 +1200,10 @@ struct InfoCollector
void visitReturn(Return* curr) { addResult(curr->value); }
+ void visitContNew(ContNew* curr) {
+ // TODO: optimize when possible
+ addRoot(curr);
+ }
void visitResume(Resume* curr) {
// TODO: optimize when possible
addRoot(curr);
diff --git a/src/ir/subtype-exprs.h b/src/ir/subtype-exprs.h
index 056b373c2..6b8348319 100644
--- a/src/ir/subtype-exprs.h
+++ b/src/ir/subtype-exprs.h
@@ -368,6 +368,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> {
void visitStringSliceWTF(StringSliceWTF* curr) {}
void visitStringSliceIter(StringSliceIter* curr) {}
+ void visitContNew(ContNew* curr) { WASM_UNREACHABLE("not implemented"); }
void visitResume(Resume* curr) { WASM_UNREACHABLE("not implemented"); }
};