diff options
author | Alon Zakai <azakai@google.com> | 2020-11-17 15:55:40 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-17 15:55:40 -0800 |
commit | 5d1642bd600b591145ae96d1916f85888c0f4dbf (patch) | |
tree | e2dddd79c8435a0faf9a197409cc58baa041676b /src | |
parent | 165fef7f4751baa561a125f5d7f5e5d5b7698ed1 (diff) | |
download | binaryen-5d1642bd600b591145ae96d1916f85888c0f4dbf.tar.gz binaryen-5d1642bd600b591145ae96d1916f85888c0f4dbf.tar.bz2 binaryen-5d1642bd600b591145ae96d1916f85888c0f4dbf.zip |
[Fuzzer] Don't compare references, just their types (#3384)
There are several issues here that we can't fully handle, see #3378, but basically
we are comparing results between two separate wasm modules (and
a separate instance of each) - we can't really identify an identical
reference between such things. We can only compare things structurally,
for which we compare the types.
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/execution-results.h | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 1539806d1..d99826210 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -94,14 +94,6 @@ struct ExecutionResults { if (func->sig.results != Type::none) { // this has a result Literals ret = run(func, wasm, instance); - // We cannot compare funcrefs by name because function names can - // change (after duplicate function elimination or roundtripping) - // while the function contents are still the same - for (Literal& val : ret) { - if (val.type == Type::funcref && !val.isNull()) { - val = Literal::makeFunc(Name("funcref")); - } - } results[exp->name] = ret; // ignore the result if we hit an unreachable and returned no value if (ret.size() > 0) { @@ -123,11 +115,46 @@ struct ExecutionResults { ExecutionResults optimizedResults; optimizedResults.get(wasm); if (optimizedResults != *this) { - std::cout << "[fuzz-exec] optimization passes changed execution results"; + std::cout << "[fuzz-exec] optimization passes changed results\n"; exit(1); } } + bool areEqual(Literal a, Literal b) { + if (a.type != b.type) { + std::cout << "types not identical! " << a << " != " << b << '\n'; + return false; + } + if (a.type.isRef()) { + // Don't compare references - only their types. There are several issues + // here that we can't fully handle, see + // https://github.com/WebAssembly/binaryen/issues/3378, but the core issue + // is that we are comparing results between two separate wasm modules (and + // a separate instance of each) - we can't really identify an identical + // reference between such things. We can only compare things structurally, + // for which we compare the types. + return true; + } + if (a != b) { + std::cout << "values not identical! " << a << " != " << b << '\n'; + return false; + } + return true; + } + + bool areEqual(Literals a, Literals b) { + if (a.size() != b.size()) { + std::cout << "literal counts not identical! " << a << " != " << b << '\n'; + return false; + } + for (Index i = 0; i < a.size(); i++) { + if (!areEqual(a[i], b[i])) { + return false; + } + } + return true; + } + bool operator==(ExecutionResults& other) { for (auto& iter : other.results) { auto name = iter.first; @@ -136,16 +163,19 @@ struct ExecutionResults { return false; } std::cout << "[fuzz-exec] comparing " << name << '\n'; - if (results[name] != other.results[name]) { - std::cout << "not identical! " << results[name] - << " != " << other.results[name] << "\n"; + if (!areEqual(results[name], other.results[name])) { return false; } } - if (loggings != other.loggings) { - std::cout << "logging not identical!\n"; + if (loggings.size() != other.loggings.size()) { + std::cout << "logging counts not identical!\n"; return false; } + for (Index i = 0; i < loggings.size(); i++) { + if (!areEqual(loggings[i], other.loggings[i])) { + return false; + } + } return true; } |