summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-10-29 11:41:43 -0700
committerGitHub <noreply@github.com>2024-10-29 11:41:43 -0700
commit2a1cb314d6a028cfd54374f89a47e111678c3d25 (patch)
tree33cd9be7cc4112ddd6a86c5f381bd50133e9d064 /src
parent3d3a38700f29236eb7e66742fdc2df8616ab7599 (diff)
downloadbinaryen-2a1cb314d6a028cfd54374f89a47e111678c3d25.tar.gz
binaryen-2a1cb314d6a028cfd54374f89a47e111678c3d25.tar.bz2
binaryen-2a1cb314d6a028cfd54374f89a47e111678c3d25.zip
[GC] Fix handling of public types in TypeRefining (#7037)
Diffstat (limited to 'src')
-rw-r--r--src/passes/TypeRefining.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/passes/TypeRefining.cpp b/src/passes/TypeRefining.cpp
index c7a1fce6e..ee12c388d 100644
--- a/src/passes/TypeRefining.cpp
+++ b/src/passes/TypeRefining.cpp
@@ -137,6 +137,11 @@ struct TypeRefining : public Pass {
// that we can avoid wasteful work later if not.
bool canOptimize = false;
+ // We cannot modify public types.
+ auto publicTypes = ModuleUtils::getPublicHeapTypes(*module);
+ std::unordered_set<HeapType> publicTypesSet(publicTypes.begin(),
+ publicTypes.end());
+
// We have combined all the information we have about writes to the fields,
// but we still need to make sure that the new types makes sense. In
// particular, subtyping cares about things like mutability, and we also
@@ -155,6 +160,14 @@ struct TypeRefining : public Pass {
while (!work.empty()) {
auto type = work.pop();
+ for (auto subType : subTypes.getImmediateSubTypes(type)) {
+ work.push(subType);
+ }
+
+ if (publicTypesSet.count(type)) {
+ continue;
+ }
+
// First, find fields that have nothing written to them at all, and set
// their value to their old type. We must pick some type for the field,
// and we have nothing better to go on. (If we have a super, and it does
@@ -173,7 +186,14 @@ struct TypeRefining : public Pass {
if (auto super = type.getDeclaredSuperType()) {
auto& superFields = super->getStruct().fields;
for (Index i = 0; i < superFields.size(); i++) {
- auto newSuperType = finalInfos[*super][i].getLUB();
+ // The super's new type is either what we propagated, or, if it is
+ // public, unchanged since we cannot optimize it
+ Type newSuperType;
+ if (!publicTypesSet.count(*super)) {
+ newSuperType = finalInfos[*super][i].getLUB();
+ } else {
+ newSuperType = superFields[i].type;
+ }
auto& info = finalInfos[type][i];
auto newType = info.getLUB();
if (!Type::isSubType(newType, newSuperType)) {
@@ -215,10 +235,6 @@ struct TypeRefining : public Pass {
canOptimize = true;
}
}
-
- for (auto subType : subTypes.getImmediateSubTypes(type)) {
- work.push(subType);
- }
}
if (canOptimize) {