Skip to content

Commit d175e45

Browse files
authored
Allow the fuzzer to use tests with exact types (#7598)
Remove the list of tests containing exact types from the list of tests the fuzzer is disallowed from using as initial contents. Also allow fuzzing V8 with exact types. Fix various parts of the fuzzer to ensure we emit valid binaries when initial contents have exact references.
1 parent 2bba2eb commit d175e45

File tree

5 files changed

+28
-46
lines changed

5 files changed

+28
-46
lines changed

scripts/fuzz_opt.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,10 @@ def randomize_feature_opts():
151151

152152
# The shared-everything feature is new and we want to fuzz it, but it
153153
# also currently disables fuzzing V8, so disable it most of the time.
154-
# Same with custom descriptors and strings - all these cannot be run in
155-
# V8 for now. Relaxed SIMD's nondeterminism disables much but not all of
156-
# our V8 fuzzing, so avoid it too.
154+
# Same with strings. Relaxed SIMD's nondeterminism disables much but not
155+
# all of our V8 fuzzing, so avoid it too.
157156
if random.random() < 0.9:
158157
FEATURE_OPTS.append('--disable-shared-everything')
159-
FEATURE_OPTS.append('--disable-custom-descriptors')
160158
FEATURE_OPTS.append('--disable-strings')
161159
FEATURE_OPTS.append('--disable-relaxed-simd')
162160

@@ -826,9 +824,8 @@ def run(self, wasm, extra_d8_flags=[]):
826824
def can_run(self, wasm):
827825
# V8 does not support shared memories when running with
828826
# shared-everything enabled, so do not fuzz shared-everything
829-
# for now. It also does not yet support custom descriptors, nor
830-
# strings.
831-
return all_disallowed(['shared-everything', 'custom-descriptors', 'strings'])
827+
# for now. It also does not yet support strings.
828+
return all_disallowed(['shared-everything', 'strings'])
832829

833830
def can_compare_to_self(self):
834831
# With nans, VM differences can confuse us, so only very simple VMs
@@ -1595,7 +1592,7 @@ def can_run_on_wasm(self, wasm):
15951592
return False
15961593

15971594
# see D8.can_run
1598-
return all_disallowed(['shared-everything', 'custom-descriptors', 'strings'])
1595+
return all_disallowed(['shared-everything', 'strings'])
15991596

16001597

16011598
# Check that the text format round-trips without error.
@@ -1798,7 +1795,7 @@ def can_run_on_wasm(self, wasm):
17981795
return False
17991796
if NANS:
18001797
return False
1801-
return all_disallowed(['shared-everything', 'custom-descriptors', 'strings'])
1798+
return all_disallowed(['shared-everything', 'strings'])
18021799

18031800

18041801
# Test --fuzz-preserve-imports-exports, which never modifies imports or exports.

scripts/test/fuzzing.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -110,33 +110,13 @@
110110
'dce-stack-switching.wast',
111111
'precompute-stack-switching.wast',
112112
'vacuum-stack-switching.wast',
113-
# TODO: fuzzer support for exact references
114-
'exact-references.wast',
115-
'exact-references-lowering.wast',
116-
'exact-casts.wast',
117-
'exact-casts-trivial.wast',
118-
'abstract-type-refining-exact.wast',
119-
'optimize-instructions-exact.wast',
120-
'optimize-instructions-all-casts.wast',
121-
'optimize-instructions-all-casts-exact.wast',
122-
'local-subtyping-exact.wast',
123-
'remove-unused-types-exact.wast',
124-
'coalesce-locals-exact.wast',
125-
'remove-unused-brs-exact.wast',
126-
'signature-refining-exact.wast',
127-
'gufa-cast-all-exact.wast',
128-
'type-merging-exact.wast',
129-
'type-refining-exact.wast',
130-
'type-refining-gufa-exact.wast',
131-
'type-ssa-exact.wast',
132-
'minimize-rec-groups-exact.wast',
133-
'minimize-rec-groups-ignore-exact.wast',
134-
'public-exact.wast',
135113
# TODO: fuzzer support for custom descriptors
136114
'custom-descriptors.wast',
137115
# TODO: fix split_wast() on tricky escaping situations like a string ending
138116
# in \\" (the " is not escaped - there is an escaped \ before it)
139117
'string-lifting-section.wast',
118+
# TODO: fuzzer support for uninhabitable imported globals
119+
'exact-references.wast',
140120
]
141121

142122

scripts/test/shared.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ def has_shell_timeout():
257257
'--experimental-wasm-compilation-hints',
258258
'--experimental-wasm-stringref',
259259
'--experimental-wasm-fp16',
260+
'--experimental-wasm-custom-descriptors',
260261
]
261262

262263
# external tools

src/tools/fuzzing/fuzzing.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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).

src/tools/fuzzing/heap-types.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,13 +900,14 @@ std::vector<HeapType> Inhabitator::build() {
900900
}
901901
auto heapType = type.getHeapType();
902902
auto nullability = type.getNullability();
903+
auto exactness = type.getExactness();
903904
if (auto it = typeIndices.find(heapType); it != typeIndices.end()) {
904905
heapType = builder[it->second];
905906
}
906907
if (nullables.count(pos)) {
907908
nullability = Nullable;
908909
}
909-
type = builder.getTempRefType(heapType, nullability);
910+
type = builder.getTempRefType(heapType, nullability, exactness);
910911
};
911912

912913
for (size_t i = 0; i < types.size(); ++i) {

0 commit comments

Comments
 (0)