summaryrefslogtreecommitdiff
path: root/test/gtest/possible-contents.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-10-18 14:46:06 -0700
committerGitHub <noreply@github.com>2022-10-18 14:46:06 -0700
commit6a60b9e1d9fbaeeda20ac31b289fda4daa48d209 (patch)
tree6cef1e1282e2d50b334a086c115ea095cf204f74 /test/gtest/possible-contents.cpp
parente4fd739f72eae49aa47bef06af9f38625a3a9f33 (diff)
downloadbinaryen-6a60b9e1d9fbaeeda20ac31b289fda4daa48d209.tar.gz
binaryen-6a60b9e1d9fbaeeda20ac31b289fda4daa48d209.tar.bz2
binaryen-6a60b9e1d9fbaeeda20ac31b289fda4daa48d209.zip
[Wasm GC] Filter GUFA expression locations by their type (#5149)
Now that we have a cone type, we are able to represent in PossibleContents the natural content of a wasm location: a type or any of its subtypes. This allows us to enforce the wasm typing rules, that is, to filter the data arriving at a location by the wasm type of the location. Technically this could be unnecessary if we had full implementations of flowFoo and so forth, that is, tailored code for each wasm expression that makes sure we only contain and flow content that fits in the wasm type. Atm we don't have that, and until the wasm spec stabilizes it's probably not worth the effort. Instead, simply filter based on the type, which gives the same result (though it does take a little more work; I measured it at 3% or so of runtime). While doing so normalize cones to their actual maximum depth, which simplifies things and will help more later as well.
Diffstat (limited to 'test/gtest/possible-contents.cpp')
-rw-r--r--test/gtest/possible-contents.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/test/gtest/possible-contents.cpp b/test/gtest/possible-contents.cpp
index 7b8f0c4a8..802d08c18 100644
--- a/test/gtest/possible-contents.cpp
+++ b/test/gtest/possible-contents.cpp
@@ -854,6 +854,33 @@ TEST_F(PossibleContentsTest, TestOracleManyTypes) {
auto bodyContents =
oracle.getContents(ResultLocation{wasm->getFunction("foo"), 0});
ASSERT_TRUE(bodyContents.isConeType());
- EXPECT_TRUE(bodyContents.getType().getHeapType() == HeapType::data);
- EXPECT_TRUE(bodyContents.getCone().depth == 1);
+ EXPECT_EQ(bodyContents.getType().getHeapType(), HeapType::data);
+ EXPECT_EQ(bodyContents.getCone().depth, Index(1));
+}
+
+TEST_F(PossibleContentsTest, TestOracleNoFullCones) {
+ // PossibleContents should be normalized, so we never have full cones (depth
+ // infinity).
+ auto wasm = parse(R"(
+ (module
+ (type $A (struct_subtype (field i32) data))
+ (type $B (struct_subtype (field i32) $A))
+ (type $C (struct_subtype (field i32) $B))
+ (func $foo (export "foo")
+ ;; Note we must declare $C so that $B and $C have uses and are not
+ ;; removed automatically from consideration.
+ (param $a (ref $A)) (param $c (ref $C))
+ (result (ref any))
+ (local.get $a)
+ )
+ )
+ )");
+ ContentOracle oracle(*wasm);
+ // The function is exported, and all we know about the parameter $a is that it
+ // is some subtype of $A. This is normalized to depth 2 because that is the
+ // actual depth of subtypes.
+ auto bodyContents =
+ oracle.getContents(ResultLocation{wasm->getFunction("foo"), 0});
+ ASSERT_TRUE(bodyContents.isConeType());
+ EXPECT_EQ(bodyContents.getCone().depth, Index(2));
}