summaryrefslogtreecommitdiff
path: root/src/tools/fuzzing/fuzzing.cpp
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-11-04 11:05:01 -0700
committerGitHub <noreply@github.com>2021-11-04 11:05:01 -0700
commitf1947db456df4576ac857a535f16cba3ffbfdc37 (patch)
treee8b9cb213dc3cfc1babce105abb7802958efd370 /src/tools/fuzzing/fuzzing.cpp
parentab66e9ab1210a87d1db8ebe93cf8463eafe34e33 (diff)
downloadbinaryen-f1947db456df4576ac857a535f16cba3ffbfdc37.tar.gz
binaryen-f1947db456df4576ac857a535f16cba3ffbfdc37.tar.bz2
binaryen-f1947db456df4576ac857a535f16cba3ffbfdc37.zip
[NFC] Factor fuzzer randomness into a separate utility (#4304)
In preparation for using it from a separate file specifically for generating random HeapTypes that has no need to depend on all of fuzzing.h.
Diffstat (limited to 'src/tools/fuzzing/fuzzing.cpp')
-rw-r--r--src/tools/fuzzing/fuzzing.cpp68
1 files changed, 9 insertions, 59 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 6ee8b4cd0..3182936cd 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -43,15 +43,8 @@ constexpr size_t Important = 2;
} // anonymous namespace
TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
- std::vector<char> input)
- : wasm(wasm), builder(wasm) {
- bytes.swap(input);
- pos = 0;
- finishedInput = false;
- // ensure *some* input to be read
- if (bytes.size() == 0) {
- bytes.push_back(0);
- }
+ std::vector<char>&& input)
+ : wasm(wasm), builder(wasm), random(std::move(input)) {
// - funcref cannot be logged because referenced functions can be inlined or
// removed during optimization
// - there's no point in logging externref or anyref because these are opaque
@@ -67,51 +60,8 @@ TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
: TranslateToFuzzReader(
wasm, read_file<std::vector<char>>(filename, Flags::Binary)) {}
-int8_t TranslateToFuzzReader::get() {
- if (pos == bytes.size()) {
- // we ran out of input, go to the start for more stuff
- finishedInput = true;
- pos = 0;
- xorFactor++;
- }
- return bytes[pos++] ^ xorFactor;
-}
-
-int16_t TranslateToFuzzReader::get16() {
- auto temp = uint16_t(get()) << 8;
- return temp | uint16_t(get());
-}
-
-int32_t TranslateToFuzzReader::get32() {
- auto temp = uint32_t(get16()) << 16;
- return temp | uint32_t(get16());
-}
-
-int64_t TranslateToFuzzReader::get64() {
- auto temp = uint64_t(get32()) << 32;
- return temp | uint64_t(get32());
-}
-
-Index TranslateToFuzzReader::upTo(Index x) {
- if (x == 0) {
- return 0;
- }
- Index raw;
- if (x <= 255) {
- raw = get();
- } else if (x <= 65535) {
- raw = get16();
- } else {
- raw = get32();
- }
- auto ret = raw % x;
- // use extra bits as "noise" for later
- xorFactor += raw / x;
- return ret;
-}
-
void TranslateToFuzzReader::pickPasses(OptimizationOptions& options) {
- while (options.passes.size() < 20 && !finishedInput && !oneIn(3)) {
+ while (options.passes.size() < 20 && !random.finished() && !oneIn(3)) {
switch (upTo(32)) {
case 0:
case 1:
@@ -235,7 +185,7 @@ void TranslateToFuzzReader::build() {
modifyInitialFunctions();
addImportLoggingSupport();
// keep adding functions until we run out of input
- while (!finishedInput) {
+ while (!random.finished()) {
auto* func = addFunction();
addInvocations(func);
}
@@ -604,7 +554,7 @@ Function* TranslateToFuzzReader::addFunction() {
wasm.addExport(export_);
}
// add some to an elem segment
- while (oneIn(3) && !finishedInput) {
+ while (oneIn(3) && !random.finished()) {
auto type = Type(func->type, NonNullable);
std::vector<ElementSegment*> compatibleSegments;
ModuleUtils::iterActiveElementSegments(wasm, [&](ElementSegment* segment) {
@@ -874,7 +824,7 @@ void TranslateToFuzzReader::addInvocations(Function* func) {
return;
}
std::vector<Expression*> invocations;
- while (oneIn(2) && !finishedInput) {
+ while (oneIn(2) && !random.finished()) {
std::vector<Expression*> args;
for (const auto& type : func->getParams()) {
args.push_back(makeConst(type));
@@ -906,7 +856,7 @@ void TranslateToFuzzReader::addInvocations(Function* func) {
Expression* TranslateToFuzzReader::make(Type type) {
// When we should stop, emit something small (but not necessarily trivial).
- if (finishedInput || nesting >= 5 * NESTING_LIMIT || // hard limit
+ if (random.finished() || nesting >= 5 * NESTING_LIMIT || // hard limit
(nesting >= NESTING_LIMIT && !oneIn(3))) {
if (type.isConcrete()) {
if (oneIn(2)) {
@@ -1086,13 +1036,13 @@ Expression* TranslateToFuzzReader::makeBlock(Type type) {
if (num == 0 && !oneIn(10)) {
num++;
}
- while (num > 0 && !finishedInput) {
+ while (num > 0 && !random.finished()) {
ret->list.push_back(make(Type::none));
num--;
}
// give a chance to make the final element an unreachable break, instead
// of concrete - a common pattern (branch to the top of a loop etc.)
- if (!finishedInput && type.isConcrete() && oneIn(2)) {
+ if (!random.finished() && type.isConcrete() && oneIn(2)) {
ret->list.push_back(makeBreak(Type::unreachable));
} else {
ret->list.push_back(make(type));