diff options
-rwxr-xr-x | scripts/fuzz_opt.py | 4 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 32 | ||||
-rw-r--r-- | src/tools/fuzzing/heap-types.cpp | 5 | ||||
-rw-r--r-- | src/tools/fuzzing/parameters.h | 3 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_all-features_metrics_noprint.txt | 73 |
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 |