diff options
-rw-r--r-- | src/tools/fuzzing.h | 5 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 12 | ||||
-rw-r--r-- | test/passes/fuzz_metrics_noprint.bin.txt | 58 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_all-features_metrics_noprint.txt | 73 |
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 |