summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-04-19 17:22:28 -0700
committerGitHub <noreply@github.com>2023-04-19 17:22:28 -0700
commit9e5961792a91774962815d58c5c73bfb5612e27c (patch)
tree5f076b905041cc31c0cb58b298f010cbe0a4e226 /src
parent7cd2396dacf276750a3e27320d6b9d2af6f939d9 (diff)
downloadbinaryen-9e5961792a91774962815d58c5c73bfb5612e27c.tar.gz
binaryen-9e5961792a91774962815d58c5c73bfb5612e27c.tar.bz2
binaryen-9e5961792a91774962815d58c5c73bfb5612e27c.zip
Remove the ability to construct basic types in a TypeBuilder (#5678)
This capability was originally introduced to support calculating LUBs in the equirecursive type system, but has not been needed for anything except tests since the equirecursive type system was removed. Since building basic heap types is no longer useful and was a source of significant complexity, remove the APIs that allowed it and the tests that used those APIs. Also remove test/example/type-builder.cpp, since a significant portion of it tested the removed APIs and the rest is already better tested in test/gtest/type-builder.cpp.
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp13
-rw-r--r--src/binaryen-c.h12
-rw-r--r--src/tools/fuzzing/heap-types.cpp81
-rw-r--r--src/tools/wasm-fuzz-types.cpp58
-rw-r--r--src/wasm-type.h15
-rw-r--r--src/wasm/wasm-type.cpp130
6 files changed, 35 insertions, 274 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index b23d53ad6..03132b23a 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -6321,12 +6321,6 @@ void TypeBuilderGrow(TypeBuilderRef builder, BinaryenIndex count) {
BinaryenIndex TypeBuilderGetSize(TypeBuilderRef builder) {
return ((TypeBuilder*)builder)->size();
}
-void TypeBuilderSetBasicHeapType(TypeBuilderRef builder,
- BinaryenIndex index,
- BinaryenBasicHeapType basicHeapType) {
- ((TypeBuilder*)builder)
- ->setHeapType(index, HeapType::BasicHeapType(basicHeapType));
-}
void TypeBuilderSetSignatureType(TypeBuilderRef builder,
BinaryenIndex index,
BinaryenType paramTypes,
@@ -6370,13 +6364,6 @@ void TypeBuilderSetArrayType(TypeBuilderRef builder,
}
B->setHeapType(index, Array(element));
}
-bool TypeBuilderIsBasic(TypeBuilderRef builder, BinaryenIndex index) {
- return ((TypeBuilder*)builder)->isBasic(index);
-}
-BinaryenBasicHeapType TypeBuilderGetBasic(TypeBuilderRef builder,
- BinaryenIndex index) {
- return BinaryenBasicHeapType(((TypeBuilder*)builder)->getBasic(index));
-}
BinaryenHeapType TypeBuilderGetTempHeapType(TypeBuilderRef builder,
BinaryenIndex index) {
return ((TypeBuilder*)builder)->getTempHeapType(index).getID();
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index d05bdf33b..a199561f0 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -3525,12 +3525,6 @@ BINARYEN_API TypeBuilderRef TypeBuilderCreate(BinaryenIndex size);
BINARYEN_API void TypeBuilderGrow(TypeBuilderRef builder, BinaryenIndex count);
// Gets the size of the backing table of the type builder.
BINARYEN_API BinaryenIndex TypeBuilderGetSize(TypeBuilderRef builder);
-// Sets the heap type at index `index` to a basic heap type. Must not be used in
-// nominal mode.
-BINARYEN_API void
-TypeBuilderSetBasicHeapType(TypeBuilderRef builder,
- BinaryenIndex index,
- BinaryenBasicHeapType basicHeapType);
// Sets the heap type at index `index` to a concrete signature type. Expects
// temporary tuple types if multiple parameter and/or result types include
// temporary types.
@@ -3551,12 +3545,6 @@ BINARYEN_API void TypeBuilderSetArrayType(TypeBuilderRef builder,
BinaryenType elementType,
BinaryenPackedType elementPackedType,
int elementMutable);
-// Tests if the heap type at index `index` is a basic heap type.
-BINARYEN_API bool TypeBuilderIsBasic(TypeBuilderRef builder,
- BinaryenIndex index);
-// Gets the basic heap type at index `index`.
-BINARYEN_API BinaryenBasicHeapType TypeBuilderGetBasic(TypeBuilderRef builder,
- BinaryenIndex index);
// Gets the temporary heap type to use at index `index`. Temporary heap types
// may only be used to construct temporary types using the type builder.
BINARYEN_API BinaryenHeapType TypeBuilderGetTempHeapType(TypeBuilderRef builder,
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index e58c7f51d..26cc518be 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -40,12 +40,10 @@ struct HeapTypeGeneratorImpl {
// Top-level kinds, chosen before the types are actually constructed. This
// allows us to choose HeapTypes that we know will be subtypes of data or func
// before we actually generate the types.
- using BasicKind = HeapType::BasicHeapType;
struct SignatureKind {};
struct StructKind {};
struct ArrayKind {};
- using HeapTypeKind =
- std::variant<BasicKind, SignatureKind, StructKind, ArrayKind>;
+ using HeapTypeKind = std::variant<SignatureKind, StructKind, ArrayKind>;
std::vector<HeapTypeKind> typeKinds;
// For each type, the index one past the end of its recursion group, used to
@@ -83,7 +81,7 @@ struct HeapTypeGeneratorImpl {
builder[i].subTypeOf(builder[super]);
supertypeIndices[i] = super;
subtypeIndices[super].push_back(i);
- typeKinds.push_back(getSubKind(typeKinds[super]));
+ typeKinds.push_back(typeKinds[super]);
}
}
@@ -110,11 +108,7 @@ struct HeapTypeGeneratorImpl {
// Create the heap types.
for (; index < builder.size(); ++index) {
auto kind = typeKinds[index];
- if (auto* basic = std::get_if<BasicKind>(&kind)) {
- // The type is already determined.
- builder[index] = *basic;
- } else if (!supertypeIndices[index] ||
- builder.isBasic(*supertypeIndices[index])) {
+ if (!supertypeIndices[index]) {
// No nontrivial supertype, so create a root type.
if (std::get_if<SignatureKind>(&kind)) {
builder[index] = generateSignature();
@@ -365,9 +359,7 @@ struct HeapTypeGeneratorImpl {
// the builder.
if (rand.oneIn(candidates.size() * 8)) {
auto* kind = &typeKinds[it->second];
- if (auto* basic = std::get_if<BasicKind>(kind)) {
- return HeapType(*basic).getBottom();
- } else if (std::get_if<SignatureKind>(kind)) {
+ if (std::get_if<SignatureKind>(kind)) {
return HeapType::nofunc;
} else {
return HeapType::none;
@@ -434,9 +426,7 @@ struct HeapTypeGeneratorImpl {
candidates.push_back(HeapType::func);
return rand.pick(candidates);
} else {
- // A constructed basic type. Fall through to add all of the basic
- // supertypes as well.
- type = *std::get_if<BasicKind>(kind);
+ WASM_UNREACHABLE("unexpected kind");
}
}
// This is not a constructed type, so it must be a basic type.
@@ -576,70 +566,9 @@ struct HeapTypeGeneratorImpl {
return StructKind{};
case 2:
return ArrayKind{};
- case 3:
- return BasicKind{generateBasicHeapType()};
}
WASM_UNREACHABLE("unexpected index");
}
-
- HeapTypeKind getSubKind(HeapTypeKind super) {
- if (rand.oneIn(16)) {
- // Occasionally go directly to the bottom type.
- if (auto* basic = std::get_if<BasicKind>(&super)) {
- return HeapType(*basic).getBottom();
- } else if (std::get_if<SignatureKind>(&super)) {
- return HeapType::nofunc;
- } else if (std::get_if<StructKind>(&super)) {
- return HeapType::none;
- } else if (std::get_if<ArrayKind>(&super)) {
- return HeapType::none;
- }
- WASM_UNREACHABLE("unexpected kind");
- }
- if (auto* basic = std::get_if<BasicKind>(&super)) {
- if (rand.oneIn(8)) {
- return super;
- }
- switch (*basic) {
- case HeapType::func:
- return SignatureKind{};
- case HeapType::ext:
- case HeapType::i31:
- return super;
- case HeapType::any:
- if (rand.oneIn(5)) {
- return HeapType::eq;
- }
- [[fallthrough]];
- case HeapType::eq:
- switch (rand.upTo(3)) {
- case 0:
- return HeapType::i31;
- case 1:
- return StructKind{};
- case 2:
- return ArrayKind{};
- }
- WASM_UNREACHABLE("unexpected index");
- case HeapType::struct_:
- return StructKind{};
- case HeapType::array:
- return ArrayKind{};
- case HeapType::string:
- case HeapType::stringview_wtf8:
- case HeapType::stringview_wtf16:
- case HeapType::stringview_iter:
- case HeapType::none:
- case HeapType::noext:
- case HeapType::nofunc:
- return super;
- }
- WASM_UNREACHABLE("unexpected kind");
- } else {
- // Signature and Data types can only have Signature and Data subtypes.
- return super;
- }
- }
};
} // anonymous namespace
diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp
index 0dc9f9d17..4f480ba9d 100644
--- a/src/tools/wasm-fuzz-types.cpp
+++ b/src/tools/wasm-fuzz-types.cpp
@@ -104,7 +104,7 @@ void Fuzzer::printTypes(const std::vector<HeapType>& types) {
auto inRecGroup = [&]() { return currRecGroup && currRecGroup->size() > 1; };
for (size_t i = 0; i < types.size(); ++i) {
auto type = types[i];
- if (!type.isBasic() && type.getRecGroup() != currRecGroup) {
+ if (type.getRecGroup() != currRecGroup) {
if (inRecGroup()) {
std::cout << ")\n";
}
@@ -116,10 +116,6 @@ void Fuzzer::printTypes(const std::vector<HeapType>& types) {
if (inRecGroup()) {
std::cout << ' ';
}
- if (type.isBasic()) {
- std::cout << "(type $" << i << ' ' << print(type) << ")\n";
- continue;
- }
auto [it, inserted] = seen.insert({type, i});
if (inserted) {
std::cout << print(type);
@@ -280,13 +276,9 @@ void Fuzzer::checkCanonicalization() {
currGroupStart = end;
};
for (Index i = 0; i < types.size(); ++i) {
- auto type = types[i];
- if (type.isBasic()) {
- continue;
- }
- auto newGroup = type.getRecGroup();
+ auto newGroup = types[i].getRecGroup();
if (!currGroup || newGroup != currGroup ||
- type == types[currGroupStart]) {
+ types[i] == types[currGroupStart]) {
finishGroup(i);
currGroup = newGroup;
}
@@ -296,9 +288,7 @@ void Fuzzer::checkCanonicalization() {
// Copy the original types
for (; index < types.size(); ++index) {
auto type = types[index];
- if (type.isBasic()) {
- builder[index] = type.getBasic();
- } else if (type.isSignature()) {
+ if (type.isSignature()) {
builder[index] = getSignature(type.getSignature());
} else if (type.isStruct()) {
builder[index] = getStruct(type.getStruct());
@@ -333,28 +323,27 @@ void Fuzzer::checkCanonicalization() {
CopiedHeapType getChildHeapType(HeapType old) {
auto it = typeIndices.find(old);
if (it == typeIndices.end()) {
- // This is a basic heap type that wasn't explicitly built.
+ // This is a basic heap type and wasn't explicitly built.
assert(old.isBasic());
return {OldHeapType{old}};
}
- if (!old.isBasic()) {
- // Check whether this child heap type is supposed to be a self-reference
- // into the recursion group we are defining. If it is, we must use the
- // corresponding type in the new recursion group, since anything else
- // would break isorecursive equivalence.
- auto group = old.getRecGroup();
- if (group == types[index].getRecGroup()) {
- // This is a self-reference, so find the correct index, which is the
- // last matching index less than the end of this rec group.
- std::optional<Index> i;
- for (auto candidate : it->second) {
- if (candidate >= recGroupEnds[index]) {
- break;
- }
- i = candidate;
+ assert(!old.isBasic());
+ // Check whether this child heap type is supposed to be a self-reference
+ // into the recursion group we are defining. If it is, we must use the
+ // corresponding type in the new recursion group, since anything else
+ // would break isorecursive equivalence.
+ auto group = old.getRecGroup();
+ if (group == types[index].getRecGroup()) {
+ // This is a self-reference, so find the correct index, which is the
+ // last matching index less than the end of this rec group.
+ std::optional<Index> i;
+ for (auto candidate : it->second) {
+ if (candidate >= recGroupEnds[index]) {
+ break;
}
- return {NewHeapType{builder[*i]}};
+ i = candidate;
}
+ return {NewHeapType{builder[*i]}};
}
// Choose whether to use an old type or a new type
if (rand.oneIn(2)) {
@@ -366,12 +355,7 @@ void Fuzzer::checkCanonicalization() {
candidateIndices.push_back(i);
}
}
- if (candidateIndices.empty()) {
- // This is a basic type that was only ever created after the current
- // rec group, so we can't refer to a new copy of it after all.
- assert(old.isBasic());
- return {OldHeapType{old}};
- }
+ assert(!candidateIndices.empty());
Index i = rand.pick(candidateIndices);
return {NewHeapType{builder[i]}};
} else {
diff --git a/src/wasm-type.h b/src/wasm-type.h
index ad0606d59..551096fb5 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -579,21 +579,12 @@ struct TypeBuilder {
// The number of HeapType slots in the TypeBuilder.
size_t size();
- // Sets the heap type at index `i`. May only be called before `build`. The
- // BasicHeapType overload may not be used in nominal mode.
- void setHeapType(size_t i, HeapType::BasicHeapType basic);
+ // Sets the heap type at index `i`. May only be called before `build`.
void setHeapType(size_t i, Signature signature);
void setHeapType(size_t i, const Struct& struct_);
void setHeapType(size_t i, Struct&& struct_);
void setHeapType(size_t i, Array array);
- // This is an ugly hack around the fact that temp heap types initialized with
- // BasicHeapTypes are not themselves considered basic, so `HeapType::isBasic`
- // and `HeapType::getBasic` do not work as expected with them. Call these
- // methods instead.
- bool isBasic(size_t i);
- HeapType::BasicHeapType getBasic(size_t i);
-
// Gets the temporary HeapType at index `i`. This HeapType should only be used
// to construct temporary Types using the methods below.
HeapType getTempHeapType(size_t i);
@@ -653,10 +644,6 @@ struct TypeBuilder {
TypeBuilder& builder;
size_t index;
operator HeapType() const { return builder.getTempHeapType(index); }
- Entry& operator=(HeapType::BasicHeapType basic) {
- builder.setHeapType(index, basic);
- return *this;
- }
Entry& operator=(Signature signature) {
builder.setHeapType(index, signature);
return *this;
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index c9c35ac49..f697ba5a3 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -77,9 +77,8 @@ struct TypeInfo {
bool isNullable() const { return kind == RefKind && ref.nullable; }
// If this TypeInfo represents a Type that can be represented more simply,
- // return that simpler Type. For example, this handles canonicalizing the
- // TypeInfo representing (ref null any) into the BasicType anyref. It also
- // handles eliminating singleton tuple types.
+ // return that simpler Type. For example, this handles eliminating singleton
+ // tuple types.
std::optional<Type> getCanonical() const;
bool operator==(const TypeInfo& other) const;
@@ -105,7 +104,6 @@ struct HeapTypeInfo {
RecGroupInfo* recGroup = nullptr;
size_t recGroupIndex = 0;
enum Kind {
- BasicKind,
SignatureKind,
StructKind,
ArrayKind,
@@ -117,7 +115,6 @@ struct HeapTypeInfo {
Array array;
};
- HeapTypeInfo(HeapType::BasicHeapType basic) : kind(BasicKind), basic(basic) {}
HeapTypeInfo(Signature sig) : kind(SignatureKind), signature(sig) {}
HeapTypeInfo(const Struct& struct_) : kind(StructKind), struct_(struct_) {}
HeapTypeInfo(Struct&& struct_)
@@ -131,11 +128,6 @@ struct HeapTypeInfo {
constexpr bool isArray() const { return kind == ArrayKind; }
constexpr bool isData() const { return isStruct() || isArray(); }
- // If this HeapTypeInfo represents a HeapType that can be represented more
- // simply, return that simpler HeapType. This handles turning BasicKind
- // HeapTypes into their corresponding BasicHeapTypes.
- std::optional<HeapType> getCanonical() const;
-
HeapTypeInfo& operator=(const HeapTypeInfo& other);
bool operator==(const HeapTypeInfo& other) const;
bool operator!=(const HeapTypeInfo& other) const { return !(*this == other); }
@@ -455,27 +447,12 @@ bool isTemp(HeapType type) {
return !type.isBasic() && getHeapTypeInfo(type)->isTemp;
}
-// Given a Type that may or may not be backed by the simplest possible
-// representation, return the equivalent type that is definitely backed by the
-// simplest possible representation.
-Type asCanonical(Type type) {
- if (type.isBasic()) {
- return type;
- } else if (auto canon = getTypeInfo(type)->getCanonical()) {
- return *canon;
- } else {
- return type;
- }
-}
-
HeapType::BasicHeapType getBasicHeapSupertype(HeapType type) {
if (type.isBasic()) {
return type.getBasic();
}
auto* info = getHeapTypeInfo(type);
switch (info->kind) {
- case HeapTypeInfo::BasicKind:
- break;
case HeapTypeInfo::SignatureKind:
return HeapType::func;
case HeapTypeInfo::StructKind:
@@ -597,9 +574,6 @@ HeapTypeInfo::HeapTypeInfo(const HeapTypeInfo& other) {
supertype = other.supertype;
recGroup = other.recGroup;
switch (kind) {
- case BasicKind:
- new (&basic) auto(other.basic);
- return;
case SignatureKind:
new (&signature) auto(other.signature);
return;
@@ -615,8 +589,6 @@ HeapTypeInfo::HeapTypeInfo(const HeapTypeInfo& other) {
HeapTypeInfo::~HeapTypeInfo() {
switch (kind) {
- case BasicKind:
- return;
case SignatureKind:
signature.~Signature();
return;
@@ -630,13 +602,6 @@ HeapTypeInfo::~HeapTypeInfo() {
WASM_UNREACHABLE("unexpected kind");
}
-std::optional<HeapType> HeapTypeInfo::getCanonical() const {
- if (isFinalized && kind == BasicKind) {
- return basic;
- }
- return {};
-}
-
HeapTypeInfo& HeapTypeInfo::operator=(const HeapTypeInfo& other) {
if (&other != this) {
this->~HeapTypeInfo();
@@ -702,9 +667,11 @@ private:
return typename Info::type_t(id);
};
- // Turn e.g. (ref null any) into anyref.
- if (auto canonical = info.getCanonical()) {
- return *canonical;
+ // Turn e.g. singleton tuple into non-tuple.
+ if constexpr (std::is_same_v<Info, TypeInfo>) {
+ if (auto canonical = info.getCanonical()) {
+ return *canonical;
+ }
}
std::lock_guard<std::recursive_mutex> lock(mutex);
// Check whether we already have a type for this structural Info.
@@ -1376,8 +1343,6 @@ HeapType::BasicHeapType HeapType::getBottom() const {
}
auto* info = getHeapTypeInfo(*this);
switch (info->kind) {
- case HeapTypeInfo::BasicKind:
- return HeapType(info->basic).getBottom();
case HeapTypeInfo::SignatureKind:
return nofunc;
case HeapTypeInfo::StructKind:
@@ -1861,10 +1826,7 @@ std::ostream& TypePrinter::print(HeapType type) {
#if TRACE_CANONICALIZATION
os << "(;" << ((type.getID() >> 4) % 1000) << ";)";
#endif
- if (getHeapTypeInfo(type)->kind == HeapTypeInfo::BasicKind) {
- os << "(; noncanonical ;) ";
- print(getHeapTypeInfo(type)->basic);
- } else if (type.isSignature()) {
+ if (type.isSignature()) {
print(type.getSignature(), type.getSuperType());
} else if (type.isStruct()) {
print(type.getStruct(), type.getSuperType());
@@ -2045,8 +2007,6 @@ size_t RecGroupHasher::hash(const HeapTypeInfo& info) const {
}
wasm::rehash(digest, info.kind);
switch (info.kind) {
- case HeapTypeInfo::BasicKind:
- WASM_UNREACHABLE("Basic HeapTypeInfo should have been canonicalized");
case HeapTypeInfo::SignatureKind:
hash_combine(digest, hash(info.signature));
return digest;
@@ -2171,8 +2131,6 @@ bool RecGroupEquator::eq(const HeapTypeInfo& a, const HeapTypeInfo& b) const {
return false;
}
switch (a.kind) {
- case HeapTypeInfo::BasicKind:
- WASM_UNREACHABLE("Basic HeapTypeInfo should have been canonicalized");
case HeapTypeInfo::SignatureKind:
return eq(a.signature, b.signature);
case HeapTypeInfo::StructKind:
@@ -2282,8 +2240,6 @@ void TypeGraphWalkerBase<Self>::scanHeapType(HeapType* ht) {
}
auto* info = getHeapTypeInfo(*ht);
switch (info->kind) {
- case HeapTypeInfo::BasicKind:
- break;
case HeapTypeInfo::SignatureKind:
taskList.push_back(Task::scan(&info->signature.results));
taskList.push_back(Task::scan(&info->signature.params));
@@ -2355,11 +2311,6 @@ void TypeBuilder::grow(size_t n) {
size_t TypeBuilder::size() { return impl->entries.size(); }
-void TypeBuilder::setHeapType(size_t i, HeapType::BasicHeapType basic) {
- assert(i < size() && "Index out of bounds");
- impl->entries[i].set(basic);
-}
-
void TypeBuilder::setHeapType(size_t i, Signature signature) {
assert(i < size() && "index out of bounds");
impl->entries[i].set(signature);
@@ -2380,16 +2331,6 @@ void TypeBuilder::setHeapType(size_t i, Array array) {
impl->entries[i].set(array);
}
-bool TypeBuilder::isBasic(size_t i) {
- assert(i < size() && "index out of bounds");
- return impl->entries[i].info->kind == HeapTypeInfo::BasicKind;
-}
-
-HeapType::BasicHeapType TypeBuilder::getBasic(size_t i) {
- assert(isBasic(i));
- return impl->entries[i].info->basic;
-}
-
HeapType TypeBuilder::getTempHeapType(size_t i) {
assert(i < size() && "index out of bounds");
return impl->entries[i].get();
@@ -2469,8 +2410,6 @@ struct CanonicalizationState {
// Updates the HeapType use sites within `info`.
void updateUses(ReplacementMap& replacements,
std::unique_ptr<HeapTypeInfo>& info);
- // Updates lists and uses.
- void update(ReplacementMap& replacements);
#if TRACE_CANONICALIZATION
void dump() {
@@ -2488,16 +2427,6 @@ struct CanonicalizationState {
#endif // TRACE_CANONICALIZATION
};
-void CanonicalizationState::update(ReplacementMap& replacements) {
- if (replacements.empty()) {
- return;
- }
- updateShallow(replacements);
- for (auto& info : newInfos) {
- updateUses(replacements, info);
- }
-}
-
void CanonicalizationState::updateShallow(ReplacementMap& replacements) {
if (replacements.empty()) {
return;
@@ -2670,8 +2599,6 @@ validateSubtyping(const std::vector<HeapType>& types) {
}
SubTyper typer;
switch (sub->kind) {
- case HeapTypeInfo::BasicKind:
- WASM_UNREACHABLE("unexpected kind");
case HeapTypeInfo::SignatureKind:
if (!typer.isSubType(sub->signature, super->signature)) {
return fail();
@@ -2803,43 +2730,6 @@ std::optional<TypeBuilder::Error> canonicalizeIsorecursive(
return {};
}
-void canonicalizeBasicTypes(CanonicalizationState& state) {
- // Replace heap types backed by BasicKind HeapTypeInfos with their
- // corresponding BasicHeapTypes. The heap types backed by BasicKind
- // HeapTypeInfos exist only to support building basic types in a TypeBuilder
- // and are never canonical.
- CanonicalizationState::ReplacementMap replacements;
- for (auto& info : state.newInfos) {
- if (info->kind == HeapTypeInfo::BasicKind) {
- replacements.insert({asHeapType(info), HeapType(info->basic)});
- }
- // Basic supertypes should be implicit.
- if (info->supertype && info->supertype->kind == HeapTypeInfo::BasicKind) {
- info->supertype = nullptr;
- }
- }
- state.update(replacements);
-
- if (replacements.size()) {
- // Canonicalizing basic heap types may cause their parent types to become
- // canonicalizable as well, for example after creating `(ref null any)` we
- // can futher canonicalize to `anyref`.
- struct TypeCanonicalizer : TypeGraphWalkerBase<TypeCanonicalizer> {
- void scanType(Type* type) {
- if (type->isTuple()) {
- TypeGraphWalkerBase<TypeCanonicalizer>::scanType(type);
- } else {
- *type = asCanonical(*type);
- }
- }
- };
- for (auto& info : state.newInfos) {
- auto root = asHeapType(info);
- TypeCanonicalizer{}.walkRoot(&root);
- }
- }
-}
-
} // anonymous namespace
TypeBuilder::BuildResult TypeBuilder::build() {
@@ -2859,10 +2749,6 @@ TypeBuilder::BuildResult TypeBuilder::build() {
state.newInfos.emplace_back(std::move(info));
}
- // Eagerly replace references to built basic heap types so the more
- // complicated canonicalization algorithms don't need to consider them.
- canonicalizeBasicTypes(state);
-
#if TRACE_CANONICALIZATION
std::cerr << "After replacing basic heap types:\n";
state.dump();