summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/execution-results.h52
-rw-r--r--test/lit/exec/eh.wast64
-rw-r--r--test/passes/fuzz-exec_all-features.txt4
-rw-r--r--test/passes/optimize-instructions_fuzz-exec.txt6
4 files changed, 102 insertions, 24 deletions
diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h
index b689ffc66..18f4a399c 100644
--- a/src/tools/execution-results.h
+++ b/src/tools/execution-results.h
@@ -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.
@@ -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);
+ 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&) {
@@ -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;
}
}
@@ -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);
@@ -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
@@ -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};
} catch (const HostLimitException&) {
// This should be ignored and not compared with, as optimizations can
// change whether a host limit is reached.
diff --git a/test/lit/exec/eh.wast b/test/lit/exec/eh.wast
new file mode 100644
index 000000000..779309eb6
--- /dev/null
+++ b/test/lit/exec/eh.wast
@@ -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
diff --git a/test/passes/fuzz-exec_all-features.txt b/test/passes/fuzz-exec_all-features.txt
index 0225876a1..4b3e64e7c 100644
--- a/test/passes/fuzz-exec_all-features.txt
+++ b/test/passes/fuzz-exec_all-features.txt
@@ -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
@@ -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
@@ -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
diff --git a/test/passes/optimize-instructions_fuzz-exec.txt b/test/passes/optimize-instructions_fuzz-exec.txt
index 2ebd01f1c..ea32b8916 100644
--- a/test/passes/optimize-instructions_fuzz-exec.txt
+++ b/test/passes/optimize-instructions_fuzz-exec.txt
@@ -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]
@@ -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