Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/tools/fuzzing/heap-types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#include "ir/gc-type-utils.h"
#include "ir/subtypes.h"
#include "support/insert_ordered.h"
#include "tools/fuzzing.h"
#include "tools/fuzzing/heap-types.h"

Expand Down Expand Up @@ -275,12 +274,13 @@ struct HeapTypeGeneratorImpl {
builder[index].setOpen(subtypeIndices[index].size() > 1 || rand.oneIn(2));
auto kind = typeKinds[index];
auto share = HeapType(builder[index]).getShared();
bool isDesc = describedIndices[index].has_value();
if (!supertypeIndices[index]) {
// No nontrivial supertype, so create a root type.
if (std::get_if<SignatureKind>(&kind)) {
builder[index] = generateSignature();
} else if (std::get_if<StructKind>(&kind)) {
builder[index] = generateStruct(share);
builder[index] = generateStruct(share, isDesc);
} else if (std::get_if<ArrayKind>(&kind)) {
builder[index] = generateArray(share);
} else {
Expand Down Expand Up @@ -415,7 +415,13 @@ struct HeapTypeGeneratorImpl {
return {params, generateReturnType()};
}

Field generateField(Shareability share) {
Field generateField(Shareability share, bool isPrototypeField = false) {
// If this field could configure a prototype, then we want to give it a type
// that lets it do so a significant portion of the time.
if (isPrototypeField && share == Unshared && rand.oneIn(2)) {
auto nullability = rand.oneIn(2) ? NonNullable : Nullable;
return {Type(HeapType::ext, nullability), Immutable};
}
auto mutability = rand.oneIn(2) ? Mutable : Immutable;
if (rand.oneIn(6)) {
return {rand.oneIn(2) ? Field::i8 : Field::i16, mutability};
Expand All @@ -424,10 +430,13 @@ struct HeapTypeGeneratorImpl {
}
}

Struct generateStruct(Shareability share) {
Struct generateStruct(Shareability share, bool isDesc) {
std::vector<Field> fields(rand.upTo(params.MAX_STRUCT_SIZE + 1));
// Prototypes are configured on the first field of descriptors types.
bool isPrototypeField = isDesc;
for (auto& field : fields) {
field = generateField(share);
field = generateField(share, isPrototypeField);
isPrototypeField = false;
}
return {fields};
}
Expand Down
96 changes: 44 additions & 52 deletions test/lit/fuzz-types.test
Original file line number Diff line number Diff line change
@@ -1,64 +1,56 @@
;; RUN: wasm-fuzz-types -v --seed=0 | filecheck %s
;; RUN: wasm-fuzz-types -v --seed=2 | filecheck %s

;; CHECK: Running with seed 0
;; CHECK: Running with seed 2
;; CHECK-NEXT: Built 20 types:
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $0 (sub (shared (array i8))))
;; CHECK-NEXT: (type $1 (shared (array (ref $1))))
;; CHECK-NEXT: (type $2 (sub (shared (func (param i64 (ref null $5) i64) (result (ref $2))))))
;; CHECK-NEXT: (type $3 (sub $0 (shared (array i8))))
;; CHECK-NEXT: (type $4 (sub (array (ref null $9))))
;; CHECK-NEXT: (type $5 (sub final $0 (shared (array i8))))
;; CHECK-NEXT: (type $6 (sub $2 (shared (func (param i64 (ref null (shared eq)) i64) (result (ref $8))))))
;; CHECK-NEXT: (type $7 (sub (shared (descriptor $9) (struct (field (ref null $7)) (field (mut i64)) (field (mut i8)) (field i32) (field (mut i32))))))
;; CHECK-NEXT: (type $8 (sub $2 (shared (func (param i64 (ref null $0) i64) (result (ref $8))))))
;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $12) (struct (field i32) (field (mut (ref $8))) (field f64))))
;; CHECK-NEXT: (type $10 (sub (array (mut externref))))
;; CHECK-NEXT: (type $11 (sub $4 (array (ref $9))))
;; CHECK-NEXT: (type $12 (sub (shared (describes $9) (struct (field (mut f64)) (field (mut i32)) (field (mut f64))))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $13 (sub (struct (field (mut i16)) (field i64) (field (mut (ref (shared func)))))))
;; CHECK-NEXT: (type $14 (sub (shared (array (ref null $14)))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $15 (shared (array (ref null (shared extern)))))
;; CHECK-NEXT: (type $16 (sub final $14 (shared (array (ref null $16)))))
;; CHECK-NEXT: (type $0 (shared (struct)))
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $1 (array (ref $2)))
;; CHECK-NEXT: (type $2 (sub (shared (array (mut i16)))))
;; CHECK-NEXT: (type $3 (sub (shared (array i32))))
;; CHECK-NEXT: (type $4 (sub (descriptor $5) (struct (field (mut (ref $0))))))
;; CHECK-NEXT: (type $5 (sub (describes $4) (struct (field f64) (field (mut i64)))))
;; CHECK-NEXT: (type $6 (sub (array v128)))
;; CHECK-NEXT: (type $7 (shared (struct (field f32) (field (mut (ref $0))))))
;; CHECK-NEXT: (type $8 (sub (shared (struct (field f64) (field (mut (ref (shared struct)))) (field (mut f64)) (field i16) (field i32) (field i64)))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $17 (shared (struct (field (mut (ref null $2))) (field i32) (field (mut (ref $14))))))
;; CHECK-NEXT: (type $18 (sub $11 (array (ref $9))))
;; CHECK-NEXT: (type $19 (sub $2 (shared (func (param i64 (ref null $0) i64) (result (ref $6))))))
;; CHECK-NEXT: (type $9 (descriptor $12) (struct (field i64) (field i16)))
;; CHECK-NEXT: (type $10 (array (mut (ref null $5))))
;; CHECK-NEXT: (type $11 (sub (shared (func (param (ref $7) f64 (ref $9)) (result (ref null $10))))))
;; CHECK-NEXT: (type $12 (sub (describes $9) (descriptor $13) (struct (field (ref (shared any))) (field (mut (ref extern))) (field v128) (field (ref null $17)))))
;; CHECK-NEXT: (type $13 (sub (describes $12) (descriptor $17) (struct (field externref) (field (mut i8)) (field (mut i32)) (field (mut f32)) (field i16) (field (mut (ref null $6))))))
;; CHECK-NEXT: (type $14 (sub (func (result i64))))
;; CHECK-NEXT: (type $15 (sub (shared (func))))
;; CHECK-NEXT: (type $16 (shared (func (result (ref null $0)))))
;; CHECK-NEXT: (type $17 (sub (describes $13) (struct (field (ref extern)))))
;; CHECK-NEXT: (type $18 (sub (func (param v128 (ref null $10)))))
;; CHECK-NEXT: (type $19 (sub final $11 (shared (func (param (ref null (shared any)) f64 (ref any)) (result (ref $10))))))
;; CHECK-NEXT: )
;; CHECK-NEXT:
;; CHECK-NEXT: Inhabitable types:
;; CHECK-NEXT:
;; CHECK-NEXT: Built 20 types:
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $0 (sub (shared (array i8))))
;; CHECK-NEXT: (type $1 (shared (array (ref null $1))))
;; CHECK-NEXT: (type $2 (sub (shared (func (param i64 (ref null $5) i64) (result (ref $2))))))
;; CHECK-NEXT: (type $3 (sub $0 (shared (array i8))))
;; CHECK-NEXT: (type $4 (sub (array (ref null $9))))
;; CHECK-NEXT: (type $5 (sub final $0 (shared (array i8))))
;; CHECK-NEXT: (type $6 (sub $2 (shared (func (param i64 (ref null (shared eq)) i64) (result (ref $8))))))
;; CHECK-NEXT: (type $7 (sub (shared (descriptor $9) (struct (field (ref null $7)) (field (mut i64)) (field (mut i8)) (field i32) (field (mut i32))))))
;; CHECK-NEXT: (type $8 (sub $2 (shared (func (param i64 (ref null $0) i64) (result (ref $8))))))
;; CHECK-NEXT: (type $9 (shared (describes $7) (descriptor $12) (struct (field i32) (field (mut (ref $8))) (field f64))))
;; CHECK-NEXT: (type $10 (sub (array (mut externref))))
;; CHECK-NEXT: (type $11 (sub $4 (array (ref $9))))
;; CHECK-NEXT: (type $12 (sub (shared (describes $9) (struct (field (mut f64)) (field (mut i32)) (field (mut f64))))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $13 (sub (struct (field (mut i16)) (field i64) (field (mut (ref (shared func)))))))
;; CHECK-NEXT: (type $14 (sub (shared (array (ref null $14)))))
;; CHECK-NEXT: (type $0 (shared (struct)))
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $1 (array (ref $2)))
;; CHECK-NEXT: (type $2 (sub (shared (array (mut i16)))))
;; CHECK-NEXT: (type $3 (sub (shared (array i32))))
;; CHECK-NEXT: (type $4 (sub (descriptor $5) (struct (field (mut (ref $0))))))
;; CHECK-NEXT: (type $5 (sub (describes $4) (struct (field f64) (field (mut i64)))))
;; CHECK-NEXT: (type $6 (sub (array v128)))
;; CHECK-NEXT: (type $7 (shared (struct (field f32) (field (mut (ref $0))))))
;; CHECK-NEXT: (type $8 (sub (shared (struct (field f64) (field (mut (ref (shared struct)))) (field (mut f64)) (field i16) (field i32) (field i64)))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $15 (shared (array (ref null (shared extern)))))
;; CHECK-NEXT: (type $16 (sub final $14 (shared (array (ref null $16)))))
;; CHECK-NEXT: (type $9 (descriptor $12) (struct (field i64) (field i16)))
;; CHECK-NEXT: (type $10 (array (mut (ref null $5))))
;; CHECK-NEXT: (type $11 (sub (shared (func (param (ref $7) f64 (ref $9)) (result (ref null $10))))))
;; CHECK-NEXT: (type $12 (sub (describes $9) (descriptor $13) (struct (field (ref (shared any))) (field (mut externref)) (field v128) (field (ref null $17)))))
;; CHECK-NEXT: (type $13 (sub (describes $12) (descriptor $17) (struct (field externref) (field (mut i8)) (field (mut i32)) (field (mut f32)) (field i16) (field (mut (ref null $6))))))
;; CHECK-NEXT: (type $14 (sub (func (result i64))))
;; CHECK-NEXT: (type $15 (sub (shared (func))))
;; CHECK-NEXT: (type $16 (shared (func (result (ref null $0)))))
;; CHECK-NEXT: (type $17 (sub (describes $13) (struct (field externref))))
;; CHECK-NEXT: (type $18 (sub (func (param v128 (ref null $10)))))
;; CHECK-NEXT: (type $19 (sub final $11 (shared (func (param (ref null (shared any)) f64 (ref any)) (result (ref $10))))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
;; CHECK-NEXT: (type $17 (shared (struct (field (mut (ref null $2))) (field i32) (field (mut (ref $14))))))
;; CHECK-NEXT: (type $18 (sub $11 (array (ref $9))))
;; CHECK-NEXT: (type $19 (sub $2 (shared (func (param i64 (ref null $0) i64) (result (ref $6))))))
;; CHECK-NEXT: )
Loading