summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-03-08 12:11:50 -0800
committerGitHub <noreply@github.com>2023-03-08 12:11:50 -0800
commite03aa8931bc36fdf1f249e78d77cc14b4929c559 (patch)
tree0c589c538815ef7517729066c094f0688c71e292 /src
parent88b45a5a711678e789785f47701f9ae66131261f (diff)
downloadbinaryen-e03aa8931bc36fdf1f249e78d77cc14b4929c559.tar.gz
binaryen-e03aa8931bc36fdf1f249e78d77cc14b4929c559.tar.bz2
binaryen-e03aa8931bc36fdf1f249e78d77cc14b4929c559.zip
Fuzzer: Pick from existing heap types in the module (#5539)
Diffstat (limited to 'src')
-rw-r--r--src/tools/fuzzing.h4
-rw-r--r--src/tools/fuzzing/fuzzing.cpp47
2 files changed, 46 insertions, 5 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;
}