Skip to content

Commit c528c7e

Browse files
authored
[NFC] Clean up pick<HeapType>() calls in fuzzer (v2) (#7475)
* Add some assertions on features being properly enabled. * Simplify code to avoid FeatureOptions when unnecessary (feature known to be enabled). * Add comments on the definition of upTo/oneIn of zero. * Add a FeatureOptions overload to handle an option without a feature.
1 parent deb404c commit c528c7e

File tree

3 files changed

+39
-20
lines changed

3 files changed

+39
-20
lines changed

src/tools/fuzzing/fuzzing.cpp

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,13 +3426,9 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) {
34263426
// Choose a subtype we can materialize a constant for. We cannot
34273427
// materialize non-nullable refs to func or i31 in global contexts.
34283428
Nullability nullability = getSubType(type.getNullability());
3429-
auto subtypeOpts = FeatureOptions<HeapType>().add(
3430-
FeatureSet::ReferenceTypes | FeatureSet::GC,
3431-
HeapType::i31,
3432-
HeapType::struct_,
3433-
HeapType::array);
3434-
auto subtype = pick(subtypeOpts).getBasic(share);
3435-
return makeConst(Type(subtype, nullability));
3429+
assert(wasm.features.hasGC());
3430+
auto subtype = pick(HeapTypes::i31, HeapTypes::struct_, HeapTypes::array);
3431+
return makeConst(Type(subtype.getBasic(share), nullability));
34363432
}
34373433
case HeapType::eq: {
34383434
if (!wasm.features.hasGC()) {
@@ -5406,16 +5402,18 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) {
54065402
switch (type.getBasic(Unshared)) {
54075403
case HeapType::func:
54085404
// TODO: Typed function references.
5405+
assert(wasm.features.hasReferenceTypes());
54095406
return pick(FeatureOptions<HeapType>()
5410-
.add(FeatureSet::ReferenceTypes, HeapType::func)
5411-
.add(FeatureSet::GC, HeapType::nofunc))
5407+
.add(HeapTypes::func)
5408+
.add(FeatureSet::GC, HeapTypes::nofunc))
54125409
.getBasic(share);
54135410
case HeapType::cont:
54145411
return pick(HeapTypes::cont, HeapTypes::nocont).getBasic(share);
54155412
case HeapType::ext: {
5413+
assert(wasm.features.hasReferenceTypes());
54165414
auto options = FeatureOptions<HeapType>()
5417-
.add(FeatureSet::ReferenceTypes, HeapType::ext)
5418-
.add(FeatureSet::GC, HeapType::noext);
5415+
.add(HeapTypes::ext)
5416+
.add(FeatureSet::GC, HeapTypes::noext);
54195417
if (share == Unshared) {
54205418
// Shared strings not yet supported.
54215419
options.add(FeatureSet::Strings, HeapType::string);
@@ -5425,14 +5423,13 @@ HeapType TranslateToFuzzReader::getSubType(HeapType type) {
54255423
case HeapType::any: {
54265424
assert(wasm.features.hasReferenceTypes());
54275425
assert(wasm.features.hasGC());
5428-
auto options = FeatureOptions<HeapType>().add(FeatureSet::GC,
5429-
HeapType::any,
5430-
HeapType::eq,
5431-
HeapType::i31,
5432-
HeapType::struct_,
5433-
HeapType::array,
5434-
HeapType::none);
5435-
return pick(options).getBasic(share);
5426+
return pick(HeapTypes::any,
5427+
HeapTypes::eq,
5428+
HeapTypes::i31,
5429+
HeapTypes::struct_,
5430+
HeapTypes::array,
5431+
HeapTypes::none)
5432+
.getBasic(share);
54365433
}
54375434
case HeapType::eq:
54385435
assert(wasm.features.hasReferenceTypes());

src/tools/fuzzing/heap-types.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ struct HeapTypeGeneratorImpl {
424424
return HeapTypes::none.getBasic(share);
425425
}
426426
}
427+
// If we had no candidates then the oneIn() above us should have returned
428+
// true, since oneIn(0) => true.
429+
assert(!candidates.empty());
427430
return rand.pick(candidates);
428431
} else {
429432
// This is not a constructed type, so it must be a basic type.

src/tools/fuzzing/random.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <vector>
2323

2424
#include "wasm-features.h"
25+
#include "wasm-type.h"
2526

2627
namespace wasm {
2728

@@ -53,8 +54,9 @@ class Random {
5354
double getDouble();
5455

5556
// Choose an integer value in [0, x). This doesn't use a perfectly uniform
56-
// distribution, but it's fast and reasonable.
57+
// distribution, but it's fast and reasonable. upTo(0) is defined as 0.
5758
uint32_t upTo(uint32_t x);
59+
// Returns true with probability 1 in x. oneIn(0) is defined as true.
5860
bool oneIn(uint32_t x) { return upTo(x) == 0; }
5961

6062
// Apply upTo twice, generating a skewed distribution towards
@@ -114,6 +116,23 @@ class Random {
114116
#endif
115117

116118
template<typename T> struct FeatureOptions {
119+
FeatureOptions<T>& add(HeapType::BasicHeapType option) {
120+
// Using FeatureOptions with BasicHeapTypes is risky as BasicHeapType
121+
// is an enum, which can convert into FeatureSet implicitly (which would
122+
// then be ambiguous with add(FeatureSet) below). Use HeapType instead.
123+
//
124+
// Use a weird static assert on something other than |false| because of
125+
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2593r1.html
126+
// (older compilers may error without this workaround).
127+
static_assert(sizeof(T) == 0);
128+
}
129+
130+
// An option without a feature is applied in all cases.
131+
FeatureOptions<T>& add(T option) {
132+
options[FeatureSet::MVP].push_back(option);
133+
return *this;
134+
}
135+
117136
template<typename... Ts>
118137
FeatureOptions<T>& add(FeatureSet feature, T option, Ts... rest) {
119138
options[feature].push_back(option);

0 commit comments

Comments
 (0)