diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-11-19 16:16:42 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-19 16:16:42 -0800 |
commit | d532e3a4b02375fe85a2e81be336a181e6bdc10b (patch) | |
tree | 222e18bc63327c22b98c64e29a903a461d731c60 /src/tools | |
parent | be672c057bcb39b27f34f4031eea747bd72161d2 (diff) | |
download | binaryen-d532e3a4b02375fe85a2e81be336a181e6bdc10b.tar.gz binaryen-d532e3a4b02375fe85a2e81be336a181e6bdc10b.tar.bz2 binaryen-d532e3a4b02375fe85a2e81be336a181e6bdc10b.zip |
Allow building basic HeapTypes in nominal mode (#4346)
As we work toward allowing nominal and structural types to coexist, any
difference in how they can be built or used will be an inconvenient footgun that
we will have to work around. In the spirit of reducing the differences between
the type systems, allow TypeBuilder to construct basic HeapTypes in nominal mode
just as it can in equirecursive mode.
Although this change is a net increase in code complexity for not much
benefit (wasm-opt never needs to build basic HeapTypes), it is also an
incremental step toward getting rid of separate type system modes, so I expect
it to simplify other PRs in the near future.
This change also uncovered a bug in how the type fuzzer generated subtypes of
basic HeapTypes. The generated subtypes did not necessarily have the intended
`Kind`, which caused failures in nominal subtype validation in the fuzzer.
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/fuzzing/heap-types.cpp | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 1878f5473..9992baf55 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -365,13 +365,7 @@ struct HeapTypeGenerator { } HeapTypeKind generateHeapTypeKind() { - // Building basic heap types is only allowed in equirecursive mode. - // TODO: Relax this. - size_t options = 2; - if (getTypeSystem() == TypeSystem::Equirecursive) { - ++options; - } - switch (rand.upTo(options)) { + switch (rand.upTo(3)) { case 0: return SignatureKind{}; case 1: @@ -441,12 +435,14 @@ struct HeapTypeGenerator { // Create the heap types. for (Index i = 0; i < builder.size(); ++i) { - if (!supertypeIndices[i]) { - // Create a root type. - auto kind = typeKinds[i]; - if (auto* basic = std::get_if<BasicKind>(&kind)) { - builder[i] = *basic; - } else if (std::get_if<SignatureKind>(&kind)) { + auto kind = typeKinds[i]; + if (auto* basic = std::get_if<BasicKind>(&kind)) { + // The type is already determined. + builder[i] = *basic; + } else if (!supertypeIndices[i] || + builder.isBasic(*supertypeIndices[i])) { + // No nontrivial supertype, so create a root type. + if (std::get_if<SignatureKind>(&kind)) { builder[i] = generateSignature(); } else if (std::get_if<DataKind>(&kind)) { if (rand.oneIn(2)) { @@ -459,12 +455,8 @@ struct HeapTypeGenerator { } } else { // We have a supertype, so create a subtype. - Index super = *supertypeIndices[i]; - HeapType supertype = builder[super]; - if (builder.isBasic(super)) { - auto assignable = generateSubBasic(builder.getBasic(super)); - std::visit([&](auto&& arg) { builder[i] = arg; }, assignable); - } else if (supertype.isSignature()) { + HeapType supertype = builder[*supertypeIndices[i]]; + if (supertype.isSignature()) { builder[i] = generateSubSignature(supertype.getSignature()); } else if (supertype.isStruct()) { builder[i] = generateSubStruct(supertype.getStruct()); |