diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp index 589244bb2dd..4c065628382 100644 --- a/src/tools/fuzzing/heap-types.cpp +++ b/src/tools/fuzzing/heap-types.cpp @@ -263,23 +263,16 @@ struct HeapTypeGeneratorImpl { // by a described type. Only structs may have descriptor chains. if (!isDescriptor && std::get_if(&typeKinds.back()) && remainingUncommitted && features.hasCustomDescriptors()) { - if (super) { - // If we have a supertype, our descriptor chain must be at least as - // long as the supertype's descriptor chain. - size_t length = descriptorChainLengths[*super]; - if (rand.oneIn(2)) { - length += rand.upToSquared(remainingUncommitted - length); - } - descriptorChainLengths[i] = length; - numPlannedDescriptors += length; - } else { - // We can choose to start a brand new chain at this type. - if (rand.oneIn(2)) { - size_t length = rand.upToSquared(remainingUncommitted); - descriptorChainLengths[i] = length; - numPlannedDescriptors += length; - } + // If we have a supertype, our descriptor chain must be at least as + // long as the supertype's descriptor chain. + size_t length = super ? descriptorChainLengths[*super] : 0; + // If we have space, usually add at least one descriptor. + if (remainingUncommitted > length && !rand.oneIn(4)) { + length += 1 + rand.upToSquared(remainingUncommitted - length); } + assert(length <= remainingUncommitted); + descriptorChainLengths[i] = length; + numPlannedDescriptors += length; } // If this type has a descriptor chain, then we need to be able to // choose to generate the next type in the chain in the future. diff --git a/test/lit/fuzz-types.test b/test/lit/fuzz-types.test index b3683141c96..c164e32aaac 100644 --- a/test/lit/fuzz-types.test +++ b/test/lit/fuzz-types.test @@ -3,62 +3,58 @@ ;; CHECK: Running with seed 3 ;; CHECK-NEXT: Built 20 types: ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $0 (sub (shared (func (result (ref $3) i64))))) -;; CHECK-NEXT: (type $1 (sub (shared (struct (field (mut (ref null (shared extern)))) (field (ref null $3)) (field (mut v128)) (field v128) (field (mut (ref (shared any)))) (field (ref (shared i31))))))) -;; CHECK-NEXT: (type $2 (sub (func (param (ref $1))))) -;; CHECK-NEXT: (type $3 (shared (struct (field f32) (field (mut (ref null (shared eq)))) (field (ref (shared extern))) (field (mut (ref null (shared struct)))) (field (mut f32)) (field (mut (ref null $0)))))) -;; CHECK-NEXT: (type $4 (sub (func (result i64)))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $5 (struct (field (mut (ref $0))) (field i8) (field i31ref) (field (ref func)) (field f32))) -;; CHECK-NEXT: (type $6 (sub (func (param f64 (ref $7) (ref null $5) f32) (result i32)))) -;; CHECK-NEXT: (type $7 (sub (shared (func (param (ref null $4) (ref null $6)))))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $8 (struct (field (mut v128)) (field (mut (ref $5))) (field (mut v128)) (field (mut f64)) (field (mut i8)))) -;; CHECK-NEXT: (type $9 (shared (struct (field i32) (field (mut i32)) (field (mut i16))))) -;; CHECK-NEXT: (type $10 (sub (func (param f32 (ref null $4) f64) (result (ref (shared struct)))))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $11 (cont $16)) -;; CHECK-NEXT: (type $12 (sub final $10 (func (param f32 funcref f64) (result (ref $9))))) -;; CHECK-NEXT: (type $13 (cont $19)) -;; CHECK-NEXT: (type $14 (sub $2 (func (param (ref null (shared struct)))))) -;; CHECK-NEXT: (type $15 (sub (struct (field (mut (ref $7))) (field (mut i8)) (field (mut v128)) (field f64) (field f64) (field i64)))) -;; CHECK-NEXT: (type $16 (sub final $14 (func (param (ref null (shared eq)))))) -;; CHECK-NEXT: (type $17 (sub (func (param f32 v128 (ref $13)) (result (ref $5))))) -;; CHECK-NEXT: (type $18 (struct (field (ref null $6)) (field (ref $17)) (field (mut f64)) (field (mut i64)))) -;; CHECK-NEXT: (type $19 (sub $4 (func (result i64)))) +;; CHECK-NEXT: (type $0 (shared (func (param i32 (ref null $3)) (result (ref null $3) f32 f32 i64)))) +;; CHECK-NEXT: (type $1 (sub (shared (descriptor $2) (struct)))) +;; CHECK-NEXT: (type $2 (sub (shared (describes $1) (descriptor $4) (struct)))) +;; CHECK-NEXT: (type $3 (sub (array (mut f32)))) +;; CHECK-NEXT: (type $4 (shared (describes $2) (struct))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $5 (sub (shared (descriptor $6) (struct (field (ref null $1)) (field (ref null (shared func))) (field (mut f32)) (field i8) (field (mut i8)))))) +;; CHECK-NEXT: (type $6 (shared (describes $5) (descriptor $7) (struct (field (mut (ref null $2))) (field (mut i8)) (field f32) (field (mut (ref $11))) (field f32)))) +;; CHECK-NEXT: (type $7 (shared (describes $6) (descriptor $9) (struct (field i32) (field v128) (field (ref null $11)) (field (mut (ref $6))) (field (mut f64)) (field (ref (shared extern)))))) +;; CHECK-NEXT: (type $8 (sub (struct (field (ref null $7)) (field i8) (field (mut (ref $6))) (field (mut externref))))) +;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $11) (struct))) +;; CHECK-NEXT: (type $10 (sub (func (param f64 i32) (result f32)))) +;; CHECK-NEXT: (type $11 (sub (shared (describes $9) (struct (field (mut i8)) (field (mut (ref $6))) (field f32) (field (ref null $2)))))) +;; CHECK-NEXT: (type $12 (sub (descriptor $13) (struct (field i32) (field (ref null $9)) (field (mut f32)) (field (mut i16)) (field f64)))) +;; CHECK-NEXT: (type $13 (describes $12) (struct (field externref) (field (ref $2)) (field (mut (ref $6))) (field (mut f32)))) +;; CHECK-NEXT: (type $14 (sub final $8 (struct (field (ref $7)) (field i8) (field (mut (ref $6))) (field (mut externref)) (field (mut (ref $1)))))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $15 (sub final $8 (struct (field (ref $7)) (field i8) (field (mut (ref $6))) (field (mut externref))))) +;; CHECK-NEXT: (type $16 (descriptor $18) (struct (field (ref null $2)) (field i16) (field i64) (field (ref $9)) (field (mut (ref $3))))) +;; CHECK-NEXT: (type $17 (sub (func (param f64) (result (ref null $19))))) +;; CHECK-NEXT: (type $18 (describes $16) (struct)) +;; CHECK-NEXT: (type $19 (cont $17)) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ;; CHECK-NEXT: Inhabitable types: ;; CHECK-NEXT: ;; CHECK-NEXT: Built 20 types: ;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $0 (sub (shared (func (result (ref $3) i64))))) -;; CHECK-NEXT: (type $1 (sub (shared (struct (field (mut (ref null (shared extern)))) (field (ref null $3)) (field (mut v128)) (field v128) (field (mut (ref (shared any)))) (field (ref (shared i31))))))) -;; CHECK-NEXT: (type $2 (sub (func (param (ref $1))))) -;; CHECK-NEXT: (type $3 (shared (struct (field f32) (field (mut (ref null (shared eq)))) (field (ref null (shared extern))) (field (mut (ref null (shared struct)))) (field (mut f32)) (field (mut (ref null $0)))))) -;; CHECK-NEXT: (type $4 (sub (func (result i64)))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $5 (struct (field (mut (ref $0))) (field i8) (field i31ref) (field (ref func)) (field f32))) -;; CHECK-NEXT: (type $6 (sub (func (param f64 (ref $7) (ref null $5) f32) (result i32)))) -;; CHECK-NEXT: (type $7 (sub (shared (func (param (ref null $4) (ref null $6)))))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $8 (struct (field (mut v128)) (field (mut (ref $5))) (field (mut v128)) (field (mut f64)) (field (mut i8)))) -;; CHECK-NEXT: (type $9 (shared (struct (field i32) (field (mut i32)) (field (mut i16))))) -;; CHECK-NEXT: (type $10 (sub (func (param f32 (ref null $4) f64) (result (ref (shared struct)))))) -;; CHECK-NEXT: ) -;; CHECK-NEXT: (rec -;; CHECK-NEXT: (type $11 (cont $16)) -;; CHECK-NEXT: (type $12 (sub final $10 (func (param f32 funcref f64) (result (ref $9))))) -;; CHECK-NEXT: (type $13 (cont $19)) -;; CHECK-NEXT: (type $14 (sub $2 (func (param (ref null (shared struct)))))) -;; CHECK-NEXT: (type $15 (sub (struct (field (mut (ref $7))) (field (mut i8)) (field (mut v128)) (field f64) (field f64) (field i64)))) -;; CHECK-NEXT: (type $16 (sub final $14 (func (param (ref null (shared eq)))))) -;; CHECK-NEXT: (type $17 (sub (func (param f32 v128 (ref $13)) (result (ref $5))))) -;; CHECK-NEXT: (type $18 (struct (field (ref null $6)) (field (ref $17)) (field (mut f64)) (field (mut i64)))) -;; CHECK-NEXT: (type $19 (sub $4 (func (result i64)))) +;; CHECK-NEXT: (type $0 (shared (func (param i32 (ref null $3)) (result (ref null $3) f32 f32 i64)))) +;; CHECK-NEXT: (type $1 (sub (shared (descriptor $2) (struct)))) +;; CHECK-NEXT: (type $2 (sub (shared (describes $1) (descriptor $4) (struct)))) +;; CHECK-NEXT: (type $3 (sub (array (mut f32)))) +;; CHECK-NEXT: (type $4 (shared (describes $2) (struct))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $5 (sub (shared (descriptor $6) (struct (field (ref null $1)) (field (ref null (shared func))) (field (mut f32)) (field i8) (field (mut i8)))))) +;; CHECK-NEXT: (type $6 (shared (describes $5) (descriptor $7) (struct (field (mut (ref null $2))) (field (mut i8)) (field f32) (field (mut (ref $11))) (field f32)))) +;; CHECK-NEXT: (type $7 (shared (describes $6) (descriptor $9) (struct (field i32) (field v128) (field (ref null $11)) (field (mut (ref null $6))) (field (mut f64)) (field (ref null (shared extern)))))) +;; CHECK-NEXT: (type $8 (sub (struct (field (ref null $7)) (field i8) (field (mut (ref $6))) (field (mut externref))))) +;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $11) (struct))) +;; CHECK-NEXT: (type $10 (sub (func (param f64 i32) (result f32)))) +;; CHECK-NEXT: (type $11 (sub (shared (describes $9) (struct (field (mut i8)) (field (mut (ref null $6))) (field f32) (field (ref null $2)))))) +;; CHECK-NEXT: (type $12 (sub (descriptor $13) (struct (field i32) (field (ref null $9)) (field (mut f32)) (field (mut i16)) (field f64)))) +;; CHECK-NEXT: (type $13 (describes $12) (struct (field externref) (field (ref $2)) (field (mut (ref $6))) (field (mut f32)))) +;; CHECK-NEXT: (type $14 (sub final $8 (struct (field (ref $7)) (field i8) (field (mut (ref $6))) (field (mut externref)) (field (mut (ref $1)))))) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (rec +;; CHECK-NEXT: (type $15 (sub final $8 (struct (field (ref $7)) (field i8) (field (mut (ref $6))) (field (mut externref))))) +;; CHECK-NEXT: (type $16 (descriptor $18) (struct (field (ref null $2)) (field i16) (field i64) (field (ref $9)) (field (mut (ref $3))))) +;; CHECK-NEXT: (type $17 (sub (func (param f64) (result (ref null $19))))) +;; CHECK-NEXT: (type $18 (describes $16) (struct)) +;; CHECK-NEXT: (type $19 (cont $17)) ;; CHECK-NEXT: )