Skip to content

Commit 0108e9b

Browse files
authored
add invocation functions for fuzz functions, so they are tested with many input values (#1303)
1 parent 09ac6aa commit 0108e9b

File tree

2 files changed

+385
-780
lines changed

2 files changed

+385
-780
lines changed

src/tools/fuzzing.h

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ class TranslateToFuzzReader {
128128
setupGlobals();
129129
// keep adding functions until we run out of input
130130
while (!finishedInput) {
131-
addFunction();
131+
auto* func = addFunction();
132+
addInvocations(func);
132133
}
133134
if (HANG_LIMIT > 0) {
134135
addHangLimitSupport();
@@ -161,12 +162,12 @@ class TranslateToFuzzReader {
161162
// the memory that we use, a small portion so that we have a good chance of
162163
// looking at writes (we also look outside of this region with small probability)
163164
// this should be a power of 2
164-
static const int USABLE_MEMORY = 32;
165+
static const int USABLE_MEMORY = 16;
165166

166167
// the number of runtime iterations (function calls, loop backbranches) we
167168
// allow before we stop execution with a trap, to prevent hangs. 0 means
168169
// no hang protection.
169-
static const int HANG_LIMIT = 100;
170+
static const int HANG_LIMIT = 10;
170171

171172
// Optionally remove NaNs, which are a source of nondeterminism (which makes
172173
// cross-VM comparisons harder)
@@ -343,7 +344,7 @@ class TranslateToFuzzReader {
343344

344345
std::map<WasmType, std::vector<Index>> typeLocals; // type => list of locals with that type
345346

346-
void addFunction() {
347+
Function* addFunction() {
347348
Index num = wasm.functions.size();
348349
func = new Function;
349350
func->name = std::string("func_") + std::to_string(num);
@@ -400,6 +401,37 @@ class TranslateToFuzzReader {
400401
}
401402
// cleanup
402403
typeLocals.clear();
404+
return func;
405+
}
406+
407+
// the fuzzer external interface sends in zeros (simpler to compare
408+
// across invocations from JS or wasm-opt etc.). Add invocations in
409+
// the wasm, so they run everywhere
410+
void addInvocations(Function* func) {
411+
std::vector<Expression*> invocations;
412+
while (oneIn(2)) {
413+
std::vector<Expression*> args;
414+
for (auto type : func->params) {
415+
args.push_back(makeConst(type));
416+
}
417+
Expression* invoke = builder.makeCall(func->name, args, func->result);
418+
if (isConcreteWasmType(func->result)) {
419+
invoke = builder.makeDrop(invoke);
420+
}
421+
invocations.push_back(invoke);
422+
}
423+
if (invocations.empty()) return;
424+
auto* invoker = new Function;
425+
invoker->name = func->name.str + std::string("_invoker");
426+
invoker->result = none;
427+
invoker->body = builder.makeBlock(invocations);
428+
wasm.addFunction(invoker);
429+
invoker->type = ensureFunctionType(getSig(invoker), &wasm)->name;
430+
auto* export_ = new Export;
431+
export_->name = invoker->name;
432+
export_->value = invoker->name;
433+
export_->kind = ExternalKind::Function;
434+
wasm.addExport(export_);
403435
}
404436

405437
Name makeLabel() {

0 commit comments

Comments
 (0)