summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-12-02 10:14:17 -0600
committerGitHub <noreply@github.com>2022-12-02 08:14:17 -0800
commited06104c6f342d14653932b02d5b060654db0d1d (patch)
tree02d88fb5414f051a3b0b9aa885fad9dd8a303048
parent197b6da7afe6ec317011800abf9453402e6beaa5 (diff)
downloadbinaryen-ed06104c6f342d14653932b02d5b060654db0d1d.tar.gz
binaryen-ed06104c6f342d14653932b02d5b060654db0d1d.tar.bz2
binaryen-ed06104c6f342d14653932b02d5b060654db0d1d.zip
Support `array` and `struct` types in the type fuzzer (#5308)
Since `data` has been removed from the upstream proposal and `struct` has been added in its place, update the type fuzzer to be structured around `struct` and `array` (which it had not previously been updated to support) rather than `data`. A follow-on PR will make the broader change of removing `data` and adding `struct`.
-rw-r--r--src/tools/fuzzing/heap-types.cpp94
-rw-r--r--test/lit/fuzz-types/isorecursive.test50
-rw-r--r--test/lit/fuzz-types/nominal.test38
3 files changed, 101 insertions, 81 deletions
diff --git a/src/tools/fuzzing/heap-types.cpp b/src/tools/fuzzing/heap-types.cpp
index e93aae56c..7d7b4cb8d 100644
--- a/src/tools/fuzzing/heap-types.cpp
+++ b/src/tools/fuzzing/heap-types.cpp
@@ -39,8 +39,10 @@ struct HeapTypeGeneratorImpl {
// before we actually generate the types.
using BasicKind = HeapType::BasicHeapType;
struct SignatureKind {};
- struct DataKind {};
- using HeapTypeKind = std::variant<BasicKind, SignatureKind, DataKind>;
+ struct StructKind {};
+ struct ArrayKind {};
+ using HeapTypeKind =
+ std::variant<BasicKind, SignatureKind, StructKind, ArrayKind>;
std::vector<HeapTypeKind> typeKinds;
// For each type, the index one past the end of its recursion group, used to
@@ -122,12 +124,10 @@ struct HeapTypeGeneratorImpl {
// No nontrivial supertype, so create a root type.
if (std::get_if<SignatureKind>(&kind)) {
builder[index] = generateSignature();
- } else if (std::get_if<DataKind>(&kind)) {
- if (rand.oneIn(2)) {
- builder[index] = generateStruct();
- } else {
- builder[index] = generateArray();
- }
+ } else if (std::get_if<StructKind>(&kind)) {
+ builder[index] = generateStruct();
+ } else if (std::get_if<ArrayKind>(&kind)) {
+ builder[index] = generateArray();
} else {
WASM_UNREACHABLE("unexpected kind");
}
@@ -152,13 +152,14 @@ struct HeapTypeGeneratorImpl {
if (rand.oneIn(16)) {
return rand.pick(HeapType::noext, HeapType::nofunc, HeapType::none);
}
- // TODO: strings and array
+ // TODO: string types
return rand.pick(HeapType::func,
HeapType::ext,
HeapType::any,
HeapType::eq,
HeapType::i31,
- HeapType::data);
+ HeapType::data,
+ HeapType::array);
}
Type::BasicType generateBasicType() {
@@ -266,8 +267,8 @@ struct HeapTypeGeneratorImpl {
}
}
- HeapType pickSubData() {
- if (auto type = pickKind<DataKind>()) {
+ HeapType pickSubStruct() {
+ if (auto type = pickKind<StructKind>()) {
return *type;
} else if (rand.oneIn(2)) {
return HeapType::none;
@@ -276,12 +277,26 @@ struct HeapTypeGeneratorImpl {
}
}
- HeapType pickSubEq() {
- if (rand.oneIn(2)) {
- return HeapType::i31;
+ HeapType pickSubArray() {
+ if (auto type = pickKind<ArrayKind>()) {
+ return *type;
+ } else if (rand.oneIn(2)) {
+ return HeapType::none;
} else {
- return pickSubData();
+ return HeapType::array;
+ }
+ }
+
+ HeapType pickSubEq() {
+ switch (rand.upTo(3)) {
+ case 0:
+ return HeapType::i31;
+ case 1:
+ return pickSubStruct();
+ case 2:
+ return pickSubArray();
}
+ WASM_UNREACHABLE("unexpected index");
}
HeapType pickSubAny() {
@@ -325,9 +340,9 @@ struct HeapTypeGeneratorImpl {
case HeapType::i31:
return HeapType::i31;
case HeapType::data:
- return pickSubData();
+ return pickSubStruct();
case HeapType::array:
- WASM_UNREACHABLE("TODO: fuzz array");
+ return pickSubArray();
case HeapType::string:
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
@@ -412,8 +427,10 @@ struct HeapTypeGeneratorImpl {
case 0:
return SignatureKind{};
case 1:
- return DataKind{};
+ return StructKind{};
case 2:
+ return ArrayKind{};
+ case 3:
return BasicKind{generateBasicHeapType()};
}
WASM_UNREACHABLE("unexpected index");
@@ -426,7 +443,9 @@ struct HeapTypeGeneratorImpl {
return HeapType(*basic).getBottom();
} else if (std::get_if<SignatureKind>(&super)) {
return HeapType::nofunc;
- } else if (std::get_if<DataKind>(&super)) {
+ } else if (std::get_if<StructKind>(&super)) {
+ return HeapType::none;
+ } else if (std::get_if<ArrayKind>(&super)) {
return HeapType::none;
}
WASM_UNREACHABLE("unexpected kind");
@@ -442,31 +461,26 @@ struct HeapTypeGeneratorImpl {
case HeapType::i31:
return super;
case HeapType::any:
- if (rand.oneIn(4)) {
- switch (rand.upTo(3)) {
- case 0:
- return HeapType::eq;
- case 1:
- return HeapType::i31;
- case 2:
- return HeapType::data;
- }
+ if (rand.oneIn(5)) {
+ return HeapType::eq;
}
- return DataKind{};
+ [[fallthrough]];
case HeapType::eq:
- if (rand.oneIn(4)) {
- switch (rand.upTo(2)) {
- case 0:
- return HeapType::i31;
- case 1:
- return HeapType::data;
- }
+ switch (rand.upTo(4)) {
+ case 0:
+ return HeapType::i31;
+ case 1:
+ return HeapType::data;
+ case 2:
+ return StructKind{};
+ case 3:
+ return ArrayKind{};
}
- return DataKind{};
+ WASM_UNREACHABLE("unexpected index");
case HeapType::data:
- return DataKind{};
+ return StructKind{};
case HeapType::array:
- WASM_UNREACHABLE("TODO: fuzz array");
+ return ArrayKind{};
case HeapType::string:
case HeapType::stringview_wtf8:
case HeapType::stringview_wtf16:
diff --git a/test/lit/fuzz-types/isorecursive.test b/test/lit/fuzz-types/isorecursive.test
index 4a1725c07..f670104f5 100644
--- a/test/lit/fuzz-types/isorecursive.test
+++ b/test/lit/fuzz-types/isorecursive.test
@@ -1,26 +1,32 @@
-;; RUN: wasm-fuzz-types --hybrid -v --seed=0 | filecheck %s
+;; RUN: wasm-fuzz-types --hybrid -v --seed=1 | filecheck %s
-;; CHECK: (rec
-;; CHECK-NEXT: (type $0 (array (mut i64)))
-;; CHECK-NEXT: (type $1 (func (param i32 (ref eq) (ref null $3)) (result v128)))
-;; CHECK-NEXT: (type $2 (array (mut v128)))
-;; CHECK-NEXT: (type $3 (array_subtype (mut i64) $0))
-;; CHECK-NEXT: (type $4 (array i32))
-;; CHECK-NEXT: (type $5 none)
-;; CHECK-NEXT: (type $6 extern)
+;; CHECK: (type $0 (struct))
+;; CHECK-NEXT: (rec
+;; CHECK-NEXT: (type $1 (struct))
+;; CHECK-NEXT: (type $2 (array i16))
+;; CHECK-NEXT: (type $3 (func))
+;; CHECK-NEXT: (type $4 (func (param (ref $5) i32 i64 f64 f64 (ref eq) v128) (result i64)))
+;; CHECK-NEXT: (type $5 (array (mut i32)))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $7 (array_subtype (mut i64) $3))
-;; CHECK-NEXT: (type $8 (func (result v128)))
-;; CHECK-NEXT: (type $9 (array_subtype (mut v128) $2))
-;; CHECK-NEXT: (type $10 none)
-;; CHECK-NEXT: (type $11 none)
-;; CHECK-NEXT: (type $12 (array_subtype (mut v128) $2))
-;; CHECK-NEXT: (type $13 (func (param f32 (ref none) (ref null $3)) (result eqref)))
-;; CHECK-NEXT: (type $14 (array_subtype (mut i64) $7))
-;; CHECK-NEXT: (type $15 (func (param (ref null $17) v128 (ref i31))))
-;; CHECK-NEXT: (type $16 (array i32))
-;; CHECK-NEXT: (type $17 (func (param (ref i31)) (result v128)))
-;; CHECK-NEXT: (type $18 (func (param f32)))
-;; CHECK-NEXT: (type $19 (array_subtype (mut i64) $3))
+;; CHECK-NEXT: (type $6 (array (mut funcref)))
+;; CHECK-NEXT: (type $7 (func (param f64) (result i64)))
;; CHECK-NEXT: )
+;; CHECK-NEXT: (rec
+;; CHECK-NEXT: (type $8 (struct_subtype $1))
+;; CHECK-NEXT: (type $9 (func_subtype (param (ref $5) i32 i64 f64 f64 (ref eq) v128) (result i64) $4))
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (rec
+;; CHECK-NEXT: (type $10 (func_subtype (param (ref $5) i32 i64 f64 f64 (ref eq) v128) (result i64) $9))
+;; CHECK-NEXT: (type $11 (array_subtype (mut funcref) $6))
+;; CHECK-NEXT: (type $12 (array f64))
+;; CHECK-NEXT: (type $13 none)
+;; CHECK-NEXT: (type $14 (array arrayref))
+;; CHECK-NEXT: (type $15 (array (mut i8)))
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (rec
+;; CHECK-NEXT: (type $16 (array_subtype f64 $12))
+;; CHECK-NEXT: (type $17 (func (param (ref $5) (ref null $3) (ref null $0) (ref null $2) (ref $8) v128) (result v128)))
+;; CHECK-NEXT: (type $18 none)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (type $19 (func_subtype (param (ref $5) i32 i64 f64 f64 (ref eq) v128) (result i64) $9))
diff --git a/test/lit/fuzz-types/nominal.test b/test/lit/fuzz-types/nominal.test
index 26802a4ba..c127105bb 100644
--- a/test/lit/fuzz-types/nominal.test
+++ b/test/lit/fuzz-types/nominal.test
@@ -1,22 +1,22 @@
;; RUN: wasm-fuzz-types --nominal -v --seed=0 | filecheck %s
-;; CHECK: (type $0 (array (mut (ref null $8))))
-;; CHECK-NEXT: (type $1 (func (param nullref) (result v128)))
-;; CHECK-NEXT: (type $2 (struct (field (mut i64) (mut i8) (mut (ref $12)) (mut f32))))
-;; CHECK-NEXT: (type $3 (array_subtype (mut (ref null $8)) $0))
-;; CHECK-NEXT: (type $4 (array (mut i64)))
+;; CHECK: (type $0 (struct (field (mut i16) i31ref f32 f32 f64)))
+;; CHECK-NEXT: (type $1 (func (param f64 v128)))
+;; CHECK-NEXT: (type $2 (struct (field (mut (ref null $19)) f64 arrayref)))
+;; CHECK-NEXT: (type $3 (struct_subtype (field (mut i16) (ref i31) f32 f32 f64) $0))
+;; CHECK-NEXT: (type $4 (struct (field (mut (ref null $11)) (mut i8))))
;; CHECK-NEXT: (type $5 none)
-;; CHECK-NEXT: (type $6 extern)
-;; CHECK-NEXT: (type $7 (array_subtype (mut (ref null $8)) $3))
-;; CHECK-NEXT: (type $8 (func (result (ref $9))))
-;; CHECK-NEXT: (type $9 (struct_subtype (field (mut i64) (mut i8) (mut (ref $12)) (mut f32) i16) $2))
-;; CHECK-NEXT: (type $10 none)
-;; CHECK-NEXT: (type $11 none)
-;; CHECK-NEXT: (type $12 (struct_subtype (field (mut i64) (mut i8) (mut (ref $12)) (mut f32) (mut f32) (mut (ref $4))) $2))
-;; CHECK-NEXT: (type $13 (func (param dataref)))
-;; CHECK-NEXT: (type $14 (array_subtype (mut (ref null $8)) $7))
-;; CHECK-NEXT: (type $15 (func (param externref)))
-;; CHECK-NEXT: (type $16 (array v128))
-;; CHECK-NEXT: (type $17 (func (result (ref extern))))
-;; CHECK-NEXT: (type $18 (func (param v128 i64)))
-;; CHECK-NEXT: (type $19 (array_subtype (mut (ref null $8)) $3))
+;; CHECK-NEXT: (type $6 (array (ref null $18)))
+;; CHECK-NEXT: (type $7 (func_subtype (param f64 v128) $1))
+;; CHECK-NEXT: (type $8 (array (mut (ref null $19))))
+;; CHECK-NEXT: (type $9 (array (mut f64)))
+;; CHECK-NEXT: (type $10 (struct_subtype (field (mut i16) i31ref f32 f32 f64) $0))
+;; CHECK-NEXT: (type $11 (func (param i32 f64) (result (ref null $8))))
+;; CHECK-NEXT: (type $12 (func_subtype (param f64 v128) $1))
+;; CHECK-NEXT: (type $13 (func_subtype (param f64 v128) $12))
+;; CHECK-NEXT: (type $14 (func_subtype (param i32 f64) (result (ref null $8)) $11))
+;; CHECK-NEXT: (type $15 (func_subtype (param i32 f64) (result (ref null $8)) $14))
+;; CHECK-NEXT: (type $16 (func (result v128)))
+;; CHECK-NEXT: (type $17 (array f32))
+;; CHECK-NEXT: (type $18 (array i64))
+;; CHECK-NEXT: (type $19 (struct_subtype (field (mut i16) (ref none) f32 f32 f64 (ref $2)) $0))