summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/fuzzing.h4
-rw-r--r--src/tools/fuzzing/fuzzing.cpp47
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt64
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