diff options
author | Alon Zakai <azakai@google.com> | 2023-03-16 10:01:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-16 17:01:21 +0000 |
commit | da143ddde34854d6ac5de38cf93d60a427e30dc6 (patch) | |
tree | 482f88c704db810089d085b0587e4bb3025b4fc6 /src | |
parent | 2b326379e7deac4b37e0db5f064d06f7daf46aac (diff) | |
download | binaryen-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.h | 1 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 37 |
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()); |