diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/fuzzing/heap-types.cpp | 81 | ||||
-rw-r--r-- | src/tools/wasm-fuzz-types.cpp | 58 |
2 files changed, 26 insertions, 113 deletions
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index e58c7f51d..26cc518be 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -40,12 +40,10 @@ struct HeapTypeGeneratorImpl { // Top-level kinds, chosen before the types are actually constructed. This // allows us to choose HeapTypes that we know will be subtypes of data or func // before we actually generate the types. - using BasicKind = HeapType::BasicHeapType; struct SignatureKind {}; struct StructKind {}; struct ArrayKind {}; - using HeapTypeKind = - std::variant<BasicKind, SignatureKind, StructKind, ArrayKind>; + using HeapTypeKind = std::variant<SignatureKind, StructKind, ArrayKind>; std::vector<HeapTypeKind> typeKinds; // For each type, the index one past the end of its recursion group, used to @@ -83,7 +81,7 @@ struct HeapTypeGeneratorImpl { builder[i].subTypeOf(builder[super]); supertypeIndices[i] = super; subtypeIndices[super].push_back(i); - typeKinds.push_back(getSubKind(typeKinds[super])); + typeKinds.push_back(typeKinds[super]); } } @@ -110,11 +108,7 @@ struct HeapTypeGeneratorImpl { // Create the heap types. for (; index < builder.size(); ++index) { auto kind = typeKinds[index]; - if (auto* basic = std::get_if<BasicKind>(&kind)) { - // The type is already determined. - builder[index] = *basic; - } else if (!supertypeIndices[index] || - builder.isBasic(*supertypeIndices[index])) { + if (!supertypeIndices[index]) { // No nontrivial supertype, so create a root type. if (std::get_if<SignatureKind>(&kind)) { builder[index] = generateSignature(); @@ -365,9 +359,7 @@ struct HeapTypeGeneratorImpl { // the builder. if (rand.oneIn(candidates.size() * 8)) { auto* kind = &typeKinds[it->second]; - if (auto* basic = std::get_if<BasicKind>(kind)) { - return HeapType(*basic).getBottom(); - } else if (std::get_if<SignatureKind>(kind)) { + if (std::get_if<SignatureKind>(kind)) { return HeapType::nofunc; } else { return HeapType::none; @@ -434,9 +426,7 @@ struct HeapTypeGeneratorImpl { candidates.push_back(HeapType::func); return rand.pick(candidates); } else { - // A constructed basic type. Fall through to add all of the basic - // supertypes as well. - type = *std::get_if<BasicKind>(kind); + WASM_UNREACHABLE("unexpected kind"); } } // This is not a constructed type, so it must be a basic type. @@ -576,70 +566,9 @@ struct HeapTypeGeneratorImpl { return StructKind{}; case 2: return ArrayKind{}; - case 3: - return BasicKind{generateBasicHeapType()}; } WASM_UNREACHABLE("unexpected index"); } - - HeapTypeKind getSubKind(HeapTypeKind super) { - if (rand.oneIn(16)) { - // Occasionally go directly to the bottom type. - if (auto* basic = std::get_if<BasicKind>(&super)) { - return HeapType(*basic).getBottom(); - } else if (std::get_if<SignatureKind>(&super)) { - return HeapType::nofunc; - } else if (std::get_if<StructKind>(&super)) { - return HeapType::none; - } else if (std::get_if<ArrayKind>(&super)) { - return HeapType::none; - } - WASM_UNREACHABLE("unexpected kind"); - } - if (auto* basic = std::get_if<BasicKind>(&super)) { - if (rand.oneIn(8)) { - return super; - } - switch (*basic) { - case HeapType::func: - return SignatureKind{}; - case HeapType::ext: - case HeapType::i31: - return super; - case HeapType::any: - if (rand.oneIn(5)) { - return HeapType::eq; - } - [[fallthrough]]; - case HeapType::eq: - switch (rand.upTo(3)) { - case 0: - return HeapType::i31; - case 1: - return StructKind{}; - case 2: - return ArrayKind{}; - } - WASM_UNREACHABLE("unexpected index"); - case HeapType::struct_: - return StructKind{}; - case HeapType::array: - return ArrayKind{}; - case HeapType::string: - case HeapType::stringview_wtf8: - case HeapType::stringview_wtf16: - case HeapType::stringview_iter: - case HeapType::none: - case HeapType::noext: - case HeapType::nofunc: - return super; - } - WASM_UNREACHABLE("unexpected kind"); - } else { - // Signature and Data types can only have Signature and Data subtypes. - return super; - } - } }; } // anonymous namespace diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp index 0dc9f9d17..4f480ba9d 100644 --- a/src/tools/wasm-fuzz-types.cpp +++ b/src/tools/wasm-fuzz-types.cpp @@ -104,7 +104,7 @@ void Fuzzer::printTypes(const std::vector<HeapType>& types) { auto inRecGroup = [&]() { return currRecGroup && currRecGroup->size() > 1; }; for (size_t i = 0; i < types.size(); ++i) { auto type = types[i]; - if (!type.isBasic() && type.getRecGroup() != currRecGroup) { + if (type.getRecGroup() != currRecGroup) { if (inRecGroup()) { std::cout << ")\n"; } @@ -116,10 +116,6 @@ void Fuzzer::printTypes(const std::vector<HeapType>& types) { if (inRecGroup()) { std::cout << ' '; } - if (type.isBasic()) { - std::cout << "(type $" << i << ' ' << print(type) << ")\n"; - continue; - } auto [it, inserted] = seen.insert({type, i}); if (inserted) { std::cout << print(type); @@ -280,13 +276,9 @@ void Fuzzer::checkCanonicalization() { currGroupStart = end; }; for (Index i = 0; i < types.size(); ++i) { - auto type = types[i]; - if (type.isBasic()) { - continue; - } - auto newGroup = type.getRecGroup(); + auto newGroup = types[i].getRecGroup(); if (!currGroup || newGroup != currGroup || - type == types[currGroupStart]) { + types[i] == types[currGroupStart]) { finishGroup(i); currGroup = newGroup; } @@ -296,9 +288,7 @@ void Fuzzer::checkCanonicalization() { // Copy the original types for (; index < types.size(); ++index) { auto type = types[index]; - if (type.isBasic()) { - builder[index] = type.getBasic(); - } else if (type.isSignature()) { + if (type.isSignature()) { builder[index] = getSignature(type.getSignature()); } else if (type.isStruct()) { builder[index] = getStruct(type.getStruct()); @@ -333,28 +323,27 @@ void Fuzzer::checkCanonicalization() { CopiedHeapType getChildHeapType(HeapType old) { auto it = typeIndices.find(old); if (it == typeIndices.end()) { - // This is a basic heap type that wasn't explicitly built. + // This is a basic heap type and wasn't explicitly built. assert(old.isBasic()); return {OldHeapType{old}}; } - if (!old.isBasic()) { - // Check whether this child heap type is supposed to be a self-reference - // into the recursion group we are defining. If it is, we must use the - // corresponding type in the new recursion group, since anything else - // would break isorecursive equivalence. - auto group = old.getRecGroup(); - if (group == types[index].getRecGroup()) { - // This is a self-reference, so find the correct index, which is the - // last matching index less than the end of this rec group. - std::optional<Index> i; - for (auto candidate : it->second) { - if (candidate >= recGroupEnds[index]) { - break; - } - i = candidate; + assert(!old.isBasic()); + // Check whether this child heap type is supposed to be a self-reference + // into the recursion group we are defining. If it is, we must use the + // corresponding type in the new recursion group, since anything else + // would break isorecursive equivalence. + auto group = old.getRecGroup(); + if (group == types[index].getRecGroup()) { + // This is a self-reference, so find the correct index, which is the + // last matching index less than the end of this rec group. + std::optional<Index> i; + for (auto candidate : it->second) { + if (candidate >= recGroupEnds[index]) { + break; } - return {NewHeapType{builder[*i]}}; + i = candidate; } + return {NewHeapType{builder[*i]}}; } // Choose whether to use an old type or a new type if (rand.oneIn(2)) { @@ -366,12 +355,7 @@ void Fuzzer::checkCanonicalization() { candidateIndices.push_back(i); } } - if (candidateIndices.empty()) { - // This is a basic type that was only ever created after the current - // rec group, so we can't refer to a new copy of it after all. - assert(old.isBasic()); - return {OldHeapType{old}}; - } + assert(!candidateIndices.empty()); Index i = rand.pick(candidateIndices); return {NewHeapType{builder[i]}}; } else { |