summaryrefslogtreecommitdiff
path: root/src/tools/fuzzing
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/fuzzing')
-rw-r--r--src/tools/fuzzing/heap-types.cpp35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index cb33a65ed..174f3fd89 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -685,10 +685,8 @@ struct Inhabitator {
//
// An invariant field of a heaptype must have the same type in subtypes of
// that heaptype. A covariant field of a heaptype must be typed with a subtype
- // of its original type in subtypes of the heaptype. A contravariant field of
- // a heap type must be typed with a supertype of its original type in subtypes
- // of the heaptype.
- enum Variance { Invariant, Covariant, Contravariant };
+ // of its original type in subtypes of the heaptype.
+ enum Variance { Invariant, Covariant };
// The input types.
const std::vector<HeapType>& types;
@@ -712,7 +710,7 @@ struct Inhabitator {
Inhabitator::Variance Inhabitator::getVariance(FieldPos field) {
auto [type, idx] = field;
- assert(!type.isBasic());
+ assert(!type.isBasic() && !type.isSignature());
if (type.isStruct()) {
if (type.getStruct().fields[idx].mutable_ == Mutable) {
return Invariant;
@@ -727,13 +725,6 @@ Inhabitator::Variance Inhabitator::getVariance(FieldPos field) {
return Covariant;
}
}
- if (type.isSignature()) {
- if (idx < type.getSignature().params.size()) {
- return Contravariant;
- } else {
- return Covariant;
- }
- }
WASM_UNREACHABLE("unexpected kind");
}
@@ -768,8 +759,6 @@ void Inhabitator::markNullable(FieldPos field) {
curr = *super;
}
}
- [[fallthrough]];
- case Contravariant:
// Mark the field nullable in all subtypes. If the subtype field is
// already nullable, that's ok and this will have no effect. TODO: Remove
// this extra `index` variable once we have C++20. It's a workaround for
@@ -784,6 +773,11 @@ void Inhabitator::markNullable(FieldPos field) {
void Inhabitator::markBottomRefsNullable() {
for (auto type : types) {
+ if (type.isSignature()) {
+ // Functions can always be instantiated, even if their types refer to
+ // uninhabitable types.
+ continue;
+ }
auto children = type.getTypeChildren();
for (size_t i = 0; i < children.size(); ++i) {
auto child = children[i];
@@ -801,6 +795,11 @@ void Inhabitator::markExternRefsNullable() {
// TODO: Remove this once the fuzzer imports externref globals or gets some
// other way to instantiate externrefs.
for (auto type : types) {
+ if (type.isSignature()) {
+ // Functions can always be instantiated, even if their types refer to
+ // uninhabitable types.
+ continue;
+ }
auto children = type.getTypeChildren();
for (size_t i = 0; i < children.size(); ++i) {
auto child = children[i];
@@ -863,6 +862,14 @@ void Inhabitator::breakNonNullableCycles() {
++idx;
continue;
}
+ // Skip references to function types. Functions types can always be
+ // instantiated since functions can be created even with uninhabitable
+ // params or results. Function references therefore break cycles that
+ // would otherwise produce uninhabitability.
+ if (heapType.isSignature()) {
+ ++idx;
+ continue;
+ }
// If this ref forms a cycle, break the cycle by marking it nullable and
// continue.
if (auto it = visiting.find(heapType); it != visiting.end()) {