summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/fuzzing/fuzzing.cpp119
-rw-r--r--src/tools/fuzzing/heap-types.cpp132
-rw-r--r--src/tools/wasm-fuzz-types.cpp23
3 files changed, 157 insertions, 117 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 64780696b..bebf4f989 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -291,28 +291,35 @@ void TranslateToFuzzReader::setupHeapTypes() {
auto eq = HeapTypes::eq.getBasic(share);
auto any = HeapTypes::any.getBasic(share);
auto func = HeapTypes::func.getBasic(share);
- if (type.isStruct()) {
- interestingHeapSubTypes[struct_].push_back(type);
- interestingHeapSubTypes[eq].push_back(type);
- interestingHeapSubTypes[any].push_back(type);
-
- // Note the mutable fields.
- auto& fields = type.getStruct().fields;
- for (Index i = 0; i < fields.size(); i++) {
- if (fields[i].mutable_) {
- mutableStructFields.push_back(StructField{type, i});
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ interestingHeapSubTypes[func].push_back(type);
+ break;
+ case HeapTypeKind::Struct: {
+ interestingHeapSubTypes[struct_].push_back(type);
+ interestingHeapSubTypes[eq].push_back(type);
+ interestingHeapSubTypes[any].push_back(type);
+ // Note the mutable fields.
+ auto& fields = type.getStruct().fields;
+ for (Index i = 0; i < fields.size(); i++) {
+ if (fields[i].mutable_) {
+ mutableStructFields.push_back(StructField{type, i});
+ }
}
+ break;
}
- } else if (type.isArray()) {
- interestingHeapSubTypes[array].push_back(type);
- interestingHeapSubTypes[eq].push_back(type);
- interestingHeapSubTypes[any].push_back(type);
-
- if (type.getArray().element.mutable_) {
- mutableArrays.push_back(type);
- }
- } else if (type.isSignature()) {
- interestingHeapSubTypes[func].push_back(type);
+ case HeapTypeKind::Array:
+ interestingHeapSubTypes[array].push_back(type);
+ interestingHeapSubTypes[eq].push_back(type);
+ interestingHeapSubTypes[any].push_back(type);
+ if (type.getArray().element.mutable_) {
+ mutableArrays.push_back(type);
+ }
+ break;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
}
@@ -2757,43 +2764,49 @@ Expression* TranslateToFuzzReader::makeCompoundRef(Type type) {
return funcContext ? make(type) : makeTrivial(type);
};
- if (heapType.isSignature()) {
- return makeRefFuncConst(type);
- } else if (type.isStruct()) {
- auto& fields = heapType.getStruct().fields;
- std::vector<Expression*> values;
- // If there is a nondefaultable field, we must provide the value and not
- // depend on defaults. Also do that randomly half the time.
- if (std::any_of(
- fields.begin(),
- fields.end(),
- [&](const Field& field) { return !field.type.isDefaultable(); }) ||
- oneIn(2)) {
- for (auto& field : fields) {
- values.push_back(makeChild(field.type));
- }
- // Add more nesting manually, as we can easily get exponential blowup
- // here. This nesting makes it much less likely for a recursive data
- // structure to end up as a massive tree of struct.news, since the nesting
- // limitation code at the top of this function will kick in.
- if (!values.empty()) {
- // Subtract 1 since if there is a single value there cannot be
- // exponential blowup.
- nester.add(values.size() - 1);
+ switch (heapType.getKind()) {
+ case HeapTypeKind::Func:
+ return makeRefFuncConst(type);
+ case HeapTypeKind::Struct: {
+ auto& fields = heapType.getStruct().fields;
+ std::vector<Expression*> values;
+ // If there is a nondefaultable field, we must provide the value and not
+ // depend on defaults. Also do that randomly half the time.
+ if (std::any_of(
+ fields.begin(),
+ fields.end(),
+ [&](const Field& field) { return !field.type.isDefaultable(); }) ||
+ oneIn(2)) {
+ for (auto& field : fields) {
+ values.push_back(makeChild(field.type));
+ }
+ // Add more nesting manually, as we can easily get exponential blowup
+ // here. This nesting makes it much less likely for a recursive data
+ // structure to end up as a massive tree of struct.news, since the
+ // nesting limitation code at the top of this function will kick in.
+ if (!values.empty()) {
+ // Subtract 1 since if there is a single value there cannot be
+ // exponential blowup.
+ nester.add(values.size() - 1);
+ }
}
+ return builder.makeStructNew(heapType, values);
}
- return builder.makeStructNew(heapType, values);
- } else if (type.isArray()) {
- auto element = heapType.getArray().element;
- Expression* init = nullptr;
- if (!element.type.isDefaultable() || oneIn(2)) {
- init = makeChild(element.type);
+ case HeapTypeKind::Array: {
+ auto element = heapType.getArray().element;
+ Expression* init = nullptr;
+ if (!element.type.isDefaultable() || oneIn(2)) {
+ init = makeChild(element.type);
+ }
+ auto* count = builder.makeConst(int32_t(upTo(MAX_ARRAY_SIZE)));
+ return builder.makeArrayNew(type.getHeapType(), count, init);
}
- auto* count = builder.makeConst(int32_t(upTo(MAX_ARRAY_SIZE)));
- return builder.makeArrayNew(type.getHeapType(), count, init);
- } else {
- WASM_UNREACHABLE("bad user-defined ref type");
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
+ WASM_UNREACHABLE("unexpected kind");
}
Expression* TranslateToFuzzReader::makeStringNewArray() {
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index e4d54ae07..b4833475a 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -131,14 +131,20 @@ struct HeapTypeGeneratorImpl {
} else {
// We have a supertype, so create a subtype.
HeapType supertype = builder[*supertypeIndices[index]];
- if (supertype.isSignature()) {
- builder[index] = generateSubSignature(supertype.getSignature());
- } else if (supertype.isStruct()) {
- builder[index] = generateSubStruct(supertype.getStruct(), share);
- } else if (supertype.isArray()) {
- builder[index] = generateSubArray(supertype.getArray());
- } else {
- WASM_UNREACHABLE("unexpected kind");
+ switch (supertype.getKind()) {
+ case wasm::HeapTypeKind::Func:
+ builder[index] = generateSubSignature(supertype.getSignature());
+ break;
+ case wasm::HeapTypeKind::Struct:
+ builder[index] = generateSubStruct(supertype.getStruct(), share);
+ break;
+ case wasm::HeapTypeKind::Array:
+ builder[index] = generateSubArray(supertype.getArray());
+ break;
+ case wasm::HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case wasm::HeapTypeKind::Basic:
+ WASM_UNREACHABLE("unexpected kind");
}
}
}
@@ -879,38 +885,44 @@ std::vector<HeapType> Inhabitator::build() {
for (size_t i = 0; i < types.size(); ++i) {
auto type = types[i];
- if (type.isStruct()) {
- Struct copy = type.getStruct();
- for (size_t j = 0; j < copy.fields.size(); ++j) {
- updateType({type, j}, copy.fields[j].type);
+ switch (type.getKind()) {
+ case HeapTypeKind::Func: {
+ auto sig = type.getSignature();
+ size_t j = 0;
+ std::vector<Type> params;
+ for (auto param : sig.params) {
+ params.push_back(param);
+ updateType({type, j++}, params.back());
+ }
+ std::vector<Type> results;
+ for (auto result : sig.results) {
+ results.push_back(result);
+ updateType({type, j++}, results.back());
+ }
+ builder[i] = Signature(builder.getTempTupleType(params),
+ builder.getTempTupleType(results));
+ continue;
}
- builder[i] = copy;
- continue;
- }
- if (type.isArray()) {
- Array copy = type.getArray();
- updateType({type, 0}, copy.element.type);
- builder[i] = copy;
- continue;
- }
- if (type.isSignature()) {
- auto sig = type.getSignature();
- size_t j = 0;
- std::vector<Type> params;
- for (auto param : sig.params) {
- params.push_back(param);
- updateType({type, j++}, params.back());
+ case HeapTypeKind::Struct: {
+ Struct copy = type.getStruct();
+ for (size_t j = 0; j < copy.fields.size(); ++j) {
+ updateType({type, j}, copy.fields[j].type);
+ }
+ builder[i] = copy;
+ continue;
}
- std::vector<Type> results;
- for (auto result : sig.results) {
- results.push_back(result);
- updateType({type, j++}, results.back());
+ case HeapTypeKind::Array: {
+ Array copy = type.getArray();
+ updateType({type, 0}, copy.element.type);
+ builder[i] = copy;
+ continue;
}
- builder[i] = Signature(builder.getTempTupleType(params),
- builder.getTempTupleType(results));
- continue;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
- WASM_UNREACHABLE("unexpected type kind");
+ WASM_UNREACHABLE("unexpected kind");
}
// Establish rec groups.
@@ -994,35 +1006,43 @@ bool isUninhabitable(Type type,
bool isUninhabitable(HeapType type,
std::unordered_set<HeapType>& visited,
std::unordered_set<HeapType>& visiting) {
- if (type.isBasic()) {
- return false;
- }
- if (type.isSignature()) {
- // Function types are always inhabitable.
- return false;
+ switch (type.getKind()) {
+ case HeapTypeKind::Basic:
+ return false;
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ // Function types are always inhabitable.
+ return false;
+ case HeapTypeKind::Struct:
+ case HeapTypeKind::Array:
+ break;
}
if (visited.count(type)) {
return false;
}
-
- if (!visiting.insert(type).second) {
+ auto [it, inserted] = visiting.insert(type);
+ if (!inserted) {
return true;
}
-
- if (type.isStruct()) {
- for (auto& field : type.getStruct().fields) {
- if (isUninhabitable(field.type, visited, visiting)) {
+ switch (type.getKind()) {
+ case HeapTypeKind::Struct:
+ for (auto& field : type.getStruct().fields) {
+ if (isUninhabitable(field.type, visited, visiting)) {
+ return true;
+ }
+ }
+ break;
+ case HeapTypeKind::Array:
+ if (isUninhabitable(type.getArray().element.type, visited, visiting)) {
return true;
}
- }
- } else if (type.isArray()) {
- if (isUninhabitable(type.getArray().element.type, visited, visiting)) {
- return true;
- }
- } else {
- WASM_UNREACHABLE("unexpected type kind");
+ break;
+ case HeapTypeKind::Basic:
+ case HeapTypeKind::Func:
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("unexpected kind");
}
- visiting.erase(type);
+ visiting.erase(it);
visited.insert(type);
return false;
}
diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp
index 074d235c9..7ba341e09 100644
--- a/src/tools/wasm-fuzz-types.cpp
+++ b/src/tools/wasm-fuzz-types.cpp
@@ -297,15 +297,22 @@ void Fuzzer::checkCanonicalization() {
// Copy the original types
for (; index < types.size(); ++index) {
auto type = types[index];
- if (type.isSignature()) {
- builder[index] = getSignature(type.getSignature());
- } else if (type.isStruct()) {
- builder[index] = getStruct(type.getStruct());
- } else if (type.isArray()) {
- builder[index] = getArray(type.getArray());
- } else {
- WASM_UNREACHABLE("unexpected type kind");
+ switch (type.getKind()) {
+ case HeapTypeKind::Func:
+ builder[index] = getSignature(type.getSignature());
+ continue;
+ case HeapTypeKind::Struct:
+ builder[index] = getStruct(type.getStruct());
+ continue;
+ case HeapTypeKind::Array:
+ builder[index] = getArray(type.getArray());
+ continue;
+ case HeapTypeKind::Cont:
+ WASM_UNREACHABLE("TODO: cont");
+ case HeapTypeKind::Basic:
+ break;
}
+ WASM_UNREACHABLE("unexpected type kind");
}
}