diff options
author | Alon Zakai <azakai@google.com> | 2021-01-12 22:50:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-12 14:50:54 -0800 |
commit | dc7184afcbdcc72d0a6d66e2b36fc5857050dd87 (patch) | |
tree | 1ccadec38943894c28b720920057313001f31326 | |
parent | 46f0229bfd3c145873eca4d7db5e14f657ad729b (diff) | |
download | binaryen-dc7184afcbdcc72d0a6d66e2b36fc5857050dd87.tar.gz binaryen-dc7184afcbdcc72d0a6d66e2b36fc5857050dd87.tar.bz2 binaryen-dc7184afcbdcc72d0a6d66e2b36fc5857050dd87.zip |
[GC] Fix casts of non-GC data (#3483)
The code previously assumed it could always call getGCData, but
that assumes the input is an array or a struct. It could also be an
anyref etc. that contains something other than GC data.
-rw-r--r-- | src/wasm-interpreter.h | 12 | ||||
-rw-r--r-- | test/passes/Oz_fuzz-exec_all-features.txt | 10 | ||||
-rw-r--r-- | test/passes/Oz_fuzz-exec_all-features.wast | 11 |
3 files changed, 31 insertions, 2 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 392b0c2bc..243542836 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1433,11 +1433,19 @@ public: return cast; } cast.originalRef = ref.getSingleValue(); - auto gcData = cast.originalRef.getGCData(); - if (!gcData) { + if (cast.originalRef.isNull()) { cast.outcome = cast.Null; return cast; } + // The input may not be a struct or an array; for example it could be an + // anyref of null (already handled above) or anything else (handled here, + // but this is for future use as atm the binaryen interpreter cannot + // represent external references). + if (!cast.originalRef.isGCData()) { + cast.outcome = cast.Failure; + return cast; + } + auto gcData = cast.originalRef.getGCData(); auto refRtt = gcData->rtt; auto intendedRtt = rtt.getSingleValue(); if (!refRtt.isSubRtt(intendedRtt)) { diff --git a/test/passes/Oz_fuzz-exec_all-features.txt b/test/passes/Oz_fuzz-exec_all-features.txt index 8fa184345..b43681cdf 100644 --- a/test/passes/Oz_fuzz-exec_all-features.txt +++ b/test/passes/Oz_fuzz-exec_all-features.txt @@ -21,6 +21,8 @@ [fuzz-exec] calling br_on_cast [LoggingExternalInterface logging 3] [trap unreachable] +[fuzz-exec] calling cast-null-anyref-to-gc +[LoggingExternalInterface logging 0] (module (type ${mut:i32} (struct (field (mut i32)))) (type $none_=>_none (func)) @@ -32,6 +34,7 @@ (export "arrays" (func $1)) (export "rtts" (func $2)) (export "br_on_cast" (func $3)) + (export "cast-null-anyref-to-gc" (func $4)) (func $0 (; has Stack IR ;) (local $0 (ref null ${mut:i32})) (call $log @@ -194,6 +197,11 @@ ) (unreachable) ) + (func $4 (; has Stack IR ;) + (call $log + (i32.const 0) + ) + ) ) [fuzz-exec] calling structs [LoggingExternalInterface logging 0] @@ -218,3 +226,5 @@ [fuzz-exec] calling br_on_cast [LoggingExternalInterface logging 3] [trap unreachable] +[fuzz-exec] calling cast-null-anyref-to-gc +[LoggingExternalInterface logging 0] diff --git a/test/passes/Oz_fuzz-exec_all-features.wast b/test/passes/Oz_fuzz-exec_all-features.wast index 78313267c..7d586cffc 100644 --- a/test/passes/Oz_fuzz-exec_all-features.wast +++ b/test/passes/Oz_fuzz-exec_all-features.wast @@ -179,4 +179,15 @@ ) ) ) + (func "cast-null-anyref-to-gc" + ;; a null anyref is a literal which is not even of GC data, as it's not an + ;; array or a struct, so our casting code should not assume it is. it is ok + ;; to try to cast it, and the result should be 0. + (call $log + (ref.test $struct + (ref.null any) + (rtt.canon $struct) + ) + ) + ) ) |