diff options
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/Print.cpp | 21 | ||||
-rw-r--r-- | src/passes/TypeMerging.cpp | 11 | ||||
-rw-r--r-- | src/passes/TypeSSA.cpp | 6 |
3 files changed, 27 insertions, 11 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 5d49ad900..67d0dbdcc 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -3017,13 +3017,20 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { o << ')'; } void handleHeapType(HeapType type) { - bool hasSuper = false; - // TODO: Consider finality once we support that. - if (auto super = type.getSuperType()) { - hasSuper = true; + auto super = type.getSuperType(); + bool useSub = false; + // TODO: Once we parse MVP signature types as final, use the MVP shorthand + // for final types without supertypes. + if (super || type.isFinal()) { + useSub = true; o << "(sub "; - TypeNamePrinter(o, currModule).print(*super); - o << ' '; + if (type.isFinal()) { + o << "final "; + } + if (super) { + TypeNamePrinter(o, currModule).print(*super); + o << ' '; + } } if (type.isSignature()) { handleSignature(type); @@ -3034,7 +3041,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { } else { o << type; } - if (hasSuper) { + if (useSub) { o << ')'; } } diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp index 1897adc3c..fa36eb767 100644 --- a/src/passes/TypeMerging.cpp +++ b/src/passes/TypeMerging.cpp @@ -467,6 +467,9 @@ bool shapeEq(HeapType a, HeapType b) { // Check whether `a` and `b` have the same top-level structure, including the // position and identity of any children that are not included as transitions // in the DFA, i.e. any children that are not nontrivial references. + if (a.isFinal() != b.isFinal()) { + return false; + } if (a.isStruct() && b.isStruct()) { return shapeEq(a.getStruct(), b.getStruct()); } @@ -480,15 +483,15 @@ bool shapeEq(HeapType a, HeapType b) { } size_t shapeHash(HeapType a) { - size_t digest; + size_t digest = hash(a.isFinal()); if (a.isStruct()) { - digest = hash(0); + rehash(digest, 0); hash_combine(digest, shapeHash(a.getStruct())); } else if (a.isArray()) { - digest = hash(1); + rehash(digest, 1); hash_combine(digest, shapeHash(a.getArray())); } else if (a.isSignature()) { - digest = hash(2); + rehash(digest, 2); hash_combine(digest, shapeHash(a.getSignature())); } else { WASM_UNREACHABLE("unexpected kind"); diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index 33433083f..25575e70e 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -109,6 +109,7 @@ std::vector<HeapType> ensureTypesAreInNewRecGroup(RecGroup recGroup, if (auto super = type.getSuperType()) { builder[i].subTypeOf(*super); } + builder[i].setFinal(type.isFinal()); } // Implement the hash as a struct with "random" fields, and add it. @@ -306,6 +307,11 @@ struct TypeSSA : public Pass { return false; } + if (curr->type.getHeapType().isFinal()) { + // We can't create new subtypes of a final type anyway. + return false; + } + // Look for at least one interesting operand. We will consider each operand // against the declared type, that is, the type declared for where it is // stored. If it has more information than the declared type then it is |