Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions src/tools/execution-results.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ struct LoggingExternalInterface : public ShellExternalInterface {
// we can only get results when there are no imports. we then call each method
// that has a result, with some values
struct ExecutionResults {
std::map<Name, Literals> results;
struct FunctionResult {
Literals values;
bool exception; // Whether an exception is uncaught and the function crashes
};
std::map<Name, FunctionResult> results;
Loggings loggings;

// If set, we should ignore this and not compare it to anything.
Expand All @@ -106,26 +110,20 @@ struct ExecutionResults {
}
std::cout << "[fuzz-exec] calling " << exp->name << "\n";
auto* func = wasm.getFunction(exp->value);
if (func->getResults() != Type::none) {
// this has a result
Literals ret = run(func, wasm, instance);
results[exp->name] = ret;
// ignore the result if we hit an unreachable and returned no value
if (ret.size() > 0) {
std::cout << "[fuzz-exec] note result: " << exp->name << " => ";
auto resultType = func->getResults();
if (resultType.isRef()) {
// Don't print reference values, as funcref(N) contains an index
// for example, which is not guaranteed to remain identical after
// optimizations.
std::cout << resultType << '\n';
} else {
std::cout << ret << '\n';
}
FunctionResult ret = run(func, wasm, instance);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is mostly indentation changes due to the removal of if

results[exp->name] = ret;
// ignore the result if we hit an unreachable and returned no value
if (ret.values.size() > 0) {
std::cout << "[fuzz-exec] note result: " << exp->name << " => ";
auto resultType = func->getResults();
if (resultType.isRef()) {
// Don't print reference values, as funcref(N) contains an index
// for example, which is not guaranteed to remain identical after
// optimizations.
std::cout << resultType << '\n';
} else {
std::cout << ret.values << '\n';
}
} else {
// no result, run it anyhow (it might modify memory etc.)
run(func, wasm, instance);
}
}
} catch (const TrapException&) {
Expand Down Expand Up @@ -191,7 +189,10 @@ struct ExecutionResults {
return false;
}
std::cout << "[fuzz-exec] comparing " << name << '\n';
if (!areEqual(results[name], other.results[name])) {
if (!areEqual(results[name].values, other.results[name].values)) {
return false;
}
if (results[name].exception != other.results[name].exception) {
return false;
}
}
Expand All @@ -209,7 +210,7 @@ struct ExecutionResults {

bool operator!=(ExecutionResults& other) { return !((*this) == other); }

Literals run(Function* func, Module& wasm) {
FunctionResult run(Function* func, Module& wasm) {
LoggingExternalInterface interface(loggings);
try {
ModuleInstance instance(wasm, &interface);
Expand All @@ -220,7 +221,7 @@ struct ExecutionResults {
}
}

Literals run(Function* func, Module& wasm, ModuleInstance& instance) {
FunctionResult run(Function* func, Module& wasm, ModuleInstance& instance) {
try {
LiteralList arguments;
// init hang support, if present
Expand All @@ -236,9 +237,12 @@ struct ExecutionResults {
}
arguments.push_back(Literal::makeZero(param));
}
return instance.callFunction(func->name, arguments);
return {instance.callFunction(func->name, arguments), false};
} catch (const TrapException&) {
return {};
} catch (const WasmException& e) {
std::cout << "[exception thrown: " << e << "]" << std::endl;
return {{}, true};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate from this PR, I like this idea of tracking an exception, and I think maybe we should track traps too. That is, we could have an enum "normal, exception, trap", and then line 242 would mark "trap" like this line would mark "exception".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind if I change to that in a followup?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, followup sounds better.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #4405.

} catch (const HostLimitException&) {
// This should be ignored and not compared with, as optimizations can
// change whether a host limit is reached.
Expand Down
64 changes: 64 additions & 0 deletions test/lit/exec/eh.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.

;; RUN: wasm-opt %s -all --fuzz-exec -q -o /dev/null 2>&1 | filecheck %s

(module
(tag $e-i32 (param i32))

;; CHECK: [fuzz-exec] calling throw
;; CHECK-NEXT: [exception thrown: e-i32 1]
(func "throw"
(throw $e-i32 (i32.const 1))
)

;; CHECK: [fuzz-exec] calling try-catch
(func "try-catch"
(try
(do
(throw $e-i32 (i32.const 2))
)
(catch $e-i32
(drop (pop i32))
)
)
)

;; CHECK: [fuzz-exec] calling catchless-try
;; CHECK-NEXT: [exception thrown: e-i32 3]
(func "catchless-try"
(try
(do
(throw $e-i32 (i32.const 3))
)
)
)

;; CHECK: [fuzz-exec] calling try-delegate
;; CHECK-NEXT: [exception thrown: e-i32 4]
(func "try-delegate"
(try $l0
(do
(try
(do
(throw $e-i32 (i32.const 4))
)
(delegate $l0)
)
)
)
)
)
;; CHECK: [fuzz-exec] calling throw
;; CHECK-NEXT: [exception thrown: e-i32 1]

;; CHECK: [fuzz-exec] calling try-catch

;; CHECK: [fuzz-exec] calling catchless-try
;; CHECK-NEXT: [exception thrown: e-i32 3]

;; CHECK: [fuzz-exec] calling try-delegate
;; CHECK-NEXT: [exception thrown: e-i32 4]
;; CHECK-NEXT: [fuzz-exec] comparing catchless-try
;; CHECK-NEXT: [fuzz-exec] comparing throw
;; CHECK-NEXT: [fuzz-exec] comparing try-catch
;; CHECK-NEXT: [fuzz-exec] comparing try-delegate
4 changes: 4 additions & 0 deletions test/passes/fuzz-exec_all-features.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,11 @@
[fuzz-exec] calling oob_notify
[trap final > memory: 18446744073709551512 > 65514]
[fuzz-exec] comparing aligned_for_size
[fuzz-exec] comparing oob_notify
[fuzz-exec] comparing unaligned_load
[fuzz-exec] comparing unaligned_load_offset
[fuzz-exec] comparing unaligned_notify
[fuzz-exec] comparing wrap_cmpxchg
[fuzz-exec] calling unsigned_2_bytes
[fuzz-exec] note result: unsigned_2_bytes => 65535
(module
Expand Down Expand Up @@ -183,6 +185,7 @@
)
[fuzz-exec] calling rmw-reads-modifies-and-writes
[LoggingExternalInterface logging 0]
[fuzz-exec] comparing rmw-reads-modifies-and-writes
[fuzz-exec] calling rmw-reads-modifies-and-writes-asymmetrical
[LoggingExternalInterface logging 214]
(module
Expand All @@ -207,6 +210,7 @@
)
[fuzz-exec] calling rmw-reads-modifies-and-writes-asymmetrical
[LoggingExternalInterface logging 214]
[fuzz-exec] comparing rmw-reads-modifies-and-writes-asymmetrical
[fuzz-exec] calling func
[fuzz-exec] note result: func => funcref
(module
Expand Down
6 changes: 6 additions & 0 deletions test/passes/optimize-instructions_fuzz-exec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@
[LoggingExternalInterface logging nan:0x400000]
[LoggingExternalInterface logging nan:0x400000]
[LoggingExternalInterface logging nan:0x400000]
[fuzz-exec] comparing ignore
[fuzz-exec] comparing just-one-nan
[fuzz-exec] comparing test32
[fuzz-exec] comparing test64
[fuzz-exec] calling foo
[LoggingExternalInterface logging 1]
[LoggingExternalInterface logging 1]
Expand Down Expand Up @@ -381,3 +385,5 @@
[fuzz-exec] note result: call-compare-maybe-signed-ne => 1
[fuzz-exec] comparing call-compare-maybe-signed-eq
[fuzz-exec] comparing call-compare-maybe-signed-ne
[fuzz-exec] comparing do-shift
[fuzz-exec] comparing foo