summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-03-16 10:01:21 -0700
committerGitHub <noreply@github.com>2023-03-16 17:01:21 +0000
commitda143ddde34854d6ac5de38cf93d60a427e30dc6 (patch)
tree482f88c704db810089d085b0587e4bb3025b4fc6 /src
parent2b326379e7deac4b37e0db5f064d06f7daf46aac (diff)
downloadbinaryen-da143ddde34854d6ac5de38cf93d60a427e30dc6.tar.gz
binaryen-da143ddde34854d6ac5de38cf93d60a427e30dc6.tar.bz2
binaryen-da143ddde34854d6ac5de38cf93d60a427e30dc6.zip
[Wasm GC] Fuzz ref.test (#5577)
Diffstat (limited to 'src')
-rw-r--r--src/tools/fuzzing.h1
-rw-r--r--src/tools/fuzzing/fuzzing.cpp37
2 files changed, 38 insertions, 0 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index b8be67499..c67d6c902 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -317,6 +317,7 @@ private:
// TODO: support other RefIs variants, and rename this
Expression* makeRefIsNull(Type type);
Expression* makeRefEq(Type type);
+ Expression* makeRefTest(Type type);
Expression* makeI31New(Type type);
Expression* makeI31Get(Type type);
Expression* makeMemoryInit();
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 9beedc7fd..73aff5acb 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -1077,6 +1077,7 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
options.add(FeatureSet::ReferenceTypes, &Self::makeRefIsNull);
options.add(FeatureSet::ReferenceTypes | FeatureSet::GC,
&Self::makeRefEq,
+ &Self::makeRefTest,
&Self::makeI31Get);
}
if (type.isTuple()) {
@@ -3094,6 +3095,42 @@ Expression* TranslateToFuzzReader::makeRefEq(Type type) {
return builder.makeRefEq(left, right);
}
+Expression* TranslateToFuzzReader::makeRefTest(Type type) {
+ assert(type == Type::i32);
+ assert(wasm.features.hasReferenceTypes() && wasm.features.hasGC());
+ // The case of the reference and the cast type having a connection is useful,
+ // so give a decent chance for one to be a subtype of the other.
+ Type refType, castType;
+ switch (upTo(3)) {
+ case 0:
+ // Totally random.
+ refType = getReferenceType();
+ castType = getReferenceType();
+ // They must share a bottom type in order to validate.
+ if (refType.getHeapType().getBottom() ==
+ castType.getHeapType().getBottom()) {
+ break;
+ }
+ // Otherwise, fall through and generate things in a way that is
+ // guaranteed to validate.
+ [[fallthrough]];
+ case 1:
+ // Cast is a subtype of ref.
+ refType = getReferenceType();
+ castType = getSubType(refType);
+ break;
+ case 2:
+ // Ref is a subtype of cast.
+ castType = getReferenceType();
+ refType = getSubType(castType);
+ break;
+ default:
+ // This unreachable avoids a warning on refType being possibly undefined.
+ WASM_UNREACHABLE("bad case");
+ }
+ return builder.makeRefTest(make(refType), castType);
+}
+
Expression* TranslateToFuzzReader::makeI31New(Type type) {
assert(type.isRef() && type.getHeapType() == HeapType::i31);
assert(wasm.features.hasReferenceTypes() && wasm.features.hasGC());