summaryrefslogtreecommitdiff
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
parent2b326379e7deac4b37e0db5f064d06f7daf46aac (diff)
downloadbinaryen-da143ddde34854d6ac5de38cf93d60a427e30dc6.tar.gz
binaryen-da143ddde34854d6ac5de38cf93d60a427e30dc6.tar.bz2
binaryen-da143ddde34854d6ac5de38cf93d60a427e30dc6.zip
[Wasm GC] Fuzz ref.test (#5577)
-rw-r--r--src/tools/fuzzing.h1
-rw-r--r--src/tools/fuzzing/fuzzing.cpp37
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt63
3 files changed, 68 insertions, 33 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());
diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
index 491b273a3..46655753b 100644
--- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
+++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
@@ -1,44 +1,41 @@
total
- [exports] : 12
- [funcs] : 22
+ [exports] : 9
+ [funcs] : 18
[globals] : 5
[imports] : 5
[memories] : 1
[memory-data] : 20
- [table-data] : 9
+ [table-data] : 4
[tables] : 1
[tags] : 0
- [total] : 781
- [vars] : 35
- ArrayNew : 4
- ArrayNewFixed : 1
- AtomicNotify : 1
- Binary : 90
- Block : 118
- Break : 8
- Call : 25
- CallIndirect : 1
+ [total] : 579
+ [vars] : 19
+ ArrayNew : 5
+ ArrayNewFixed : 8
+ Binary : 71
+ Block : 74
+ Break : 2
+ Call : 18
CallRef : 2
- Const : 171
- Drop : 8
- GlobalGet : 56
- GlobalSet : 56
- I31New : 3
- If : 36
- Load : 21
- LocalGet : 36
- LocalSet : 17
- Loop : 8
- Nop : 11
- RefAs : 1
+ Const : 121
+ DataDrop : 1
+ Drop : 5
+ GlobalGet : 34
+ GlobalSet : 34
+ I31Get : 2
+ I31New : 4
+ If : 21
+ Load : 19
+ LocalGet : 46
+ LocalSet : 22
+ Loop : 2
+ Nop : 9
+ RefEq : 1
RefFunc : 16
RefNull : 4
Return : 6
- SIMDExtract : 2
- Select : 1
- Store : 6
- StructNew : 4
- Switch : 1
- TupleMake : 3
- Unary : 33
- Unreachable : 31
+ Store : 1
+ StructNew : 5
+ TupleMake : 5
+ Unary : 20
+ Unreachable : 21