summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/fuzz_opt.py4
-rw-r--r--src/tools/fuzzing/fuzzing.cpp32
-rw-r--r--src/tools/fuzzing/heap-types.cpp5
-rw-r--r--src/tools/fuzzing/parameters.h3
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt73
5 files changed, 78 insertions, 39 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py
index ea4529ff2..d27f65b34 100755
--- a/scripts/fuzz_opt.py
+++ b/scripts/fuzz_opt.py
@@ -1398,7 +1398,9 @@ opt_choices = [
("--simplify-locals-notee-nostructure",),
("--ssa",),
("--type-refining",),
- ("--type-merging",),
+ # TypeMerging is blocked by
+ # https://github.com/WebAssembly/binaryen/issues/5556
+ # ("--type-merging",),
("--type-ssa",),
("--vacuum",),
]
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 3ef721db9..42d3ec3ba 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -277,11 +277,36 @@ void TranslateToFuzzReader::setupHeapTypes() {
// initial content we began with.
auto possibleHeapTypes = ModuleUtils::collectHeapTypes(wasm);
- // TODO: use heap type fuzzer to add new types in addition to the previous
-
// Filter away uninhabitable heap types, that is, heap types that we cannot
// construct, like a type with a non-nullable reference to itself.
interestingHeapTypes = HeapTypeGenerator::getInhabitable(possibleHeapTypes);
+
+ // For GC, also generate random types.
+ if (wasm.features.hasGC()) {
+ auto generator =
+ HeapTypeGenerator::create(random, wasm.features, upTo(MAX_NEW_GC_TYPES));
+ auto result = generator.builder.build();
+ if (auto* err = result.getError()) {
+ Fatal() << "Failed to build heap types: " << err->reason << " at index "
+ << err->index;
+ }
+
+ // Make the new types inhabitable. This process modifies existing types, so
+ // it leaves more available compared to HeapTypeGenerator::getInhabitable.
+ // We run that before on existing content, which may have instructions that
+ // use the types, as editing them is not trivial, and for new types here we
+ // are free to modify them so we keep as many as we can.
+ auto inhabitable = HeapTypeGenerator::makeInhabitable(*result);
+ for (auto type : inhabitable) {
+ // Trivial types are already handled specifically in e.g.
+ // getSingleConcreteType(), and we avoid adding them here as then we'd
+ // need to add code to avoid uninhabitable combinations of them (like a
+ // non-nullable bottom heap type).
+ if (!type.isBottom() && !type.isBasic()) {
+ interestingHeapTypes.push_back(type);
+ }
+ }
+ }
}
// TODO(reference-types): allow the fuzzer to create multiple tables
@@ -1992,6 +2017,7 @@ Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) {
(type.isNonNullable() && oneIn(16) && funcContext)) {
Expression* ret = builder.makeRefNull(HeapType::nofunc);
if (!type.isNullable()) {
+ assert(funcContext);
ret = builder.makeRefAs(RefAsNonNull, ret);
}
return ret;
@@ -2044,6 +2070,7 @@ Expression* TranslateToFuzzReader::makeConstBasicRef(Type type) {
// TODO: support actual non-nullable externrefs via imported globals or
// similar.
if (!type.isNullable()) {
+ assert(funcContext);
return builder.makeRefAs(RefAsNonNull, null);
}
return null;
@@ -2127,6 +2154,7 @@ Expression* TranslateToFuzzReader::makeConstBasicRef(Type type) {
case HeapType::nofunc: {
auto null = builder.makeRefNull(heapType);
if (!type.isNullable()) {
+ assert(funcContext);
return builder.makeRefAs(RefAsNonNull, null);
}
return null;
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index 0edeb833a..7fa0cd338 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -541,8 +541,9 @@ struct HeapTypeGeneratorImpl {
}
Signature generateSubSignature(Signature super) {
- return Signature(generateSupertype(super.params),
- generateSubtype(super.results));
+ auto params = generateSupertype(super.params);
+ auto results = generateSubtype(super.results);
+ return Signature(params, results);
}
Field generateSubField(Field super) {
diff --git a/src/tools/fuzzing/parameters.h b/src/tools/fuzzing/parameters.h
index e92c88210..9e5cefd9a 100644
--- a/src/tools/fuzzing/parameters.h
+++ b/src/tools/fuzzing/parameters.h
@@ -61,6 +61,9 @@ constexpr Address USABLE_MEMORY = 16;
// no hang protection.
constexpr int HANG_LIMIT = 100;
+// the maximum amount of new GC types (structs, etc.) to create
+constexpr int MAX_NEW_GC_TYPES = 25;
+
//
constexpr size_t VeryImportant = 4;
constexpr size_t Important = 2;
diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
index 80922d954..dc8be142a 100644
--- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
+++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
@@ -1,40 +1,45 @@
total
- [exports] : 8
- [funcs] : 15
- [globals] : 11
+ [exports] : 3
+ [funcs] : 4
+ [globals] : 5
[imports] : 5
[memories] : 1
[memory-data] : 20
- [table-data] : 5
+ [table-data] : 2
[tables] : 1
- [tags] : 1
- [total] : 538
- [vars] : 43
- ArrayNewFixed : 1
- AtomicFence : 2
- Binary : 67
- Block : 70
- Break : 1
- Call : 23
- CallRef : 1
- Const : 116
- Drop : 11
- GlobalGet : 36
- GlobalSet : 34
- I31New : 4
- If : 19
+ [tags] : 0
+ [total] : 682
+ [vars] : 3
+ AtomicCmpxchg : 1
+ AtomicFence : 3
+ AtomicNotify : 2
+ Binary : 76
+ Block : 105
+ Break : 15
+ Call : 5
+ CallRef : 3
+ Const : 170
+ Drop : 3
+ GlobalGet : 42
+ GlobalSet : 41
+ I31Get : 2
+ I31New : 2
+ If : 32
Load : 16
- LocalGet : 35
- LocalSet : 17
- Loop : 2
- MemoryInit : 1
- Nop : 5
- RefFunc : 17
- RefNull : 5
- Return : 4
- SIMDExtract : 1
- Store : 1
- StructNew : 5
- TupleMake : 9
- Unary : 18
- Unreachable : 17
+ LocalGet : 23
+ LocalSet : 19
+ Loop : 16
+ MemoryCopy : 1
+ MemoryFill : 2
+ MemoryInit : 2
+ Nop : 23
+ RefFunc : 7
+ RefNull : 1
+ Return : 5
+ SIMDExtract : 2
+ Select : 4
+ Store : 3
+ StructNew : 1
+ TupleMake : 2
+ Unary : 33
+ Unreachable : 20