summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/fuzzing.h5
-rw-r--r--src/tools/fuzzing/fuzzing.cpp12
-rw-r--r--test/passes/fuzz_metrics_noprint.bin.txt58
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt73
4 files changed, 80 insertions, 68 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index bdadaba5a..5529a14a8 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -89,6 +89,11 @@ private:
// of bounds (which traps in wasm, and is undefined behavior in C).
bool allowOOB = true;
+ // Whether we allow the fuzzer to add unreachable code when generating changes
+ // to existing code. This is randomized during startup, but could be an option
+ // like the above options eventually if we find that useful.
+ bool allowAddingUnreachableCode;
+
// Whether to emit atomic waits (which in single-threaded mode, may hang...)
static const bool ATOMIC_WAITS = false;
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index af2a34078..37de3d1da 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -31,6 +31,11 @@ namespace {
TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
std::vector<char>&& input)
: wasm(wasm), builder(wasm), random(std::move(input), wasm.features) {
+
+ // Half the time add no unreachable code so that we'll execute the most code
+ // as possible with no early exits.
+ allowAddingUnreachableCode = oneIn(2);
+
// - funcref cannot be logged because referenced functions can be inlined or
// removed during optimization
// - there's no point in logging anyref because it is opaque
@@ -724,9 +729,10 @@ void TranslateToFuzzReader::mutate(Function* func) {
Modder(Module& wasm, TranslateToFuzzReader& parent)
: wasm(wasm), parent(parent) {
- // Half the time, never replace with an unreachable. The other half, do it
- // sometimes (but even so, only rarely, see below).
- allowUnreachable = parent.oneIn(2);
+ // If the parent allows it then sometimes replace with an unreachable, and
+ // sometimes not. Even if we allow it, only do it in certain functions
+ // (half the time) and only do it rarely (see below).
+ allowUnreachable = parent.allowAddingUnreachableCode && parent.oneIn(2);
}
void visitExpression(Expression* curr) {
diff --git a/test/passes/fuzz_metrics_noprint.bin.txt b/test/passes/fuzz_metrics_noprint.bin.txt
index b7d64cee2..d086298d2 100644
--- a/test/passes/fuzz_metrics_noprint.bin.txt
+++ b/test/passes/fuzz_metrics_noprint.bin.txt
@@ -1,34 +1,34 @@
total
- [exports] : 41
- [funcs] : 52
- [globals] : 7
+ [exports] : 35
+ [funcs] : 45
+ [globals] : 9
[imports] : 4
[memories] : 1
- [memory-data] : 4
- [table-data] : 21
+ [memory-data] : 2
+ [table-data] : 7
[tables] : 1
[tags] : 0
- [total] : 8251
- [vars] : 153
- Binary : 661
- Block : 1232
- Break : 320
- Call : 303
- CallIndirect : 86
- Const : 1458
- Drop : 57
- GlobalGet : 646
- GlobalSet : 295
- If : 479
- Load : 157
- LocalGet : 617
- LocalSet : 473
- Loop : 208
- Nop : 137
- RefFunc : 21
- Return : 338
- Select : 58
- Store : 91
- Switch : 1
- Unary : 611
- Unreachable : 2
+ [total] : 8644
+ [vars] : 134
+ Binary : 644
+ Block : 1266
+ Break : 398
+ Call : 271
+ CallIndirect : 42
+ Const : 1434
+ Drop : 79
+ GlobalGet : 671
+ GlobalSet : 290
+ If : 527
+ Load : 139
+ LocalGet : 762
+ LocalSet : 520
+ Loop : 210
+ Nop : 201
+ RefFunc : 7
+ Return : 341
+ Select : 62
+ Store : 94
+ Switch : 4
+ Unary : 673
+ Unreachable : 9
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 3f725452b..c7df2c682 100644
--- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
+++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
@@ -1,45 +1,46 @@
total
- [exports] : 15
- [funcs] : 18
- [globals] : 6
+ [exports] : 12
+ [funcs] : 17
+ [globals] : 11
[imports] : 5
[memories] : 1
- [memory-data] : 22
- [table-data] : 6
+ [memory-data] : 20
+ [table-data] : 3
[tables] : 1
- [tags] : 0
- [total] : 541
- [vars] : 31
- ArrayInit : 7
- AtomicFence : 1
- AtomicNotify : 1
- Binary : 68
- Block : 64
- Break : 3
- Call : 14
- CallIndirect : 1
- CallRef : 1
- Const : 119
- DataDrop : 1
- Drop : 9
- GlobalGet : 49
- GlobalSet : 23
+ [tags] : 1
+ [total] : 747
+ [vars] : 51
+ ArrayInit : 6
+ AtomicFence : 3
+ AtomicNotify : 2
+ Binary : 91
+ Block : 91
+ Break : 9
+ Call : 34
+ CallRef : 2
+ Const : 161
+ Drop : 10
+ GlobalGet : 59
+ GlobalSet : 28
I31Get : 1
- I31New : 4
- If : 24
- Load : 16
- LocalGet : 26
+ If : 37
+ Load : 21
+ LocalGet : 37
LocalSet : 18
- Loop : 5
+ Loop : 10
MemoryCopy : 1
- Nop : 6
+ Nop : 16
+ RefAs : 3
+ RefEq : 1
RefFunc : 7
- RefIsNull : 3
- RefNull : 3
- Return : 26
+ RefIsNull : 2
+ RefNull : 6
+ Return : 31
+ SIMDExtract : 2
SIMDTernary : 1
- Select : 2
- Store : 2
- TupleExtract : 1
- TupleMake : 5
- Unary : 29
+ Select : 1
+ Store : 3
+ StructNew : 2
+ TupleExtract : 2
+ TupleMake : 6
+ Unary : 43