diff options
Diffstat (limited to 'src/tools')
-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 |
3 files changed, 36 insertions, 4 deletions
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; |