summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-11-17 15:55:40 -0800
committerGitHub <noreply@github.com>2020-11-17 15:55:40 -0800
commit5d1642bd600b591145ae96d1916f85888c0f4dbf (patch)
treee2dddd79c8435a0faf9a197409cc58baa041676b /src
parent165fef7f4751baa561a125f5d7f5e5d5b7698ed1 (diff)
downloadbinaryen-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.h58
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;
}