summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-11-19 16:16:42 -0800
committerGitHub <noreply@github.com>2021-11-19 16:16:42 -0800
commitd532e3a4b02375fe85a2e81be336a181e6bdc10b (patch)
tree222e18bc63327c22b98c64e29a903a461d731c60 /src/tools
parentbe672c057bcb39b27f34f4031eea747bd72161d2 (diff)
downloadbinaryen-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.cpp30
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());