diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 56dc3d0af76..f3b45c049d6 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -319,8 +319,13 @@ struct LoggingExternalInterface : public ShellExternalInterface { Literals arguments; for (const auto& param : sig.params) { // An i64 param can work from JS, but fuzz_shell provides 0, which errors - // on attempts to convert it to BigInt. v128 and exnref are disalloewd. - if (param == Type::i64 || param == Type::v128 || param.isExn()) { + // on attempts to convert it to BigInt. v128 is disallowed. + if (param == Type::i64 || param == Type::v128) { + throwJSException(); + } + // Exnref and nullexnref are also disallowed. + if (param.isRef() && + HeapType(param.getHeapType().getTop()).isMaybeShared(HeapType::exn)) { throwJSException(); } if (!param.isDefaultable()) { @@ -332,9 +337,11 @@ struct LoggingExternalInterface : public ShellExternalInterface { // Error on illegal results. Note that this happens, as per JS semantics, // *before* the call. for (const auto& result : sig.results) { - // An i64 result is fine: a BigInt will be provided. But v128 and exnref - // still error. - if (result == Type::v128 || result.isExn()) { + // An i64 result is fine: a BigInt will be provided. But v128 and + // [null]exnref still error. + if (result == Type::v128 || + (result.isRef() && HeapType(result.getHeapType().getTop()) + .isMaybeShared(HeapType::exn))) { throwJSException(); } } diff --git a/test/lit/exec/fuzzing-api.wast b/test/lit/exec/fuzzing-api.wast index 00db75a19be..e91231229eb 100644 --- a/test/lit/exec/fuzzing-api.wast +++ b/test/lit/exec/fuzzing-api.wast @@ -357,7 +357,7 @@ ) ) - (func $illegal-result (result v128) + (func $illegal-v128-result (result v128) ;; Helper for the function below. The result is illegal for JS. (call $log-i32 (i32.const 910) @@ -365,15 +365,58 @@ (v128.const i32x4 1 2 3 4) ) - ;; CHECK: [fuzz-exec] calling ref.calling.illegal-result + ;; CHECK: [fuzz-exec] calling ref.calling.illegal-v128-result ;; CHECK-NEXT: [LoggingExternalInterface logging 1] - (func $ref.calling.illegal-result (export "ref.calling.illegal-result") + (func $ref.calling.illegal-v128-result (export "ref.calling.illegal-v128-result") ;; The v128 result causes an error here, so we will log 1 as an exception. The JS ;; semantics determine that we do that check *before* the call, so the logging ;; of 910 does not go through. (call $log-i32 (call $call.ref.catch - (ref.func $illegal-result) + (ref.func $illegal-v128-result) + ) + ) + ) + + (func $illegal-exnref-result (result exnref) + ;; Helper for the function below. The result is illegal for JS. + (call $log-i32 + (i32.const 911) + ) + (block $l (result exnref) + (try_table (catch_all_ref $l) + (call $throwing) + ) + (unreachable) + ) + ) + + ;; CHECK: [fuzz-exec] calling ref.calling.illegal-exnref-result + ;; CHECK-NEXT: [LoggingExternalInterface logging 1] + (func $ref.calling.illegal-exnref-result (export "ref.calling.illegal-exnref-result") + ;; As above with the v128, the exnref cannot be converted to a JS value. + (call $log-i32 + (call $call.ref.catch + (ref.func $illegal-exnref-result) + ) + ) + ) + + (func $illegal-nullexnref-result (result nullexnref) + ;; Helper for the function below. The result is illegal for JS. + (call $log-i32 + (i32.const 912) + ) + (ref.null noexn) + ) + + ;; CHECK: [fuzz-exec] calling ref.calling.illegal-nullexnref-result + ;; CHECK-NEXT: [LoggingExternalInterface logging 1] + (func $ref.calling.illegal-nullexnref-result (export "ref.calling.illegal-nullexnref-result") + ;; As above, the nullexnref cannot be converted to a JS value. + (call $log-i32 + (call $call.ref.catch + (ref.func $illegal-nullexnref-result) ) ) ) @@ -564,7 +607,13 @@ ;; CHECK: [fuzz-exec] calling ref.calling.illegal-exnref ;; CHECK-NEXT: [LoggingExternalInterface logging 1] -;; CHECK: [fuzz-exec] calling ref.calling.illegal-result +;; CHECK: [fuzz-exec] calling ref.calling.illegal-v128-result +;; CHECK-NEXT: [LoggingExternalInterface logging 1] + +;; CHECK: [fuzz-exec] calling ref.calling.illegal-exnref-result +;; CHECK-NEXT: [LoggingExternalInterface logging 1] + +;; CHECK: [fuzz-exec] calling ref.calling.illegal-nullexnref-result ;; CHECK-NEXT: [LoggingExternalInterface logging 1] ;; CHECK: [fuzz-exec] calling ref.calling.legal-result @@ -592,8 +641,10 @@ ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.catching ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-exnref -;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-result +;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-exnref-result +;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-nullexnref-result ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-v128 +;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-v128-result ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.legal ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.legal-result ;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.rethrow