summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/fuzzing.h99
-rw-r--r--src/wasm.h18
2 files changed, 69 insertions, 48 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 243616c8a..dcb47529f 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -1314,29 +1314,29 @@ private:
case i32: {
switch (upTo(4)) {
case 0: {
- if (features.hasAtomics()) {
- return makeUnary({ pick(EqZInt32, ClzInt32, CtzInt32, PopcntInt32, ExtendS8Int32, ExtendS16Int32), make(i32) });
- } else {
- return makeUnary({ pick(EqZInt32, ClzInt32, CtzInt32, PopcntInt32), make(i32) });
- }
- break;
+ auto op = pick(
+ FeatureOptions<UnaryOp>()
+ .add(FeatureSet::MVP, EqZInt32, ClzInt32, CtzInt32, PopcntInt32)
+ .add(FeatureSet::Atomics, ExtendS8Int32, ExtendS16Int32)
+ );
+ return makeUnary({ op, make(i32) });
}
case 1: return makeUnary({ pick(EqZInt64, WrapInt64), make(i64) });
case 2: {
- if (features.hasTruncSat()) {
- return makeUnary({ pick(TruncSFloat32ToInt32, TruncUFloat32ToInt32, ReinterpretFloat32, TruncSatSFloat32ToInt32, TruncSatUFloat32ToInt32), make(f32) });
- } else {
- return makeUnary({ pick(TruncSFloat32ToInt32, TruncUFloat32ToInt32, ReinterpretFloat32), make(f32) });
- }
- break;
+ auto op = pick(
+ FeatureOptions<UnaryOp>()
+ .add(FeatureSet::MVP, TruncSFloat32ToInt32, TruncUFloat32ToInt32, ReinterpretFloat32)
+ .add(FeatureSet::TruncSat, TruncSatSFloat32ToInt32, TruncSatUFloat32ToInt32)
+ );
+ return makeUnary({ op, make(f32) });
}
case 3: {
- if (features.hasTruncSat()) {
- return makeUnary({ pick(TruncSFloat64ToInt32, TruncUFloat64ToInt32, TruncSatSFloat64ToInt32, TruncSatUFloat64ToInt32), make(f64) });
- } else {
- return makeUnary({ pick(TruncSFloat64ToInt32, TruncUFloat64ToInt32), make(f64) });
- }
- break;
+ auto op = pick(
+ FeatureOptions<UnaryOp>()
+ .add(FeatureSet::MVP, TruncSFloat64ToInt32, TruncUFloat64ToInt32)
+ .add(FeatureSet::TruncSat, TruncSatSFloat64ToInt32, TruncSatUFloat64ToInt32)
+ );
+ return makeUnary({ op, make(f64) });
}
}
WASM_UNREACHABLE();
@@ -1344,29 +1344,29 @@ private:
case i64: {
switch (upTo(4)) {
case 0: {
- if (features.hasAtomics()) {
- return makeUnary({ pick(ClzInt64, CtzInt64, PopcntInt64, ExtendS8Int64, ExtendS16Int64, ExtendS32Int64), make(i64) });
- } else {
- return makeUnary({ pick(ClzInt64, CtzInt64, PopcntInt64), make(i64) });
- }
- break;
+ auto op = pick(
+ FeatureOptions<UnaryOp>()
+ .add(FeatureSet::MVP, ClzInt64, CtzInt64, PopcntInt64)
+ .add(FeatureSet::Atomics, ExtendS8Int64, ExtendS16Int64, ExtendS32Int64)
+ );
+ return makeUnary({ op, make(i64) });
}
case 1: return makeUnary({ pick(ExtendSInt32, ExtendUInt32), make(i32) });
case 2: {
- if (features.hasTruncSat()) {
- return makeUnary({ pick(TruncSFloat32ToInt64, TruncUFloat32ToInt64, TruncSatSFloat32ToInt64, TruncSatUFloat32ToInt64), make(f32) });
- } else {
- return makeUnary({ pick(TruncSFloat32ToInt64, TruncUFloat32ToInt64), make(f32) });
- }
- break;
+ auto op = pick(
+ FeatureOptions<UnaryOp>()
+ .add(FeatureSet::MVP, TruncSFloat32ToInt64, TruncUFloat32ToInt64)
+ .add(FeatureSet::TruncSat, TruncSatSFloat32ToInt64, TruncSatUFloat32ToInt64)
+ );
+ return makeUnary({ op, make(f32) });
}
case 3: {
- if (features.hasTruncSat()) {
- return makeUnary({ pick(TruncSFloat64ToInt64, TruncUFloat64ToInt64, ReinterpretFloat64, TruncSatSFloat64ToInt64, TruncSatUFloat64ToInt64), make(f64) });
- } else {
- return makeUnary({ pick(TruncSFloat64ToInt64, TruncUFloat64ToInt64, ReinterpretFloat64), make(f64) });
- }
- break;
+ auto op = pick(
+ FeatureOptions<UnaryOp>()
+ .add(FeatureSet::MVP, TruncSFloat64ToInt64, TruncUFloat64ToInt64, ReinterpretFloat64)
+ .add(FeatureSet::TruncSat, TruncSatSFloat64ToInt64, TruncSatUFloat64ToInt64)
+ );
+ return makeUnary({ op, make(f64) });
}
}
WASM_UNREACHABLE();
@@ -1670,6 +1670,33 @@ private:
#pragma GCC diagnostic pop
#endif
+ template<typename T>
+ struct FeatureOptions {
+ template<typename ...Ts>
+ FeatureOptions<T>& add(FeatureSet::Feature feature, T option, Ts... rest) {
+ options[feature].push_back(option);
+ return add(feature, rest...);
+ }
+
+ FeatureOptions<T>& add(FeatureSet::Feature feature) {
+ return *this;
+ }
+
+ std::map<FeatureSet::Feature, std::vector<T>> options;
+ };
+
+ template<typename T>
+ const T pick(FeatureOptions<T>& picker) {
+ std::vector<T> matches;
+ for (const auto& item : picker.options) {
+ if (features.has(item.first)) {
+ matches.reserve(matches.size() + item.second.size());
+ matches.insert(matches.end(), item.second.begin(), item.second.end());
+ }
+ }
+ return vectorPick(matches);
+ }
+
// utilities
Name getTargetName(Expression* target) {
diff --git a/src/wasm.h b/src/wasm.h
index b7b835ebe..b09b4d7d3 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -50,24 +50,18 @@ struct FeatureSet {
FeatureSet(uint32_t features) : features(features) {}
bool isMVP() const { return features == MVP; }
+ bool has(Feature f) { return (features & f) == f; }
bool hasAtomics() const { return features & Atomics; }
bool hasMutableGlobals() const { return features & MutableGlobals; }
bool hasTruncSat() const { return features & TruncSat; }
bool hasAll() const { return features & (Atomics | MutableGlobals | TruncSat); }
void makeMVP() { features = MVP; }
- void setAtomics(bool v = true) {
- features = v ? (features | Atomics) : (features & ~Atomics);
- }
- void setMutableGlobals(bool v = true) {
- features = v ? (features | MutableGlobals) : (features & ~MutableGlobals);
- }
- void setTruncSat(bool v = true) {
- features = v ? (features | TruncSat) : (features & ~TruncSat);
- }
- void setAll(bool v = true) {
- features = v ? All : MVP;
- }
+ void set(Feature f, bool v = true) { features = v ? (features | f) : (features & ~f); }
+ void setAtomics(bool v = true) { set(Atomics, v); }
+ void setMutableGlobals(bool v = true) { set(MutableGlobals, v); }
+ void setTruncSat(bool v = true) { set(TruncSat, v); }
+ void setAll(bool v = true) { features = v ? All : MVP; }
private:
uint32_t features;