@@ -2177,8 +2177,11 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
2177
2177
options.add (FeatureSet::ReferenceTypes | FeatureSet::GC,
2178
2178
&Self::makeCompoundRef);
2179
2179
}
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
+ }
2182
2185
}
2183
2186
if (wasm.features .hasGC ()) {
2184
2187
if (typeStructFields.find (type) != typeStructFields.end ()) {
@@ -4907,22 +4910,25 @@ Expression* TranslateToFuzzReader::makeBrOn(Type type) {
4907
4910
case BrOnNonNull: {
4908
4911
// The sent type is the non-nullable version of the reference, so any ref
4909
4912
// of that type is ok, nullable or not.
4910
- refType = Type ( targetType.getHeapType (), getNullability ());
4913
+ refType = targetType.with ( getNullability ());
4911
4914
break ;
4912
4915
}
4913
4916
case BrOnCast: {
4914
4917
// The sent type is the heap type we cast to, with the input type's
4915
4918
// nullability, so the combination of the two must be a subtype of
4916
4919
// targetType.
4917
4920
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);
4921
4931
}
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);
4926
4932
if (targetType.isNonNullable ()) {
4927
4933
// And it must have the right nullability for the target, as mentioned
4928
4934
// above: if the target type is non-nullable then either the ref or the
@@ -4945,10 +4951,7 @@ Expression* TranslateToFuzzReader::makeBrOn(Type type) {
4945
4951
refType = getSubType (targetType);
4946
4952
// See above on BrOnCast, but flipped.
4947
4953
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 );
4952
4955
// There is no nullability to adjust: if targetType is non-nullable then
4953
4956
// both refType and castType are as well, as subtypes of it. But we can
4954
4957
// also allow castType to be nullable (it is not sent to the target).
0 commit comments