diff options
-rw-r--r-- | src/tools/fuzzing.h | 1 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 37 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_all-features_metrics_noprint.txt | 63 |
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 |