Skip to content

Commit e4ad86c

Browse files
authored
Create API for feature dependent picking in fuzzer (WebAssembly#1821)
1 parent 75b6934 commit e4ad86c

2 files changed

Lines changed: 69 additions & 48 deletions

File tree

src/tools/fuzzing.h

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,59 +1314,59 @@ class TranslateToFuzzReader {
13141314
case i32: {
13151315
switch (upTo(4)) {
13161316
case 0: {
1317-
if (features.hasAtomics()) {
1318-
return makeUnary({ pick(EqZInt32, ClzInt32, CtzInt32, PopcntInt32, ExtendS8Int32, ExtendS16Int32), make(i32) });
1319-
} else {
1320-
return makeUnary({ pick(EqZInt32, ClzInt32, CtzInt32, PopcntInt32), make(i32) });
1321-
}
1322-
break;
1317+
auto op = pick(
1318+
FeatureOptions<UnaryOp>()
1319+
.add(FeatureSet::MVP, EqZInt32, ClzInt32, CtzInt32, PopcntInt32)
1320+
.add(FeatureSet::Atomics, ExtendS8Int32, ExtendS16Int32)
1321+
);
1322+
return makeUnary({ op, make(i32) });
13231323
}
13241324
case 1: return makeUnary({ pick(EqZInt64, WrapInt64), make(i64) });
13251325
case 2: {
1326-
if (features.hasTruncSat()) {
1327-
return makeUnary({ pick(TruncSFloat32ToInt32, TruncUFloat32ToInt32, ReinterpretFloat32, TruncSatSFloat32ToInt32, TruncSatUFloat32ToInt32), make(f32) });
1328-
} else {
1329-
return makeUnary({ pick(TruncSFloat32ToInt32, TruncUFloat32ToInt32, ReinterpretFloat32), make(f32) });
1330-
}
1331-
break;
1326+
auto op = pick(
1327+
FeatureOptions<UnaryOp>()
1328+
.add(FeatureSet::MVP, TruncSFloat32ToInt32, TruncUFloat32ToInt32, ReinterpretFloat32)
1329+
.add(FeatureSet::TruncSat, TruncSatSFloat32ToInt32, TruncSatUFloat32ToInt32)
1330+
);
1331+
return makeUnary({ op, make(f32) });
13321332
}
13331333
case 3: {
1334-
if (features.hasTruncSat()) {
1335-
return makeUnary({ pick(TruncSFloat64ToInt32, TruncUFloat64ToInt32, TruncSatSFloat64ToInt32, TruncSatUFloat64ToInt32), make(f64) });
1336-
} else {
1337-
return makeUnary({ pick(TruncSFloat64ToInt32, TruncUFloat64ToInt32), make(f64) });
1338-
}
1339-
break;
1334+
auto op = pick(
1335+
FeatureOptions<UnaryOp>()
1336+
.add(FeatureSet::MVP, TruncSFloat64ToInt32, TruncUFloat64ToInt32)
1337+
.add(FeatureSet::TruncSat, TruncSatSFloat64ToInt32, TruncSatUFloat64ToInt32)
1338+
);
1339+
return makeUnary({ op, make(f64) });
13401340
}
13411341
}
13421342
WASM_UNREACHABLE();
13431343
}
13441344
case i64: {
13451345
switch (upTo(4)) {
13461346
case 0: {
1347-
if (features.hasAtomics()) {
1348-
return makeUnary({ pick(ClzInt64, CtzInt64, PopcntInt64, ExtendS8Int64, ExtendS16Int64, ExtendS32Int64), make(i64) });
1349-
} else {
1350-
return makeUnary({ pick(ClzInt64, CtzInt64, PopcntInt64), make(i64) });
1351-
}
1352-
break;
1347+
auto op = pick(
1348+
FeatureOptions<UnaryOp>()
1349+
.add(FeatureSet::MVP, ClzInt64, CtzInt64, PopcntInt64)
1350+
.add(FeatureSet::Atomics, ExtendS8Int64, ExtendS16Int64, ExtendS32Int64)
1351+
);
1352+
return makeUnary({ op, make(i64) });
13531353
}
13541354
case 1: return makeUnary({ pick(ExtendSInt32, ExtendUInt32), make(i32) });
13551355
case 2: {
1356-
if (features.hasTruncSat()) {
1357-
return makeUnary({ pick(TruncSFloat32ToInt64, TruncUFloat32ToInt64, TruncSatSFloat32ToInt64, TruncSatUFloat32ToInt64), make(f32) });
1358-
} else {
1359-
return makeUnary({ pick(TruncSFloat32ToInt64, TruncUFloat32ToInt64), make(f32) });
1360-
}
1361-
break;
1356+
auto op = pick(
1357+
FeatureOptions<UnaryOp>()
1358+
.add(FeatureSet::MVP, TruncSFloat32ToInt64, TruncUFloat32ToInt64)
1359+
.add(FeatureSet::TruncSat, TruncSatSFloat32ToInt64, TruncSatUFloat32ToInt64)
1360+
);
1361+
return makeUnary({ op, make(f32) });
13621362
}
13631363
case 3: {
1364-
if (features.hasTruncSat()) {
1365-
return makeUnary({ pick(TruncSFloat64ToInt64, TruncUFloat64ToInt64, ReinterpretFloat64, TruncSatSFloat64ToInt64, TruncSatUFloat64ToInt64), make(f64) });
1366-
} else {
1367-
return makeUnary({ pick(TruncSFloat64ToInt64, TruncUFloat64ToInt64, ReinterpretFloat64), make(f64) });
1368-
}
1369-
break;
1364+
auto op = pick(
1365+
FeatureOptions<UnaryOp>()
1366+
.add(FeatureSet::MVP, TruncSFloat64ToInt64, TruncUFloat64ToInt64, ReinterpretFloat64)
1367+
.add(FeatureSet::TruncSat, TruncSatSFloat64ToInt64, TruncSatUFloat64ToInt64)
1368+
);
1369+
return makeUnary({ op, make(f64) });
13701370
}
13711371
}
13721372
WASM_UNREACHABLE();
@@ -1670,6 +1670,33 @@ class TranslateToFuzzReader {
16701670
#pragma GCC diagnostic pop
16711671
#endif
16721672

1673+
template<typename T>
1674+
struct FeatureOptions {
1675+
template<typename ...Ts>
1676+
FeatureOptions<T>& add(FeatureSet::Feature feature, T option, Ts... rest) {
1677+
options[feature].push_back(option);
1678+
return add(feature, rest...);
1679+
}
1680+
1681+
FeatureOptions<T>& add(FeatureSet::Feature feature) {
1682+
return *this;
1683+
}
1684+
1685+
std::map<FeatureSet::Feature, std::vector<T>> options;
1686+
};
1687+
1688+
template<typename T>
1689+
const T pick(FeatureOptions<T>& picker) {
1690+
std::vector<T> matches;
1691+
for (const auto& item : picker.options) {
1692+
if (features.has(item.first)) {
1693+
matches.reserve(matches.size() + item.second.size());
1694+
matches.insert(matches.end(), item.second.begin(), item.second.end());
1695+
}
1696+
}
1697+
return vectorPick(matches);
1698+
}
1699+
16731700
// utilities
16741701

16751702
Name getTargetName(Expression* target) {

src/wasm.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,18 @@ struct FeatureSet {
5050
FeatureSet(uint32_t features) : features(features) {}
5151

5252
bool isMVP() const { return features == MVP; }
53+
bool has(Feature f) { return (features & f) == f; }
5354
bool hasAtomics() const { return features & Atomics; }
5455
bool hasMutableGlobals() const { return features & MutableGlobals; }
5556
bool hasTruncSat() const { return features & TruncSat; }
5657
bool hasAll() const { return features & (Atomics | MutableGlobals | TruncSat); }
5758

5859
void makeMVP() { features = MVP; }
59-
void setAtomics(bool v = true) {
60-
features = v ? (features | Atomics) : (features & ~Atomics);
61-
}
62-
void setMutableGlobals(bool v = true) {
63-
features = v ? (features | MutableGlobals) : (features & ~MutableGlobals);
64-
}
65-
void setTruncSat(bool v = true) {
66-
features = v ? (features | TruncSat) : (features & ~TruncSat);
67-
}
68-
void setAll(bool v = true) {
69-
features = v ? All : MVP;
70-
}
60+
void set(Feature f, bool v = true) { features = v ? (features | f) : (features & ~f); }
61+
void setAtomics(bool v = true) { set(Atomics, v); }
62+
void setMutableGlobals(bool v = true) { set(MutableGlobals, v); }
63+
void setTruncSat(bool v = true) { set(TruncSat, v); }
64+
void setAll(bool v = true) { features = v ? All : MVP; }
7165

7266
private:
7367
uint32_t features;

0 commit comments

Comments
 (0)