@@ -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