@@ -1566,20 +1566,22 @@ void TranslateToFuzzReader::recombine(Function* func) {
15661566 }
15671567
15681568 std::vector<Type> ret;
1569- auto heapType = type.getHeapType ();
1570- auto nullability = type.getNullability ();
1569+ ret.push_back (type);
15711570
1572- if (nullability == NonNullable) {
1573- ret = getRelevantTypes (Type (heapType, Nullable));
1571+ if (type.isNonNullable ()) {
1572+ auto nullable = getRelevantTypes (type.with (Nullable));
1573+ ret.insert (ret.end (), nullable.begin (), nullable.end ());
1574+ }
1575+ if (type.isExact ()) {
1576+ auto inexact = getRelevantTypes (type.with (Inexact));
1577+ ret.insert (ret.end (), inexact.begin (), inexact.end ());
1578+ // Do not consider exact references to supertypes.
1579+ return ret;
15741580 }
15751581
1576- while (1 ) {
1577- ret.push_back (Type (heapType, nullability));
1578- auto super = heapType.getSuperType ();
1579- if (!super) {
1580- break ;
1581- }
1582- heapType = *super;
1582+ for (auto heapType = type.getHeapType ().getSuperType (); heapType;
1583+ heapType = heapType->getSuperType ()) {
1584+ ret.push_back (type.with (*heapType));
15831585 }
15841586
15851587 return ret;
@@ -4902,9 +4904,17 @@ static auto makeArrayBoundsCheck(Expression* ref,
49024904 Function* func,
49034905 Builder& builder,
49044906 Expression* length = nullptr ) {
4905- auto tempRef = builder.addVar (func, ref->type );
4907+ // The reference might be a RefNull, in which case its type is exact. But we
4908+ // want to avoid creating exact-typed locals until we support them more widely
4909+ // in the fuzzer, so adjust the type. TODO: remove this once exact references
4910+ // are better supported.
4911+ Type refType = ref->type ;
4912+ if (refType.isExact ()) {
4913+ refType = refType.with (Inexact);
4914+ }
4915+ auto tempRef = builder.addVar (func, refType);
49064916 auto tempIndex = builder.addVar (func, index->type );
4907- auto * teeRef = builder.makeLocalTee (tempRef, ref, ref-> type );
4917+ auto * teeRef = builder.makeLocalTee (tempRef, ref, refType );
49084918 auto * teeIndex = builder.makeLocalTee (tempIndex, index, index->type );
49094919 auto * getSize = builder.makeArrayLen (teeRef);
49104920
@@ -4931,7 +4941,7 @@ static auto makeArrayBoundsCheck(Expression* ref,
49314941 // An additional use of the length, if it was provided.
49324942 Expression* getLength = nullptr ;
49334943 } result = {builder.makeBinary (LtUInt32, effectiveIndex, getSize),
4934- builder.makeLocalGet (tempRef, ref-> type ),
4944+ builder.makeLocalGet (tempRef, refType ),
49354945 builder.makeLocalGet (tempIndex, index->type ),
49364946 getLength};
49374947 return result;
@@ -5320,13 +5330,37 @@ Nullability TranslateToFuzzReader::getNullability() {
53205330 return Nullable;
53215331}
53225332
5333+ Exactness TranslateToFuzzReader::getExactness () {
5334+ // Without GC, the only heap types are func and extern, neither of which is
5335+ // exactly inhabitable. To avoid introducing uninhabitable types, only
5336+ // generate exact references when GC is enabled. We don't need custom
5337+ // descriptors to be enabled even though that is the feature that introduces
5338+ // exact references because the binary writer can always generalize the exact
5339+ // reference types away.
5340+ //
5341+ // if (wasm.features.hasGC() && oneIn(8)) {
5342+ // return Exact;
5343+ // }
5344+ //
5345+ // However, we cannot yet handle creating exact references in general, so for
5346+ // now we always generate inexact references when given the choice. TODO.
5347+ return Inexact;
5348+ }
5349+
53235350Nullability TranslateToFuzzReader::getSubType (Nullability nullability) {
53245351 if (nullability == NonNullable) {
53255352 return NonNullable;
53265353 }
53275354 return getNullability ();
53285355}
53295356
5357+ Exactness TranslateToFuzzReader::getSubType (Exactness exactness) {
5358+ if (exactness == Exact) {
5359+ return Exact;
5360+ }
5361+ return getExactness ();
5362+ }
5363+
53305364HeapType TranslateToFuzzReader::getSubType (HeapType type) {
53315365 if (oneIn (3 )) {
53325366 return type;
@@ -5418,9 +5452,18 @@ Type TranslateToFuzzReader::getSubType(Type type) {
54185452 if (!funcContext && heapType.isMaybeShared (HeapType::exn)) {
54195453 return type;
54205454 }
5421- heapType = getSubType (heapType);
5455+ if (type.isExact ()) {
5456+ // The only other possible heap type is bottom, but we don't want to
5457+ // generate too many bottom types.
5458+ if (!heapType.isBottom () && oneIn (20 )) {
5459+ heapType = heapType.getBottom ();
5460+ }
5461+ } else {
5462+ heapType = getSubType (heapType);
5463+ }
54225464 auto nullability = getSubType (type.getNullability ());
5423- auto subType = Type (heapType, nullability);
5465+ auto exactness = getSubType (type.getExactness ());
5466+ auto subType = Type (heapType, nullability, exactness);
54245467 // We don't want to emit lots of uninhabitable types like (ref none), so
54255468 // avoid them with high probability. Specifically, if the original type was
54265469 // inhabitable then return that; avoid adding more uninhabitability.
0 commit comments