diff options
-rw-r--r-- | src/tools/fuzzing.h | 4 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 47 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_all-features_metrics_noprint.txt | 64 |
3 files changed, 77 insertions, 38 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 5529a14a8..830e204f8 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -109,6 +109,9 @@ private: std::vector<Type> loggableTypes; + // The heap types we can pick from to generate instructions. + std::vector<HeapType> interestingHeapTypes; + Index numAddedFunctions = 0; // RAII helper for managing the state used to create a single function. @@ -315,6 +318,7 @@ private: Type getStorableType(); Type getLoggableType(); bool isLoggableType(Type type); + Nullability getNullability(); Nullability getSubType(Nullability nullability); HeapType getSubType(HeapType type); Type getSubType(Type type); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 1159dcb0c..3ef721db9 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -15,6 +15,7 @@ */ #include "tools/fuzzing.h" +#include "ir/module-utils.h" #include "ir/type-updating.h" #include "tools/fuzzing/heap-types.h" #include "tools/fuzzing/parameters.h" @@ -168,6 +169,7 @@ void TranslateToFuzzReader::build() { if (allowMemory) { setupMemory(); } + setupHeapTypes(); setupTables(); setupGlobals(); if (wasm.features.hasExceptionHandling()) { @@ -270,6 +272,18 @@ void TranslateToFuzzReader::setupMemory() { } } +void TranslateToFuzzReader::setupHeapTypes() { + // Start with any existing heap types in the module, which may exist in any + // 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); +} + // TODO(reference-types): allow the fuzzer to create multiple tables void TranslateToFuzzReader::setupTables() { // Ensure a funcref element segment and table exist. Segments with more @@ -3070,7 +3084,11 @@ Expression* TranslateToFuzzReader::makeMemoryFill() { } Type TranslateToFuzzReader::getSingleConcreteType() { - // TODO: Nontrivial reference types. + if (wasm.features.hasReferenceTypes() && oneIn(3)) { + auto heapType = pick(interestingHeapTypes); + auto nullability = getNullability(); + return Type(heapType, nullability); + } // Skip (ref func), (ref extern), and (ref i31) for now // because there is no way to create them in globals. TODO. using WeightedOption = FeatureOptions<Type>::WeightedOption; @@ -3100,6 +3118,11 @@ Type TranslateToFuzzReader::getSingleConcreteType() { } Type TranslateToFuzzReader::getReferenceType() { + if (wasm.features.hasReferenceTypes() && oneIn(2)) { + auto heapType = pick(interestingHeapTypes); + auto nullability = getNullability(); + return Type(heapType, nullability); + } return pick(FeatureOptions<Type>() // TODO: Add externref here. .add(FeatureSet::ReferenceTypes, Type(HeapType::func, Nullable)) @@ -3117,6 +3140,15 @@ Type TranslateToFuzzReader::getReferenceType() { } Type TranslateToFuzzReader::getEqReferenceType() { + if (oneIn(2)) { + // Try to find an interesting eq-compatible type. + auto heapType = pick(interestingHeapTypes); + if (HeapType::isSubType(heapType, HeapType::eq)) { + auto nullability = getNullability(); + return Type(heapType, nullability); + } + // Otherwise continue below. + } return pick( FeatureOptions<Type>().add(FeatureSet::ReferenceTypes | FeatureSet::GC, Type(HeapType::eq, Nullable), @@ -3180,10 +3212,7 @@ bool TranslateToFuzzReader::isLoggableType(Type type) { loggableTypes.end(); } -Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { - if (nullability == NonNullable) { - return NonNullable; - } +Nullability TranslateToFuzzReader::getNullability() { // Without wasm GC, avoid non-nullable types as we cannot create any values // of such types. For example, reference types adds eqref, but there is no // way to create such a value, only to receive it from the outside, while GC @@ -3196,7 +3225,15 @@ Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { return Nullable; } +Nullability TranslateToFuzzReader::getSubType(Nullability nullability) { + if (nullability == NonNullable) { + return NonNullable; + } + return getNullability(); +} + HeapType TranslateToFuzzReader::getSubType(HeapType type) { + // TODO: pick from heapTypes if (oneIn(2)) { return type; } 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 4fa1549f3..80922d954 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,42 +1,40 @@ total - [exports] : 11 - [funcs] : 25 + [exports] : 8 + [funcs] : 15 [globals] : 11 [imports] : 5 [memories] : 1 [memory-data] : 20 - [table-data] : 7 + [table-data] : 5 [tables] : 1 [tags] : 1 - [total] : 877 - [vars] : 40 - ArrayNewFixed : 11 - AtomicFence : 1 - Binary : 85 - Block : 139 - Break : 9 - Call : 49 + [total] : 538 + [vars] : 43 + ArrayNewFixed : 1 + AtomicFence : 2 + Binary : 67 + Block : 70 + Break : 1 + Call : 23 CallRef : 1 - Const : 169 - Drop : 17 - GlobalGet : 70 - GlobalSet : 66 - I31Get : 1 - I31New : 3 - If : 41 - Load : 18 - LocalGet : 43 - LocalSet : 26 - Loop : 7 - Nop : 2 - RefAs : 2 - RefFunc : 11 - RefNull : 7 + Const : 116 + Drop : 11 + GlobalGet : 36 + GlobalSet : 34 + I31New : 4 + If : 19 + Load : 16 + LocalGet : 35 + LocalSet : 17 + Loop : 2 + MemoryInit : 1 + Nop : 5 + RefFunc : 17 + RefNull : 5 Return : 4 - SIMDExtract : 3 - Store : 3 - StructNew : 9 - TupleExtract : 4 - TupleMake : 8 - Unary : 36 - Unreachable : 32 + SIMDExtract : 1 + Store : 1 + StructNew : 5 + TupleMake : 9 + Unary : 18 + Unreachable : 17 |