@@ -2177,8 +2177,11 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
21772177 options.add (FeatureSet::ReferenceTypes | FeatureSet::GC,
21782178 &Self::makeCompoundRef);
21792179 }
2180- options.add (FeatureSet::ReferenceTypes | FeatureSet::GC,
2181- &Self::makeRefCast);
2180+ // Exact casts are only allowed with custom descriptors enabled.
2181+ if (type.isInexact () || wasm.features .hasCustomDescriptors ()) {
2182+ options.add (FeatureSet::ReferenceTypes | FeatureSet::GC,
2183+ &Self::makeRefCast);
2184+ }
21822185 }
21832186 if (wasm.features .hasGC ()) {
21842187 if (typeStructFields.find (type) != typeStructFields.end ()) {
@@ -4907,22 +4910,25 @@ Expression* TranslateToFuzzReader::makeBrOn(Type type) {
49074910 case BrOnNonNull: {
49084911 // The sent type is the non-nullable version of the reference, so any ref
49094912 // of that type is ok, nullable or not.
4910- refType = Type ( targetType.getHeapType (), getNullability ());
4913+ refType = targetType.with ( getNullability ());
49114914 break ;
49124915 }
49134916 case BrOnCast: {
49144917 // The sent type is the heap type we cast to, with the input type's
49154918 // nullability, so the combination of the two must be a subtype of
49164919 // targetType.
49174920 castType = getSubType (targetType);
4918- if (!wasm.features .hasCustomDescriptors ()) {
4919- // Exact cast targets disallowed without custom descriptors.
4920- castType = castType.with (Inexact);
4921+ if (castType.isExact () && !wasm.features .hasCustomDescriptors ()) {
4922+ // This exact cast is only valid if its input has the same type (or the
4923+ // only possible strict subtype, bottom).
4924+ refType = castType;
4925+ } else {
4926+ // The ref's type must be castable to castType, or we'd not validate.
4927+ // But it can also be a subtype, which will trivially also succeed (so
4928+ // do that more rarely). Pick subtypes rarely, as they make the cast
4929+ // trivial.
4930+ refType = oneIn (5 ) ? getSubType (castType) : getSuperType (castType);
49214931 }
4922- // The ref's type must be castable to castType, or we'd not validate. But
4923- // it can also be a subtype, which will trivially also succeed (so do that
4924- // more rarely). Pick subtypes rarely, as they make the cast trivial.
4925- refType = oneIn (5 ) ? getSubType (castType) : getSuperType (castType);
49264932 if (targetType.isNonNullable ()) {
49274933 // And it must have the right nullability for the target, as mentioned
49284934 // above: if the target type is non-nullable then either the ref or the
@@ -4945,10 +4951,7 @@ Expression* TranslateToFuzzReader::makeBrOn(Type type) {
49454951 refType = getSubType (targetType);
49464952 // See above on BrOnCast, but flipped.
49474953 castType = oneIn (5 ) ? getSuperType (refType) : getSubType (refType);
4948- if (!wasm.features .hasCustomDescriptors ()) {
4949- // Exact cast targets disallowed without custom descriptors.
4950- castType = castType.with (Inexact);
4951- }
4954+ castType = castType.withInexactIfNoCustomDescs (wasm.features );
49524955 // There is no nullability to adjust: if targetType is non-nullable then
49534956 // both refType and castType are as well, as subtypes of it. But we can
49544957 // also allow castType to be nullable (it is not sent to the target).
0 commit comments