diff options
Diffstat (limited to 'src/tools/fuzzing.h')
-rw-r--r-- | src/tools/fuzzing.h | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 978d4e443..d9acadbd1 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -128,7 +128,8 @@ public: setupGlobals(); // keep adding functions until we run out of input while (!finishedInput) { - addFunction(); + auto* func = addFunction(); + addInvocations(func); } if (HANG_LIMIT > 0) { addHangLimitSupport(); @@ -161,12 +162,12 @@ private: // the memory that we use, a small portion so that we have a good chance of // looking at writes (we also look outside of this region with small probability) // this should be a power of 2 - static const int USABLE_MEMORY = 32; + static const int USABLE_MEMORY = 16; // the number of runtime iterations (function calls, loop backbranches) we // allow before we stop execution with a trap, to prevent hangs. 0 means // no hang protection. - static const int HANG_LIMIT = 100; + static const int HANG_LIMIT = 10; // Optionally remove NaNs, which are a source of nondeterminism (which makes // cross-VM comparisons harder) @@ -343,7 +344,7 @@ private: std::map<WasmType, std::vector<Index>> typeLocals; // type => list of locals with that type - void addFunction() { + Function* addFunction() { Index num = wasm.functions.size(); func = new Function; func->name = std::string("func_") + std::to_string(num); @@ -400,6 +401,37 @@ private: } // cleanup typeLocals.clear(); + return func; + } + + // the fuzzer external interface sends in zeros (simpler to compare + // across invocations from JS or wasm-opt etc.). Add invocations in + // the wasm, so they run everywhere + void addInvocations(Function* func) { + std::vector<Expression*> invocations; + while (oneIn(2)) { + std::vector<Expression*> args; + for (auto type : func->params) { + args.push_back(makeConst(type)); + } + Expression* invoke = builder.makeCall(func->name, args, func->result); + if (isConcreteWasmType(func->result)) { + invoke = builder.makeDrop(invoke); + } + invocations.push_back(invoke); + } + if (invocations.empty()) return; + auto* invoker = new Function; + invoker->name = func->name.str + std::string("_invoker"); + invoker->result = none; + invoker->body = builder.makeBlock(invocations); + wasm.addFunction(invoker); + invoker->type = ensureFunctionType(getSig(invoker), &wasm)->name; + auto* export_ = new Export; + export_->name = invoker->name; + export_->value = invoker->name; + export_->kind = ExternalKind::Function; + wasm.addExport(export_); } Name makeLabel() { |