summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/gtest/type-builder.cpp32
-rw-r--r--test/lit/fuzz-types.test91
-rw-r--r--test/lit/isorecursive-good.wast46
-rw-r--r--test/lit/passes/type-merging.wast6
-rw-r--r--test/lit/passes/type-ssa.wast59
-rw-r--r--test/passes/translate-to-fuzz_all-features_metrics_noprint.txt78
6 files changed, 204 insertions, 108 deletions
diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp
index 0744e2b5e..1c30d9cb9 100644
--- a/test/gtest/type-builder.cpp
+++ b/test/gtest/type-builder.cpp
@@ -256,6 +256,22 @@ TEST_F(TypeTest, InvalidSupertype) {
EXPECT_EQ(error->index, 1u);
}
+TEST_F(TypeTest, InvalidFinalSupertype) {
+ TypeBuilder builder(2);
+ builder[0] = Struct{};
+ builder[1] = Struct{};
+ builder[0].setFinal();
+ builder[1].subTypeOf(builder[0]);
+
+ auto result = builder.build();
+ EXPECT_FALSE(result);
+
+ const auto* error = result.getError();
+ ASSERT_TRUE(error);
+ EXPECT_EQ(error->reason, TypeBuilder::ErrorReason::InvalidSupertype);
+ EXPECT_EQ(error->index, 1u);
+}
+
TEST_F(TypeTest, ForwardReferencedChild) {
TypeBuilder builder(3);
builder.createRecGroup(0, 2);
@@ -434,6 +450,22 @@ TEST_F(TypeTest, CanonicalizeSupertypes) {
EXPECT_NE(built[4], built[5]);
}
+TEST_F(TypeTest, CanonicalizeFinal) {
+ // Types are different if their finality flag is different.
+ TypeBuilder builder(2);
+ builder[0] = Struct{};
+ builder[1] = Struct{};
+ builder[0].setFinal();
+
+ auto result = builder.build();
+ ASSERT_TRUE(result);
+ auto built = *result;
+
+ EXPECT_NE(built[0], built[1]);
+ EXPECT_TRUE(built[0].isFinal());
+ EXPECT_FALSE(built[1].isFinal());
+}
+
TEST_F(TypeTest, HeapTypeConstructors) {
HeapType sig(Signature(Type::i32, Type::i32));
HeapType struct_(Struct({Field(Type(sig, Nullable), Mutable)}));
diff --git a/test/lit/fuzz-types.test b/test/lit/fuzz-types.test
index c1748e646..43a9947f2 100644
--- a/test/lit/fuzz-types.test
+++ b/test/lit/fuzz-types.test
@@ -1,66 +1,59 @@
-;; RUN: wasm-fuzz-types -v --seed=1 | filecheck %s
+;; RUN: wasm-fuzz-types -v --seed=0 | filecheck %s
-;; CHECK: (rec
-;; CHECK-NEXT: (type $0 (struct (field (mut (ref $1)) f64 v128 (mut (ref null $1)) (mut (ref null $0)) (ref $1))))
-;; CHECK-NEXT: (type $1 (struct (field (mut v128) (mut (ref null $1)) (mut i8) (mut i16) (mut i16))))
-;; CHECK-NEXT: )
-;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $2 (array (mut i16)))
-;; CHECK-NEXT: (type $3 (func))
-;; CHECK-NEXT: )
+;; CHECK: Built 20 types:
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $4 (func (param f32) (result f64)))
-;; CHECK-NEXT: (type $5 (array v128))
-;; CHECK-NEXT: (type $6 (array (mut (ref null $3))))
-;; CHECK-NEXT: (type $7 (func (param v128) (result f32)))
-;; CHECK-NEXT: (type $8 (struct_subtype (field (mut v128) (mut (ref null $1)) (mut i8) (mut i16) (mut i16) (mut i64)) $1))
+;; CHECK-NEXT: (type $0 (struct (field i32)))
+;; CHECK-NEXT: (type $1 (func (param (ref $2)) (result externref)))
+;; CHECK-NEXT: (type $2 (struct))
;; CHECK-NEXT: )
-;; CHECK-NEXT: (type $9 (func_subtype (param v128) (result f32) $7))
-;; CHECK-NEXT: (type $10 (struct_subtype (field (mut (ref $1)) f64 v128 (mut (ref null $1)) (mut (ref null $0)) (ref $1)) $0))
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $11 (struct))
-;; CHECK-NEXT: (type $12 (struct (field (mut i32) (mut i32) v128)))
+;; CHECK-NEXT: (type $3 (sub $0 (struct (field i32 (ref $5) (ref $5)))))
+;; CHECK-NEXT: (type $4 (sub final $3 (struct (field i32 (ref $5) (ref $5) i8 (ref null $13) (mut i64)))))
+;; CHECK-NEXT: (type $5 (array (mut f64)))
+;; CHECK-NEXT: (type $6 (sub final $1 (func (param anyref) (result externref))))
+;; CHECK-NEXT: (type $7 (sub $2 (struct (field (mut (ref null $14)) (ref $3)))))
+;; CHECK-NEXT: (type $8 (sub $1 (func (param (ref struct)) (result (ref extern)))))
+;; CHECK-NEXT: (type $9 (sub $5 (array (mut f64))))
+;; CHECK-NEXT: (type $10 (sub $8 (func (param (ref any)) (result (ref noextern)))))
+;; CHECK-NEXT: (type $11 (array (mut anyref)))
+;; CHECK-NEXT: (type $12 (sub $2 (struct (field (mut f64)))))
+;; CHECK-NEXT: (type $13 (sub $1 (func (param (ref $2)) (result (ref extern)))))
+;; CHECK-NEXT: (type $14 (array (mut (ref null $14))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $13 (func (param (ref null $4)) (result f32)))
-;; CHECK-NEXT: (type $14 (array_subtype (mut i16) $2))
-;; CHECK-NEXT: (type $15 (struct (field (mut v128) (ref extern) (mut (ref $15)))))
-;; CHECK-NEXT: (type $16 (struct_subtype (field (mut v128) (ref extern) (mut (ref $15))) $15))
-;; CHECK-NEXT: (type $17 (struct_subtype (field (mut (ref $1)) f64 v128 (mut (ref null $1)) (mut (ref null $0)) (ref $1)) $0))
-;; CHECK-NEXT: (type $18 (func_subtype (param f32) (result f64) $4))
+;; CHECK-NEXT: (type $15 (sub $11 (array (mut anyref))))
+;; CHECK-NEXT: (type $16 (sub $12 (struct (field (mut f64)))))
+;; CHECK-NEXT: (type $17 (sub final (struct (field f32 (mut i32) i8 (ref array)))))
+;; CHECK-NEXT: (type $18 (sub final $11 (array (mut anyref))))
+;; CHECK-NEXT: (type $19 (sub $9 (array (mut f64))))
;; CHECK-NEXT: )
-;; CHECK-NEXT: (type $19 (func (result v128)))
;; CHECK-NEXT:
;; CHECK-NEXT: Inhabitable types:
;; CHECK-NEXT:
;; CHECK-NEXT: Built 20 types:
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $0 (struct (field (mut (ref $1)) f64 v128 (mut (ref null $1)) (mut (ref null $0)) (ref $1))))
-;; CHECK-NEXT: (type $1 (struct (field (mut v128) (mut (ref null $1)) (mut i8) (mut i16) (mut i16))))
-;; CHECK-NEXT: )
-;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $2 (array (mut i16)))
-;; CHECK-NEXT: (type $3 (func))
-;; CHECK-NEXT: )
-;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $4 (func (param f32) (result f64)))
-;; CHECK-NEXT: (type $5 (array v128))
-;; CHECK-NEXT: (type $6 (array (mut (ref null $3))))
-;; CHECK-NEXT: (type $7 (func (param v128) (result f32)))
-;; CHECK-NEXT: (type $8 (struct_subtype (field (mut v128) (mut (ref null $1)) (mut i8) (mut i16) (mut i16) (mut i64)) $1))
+;; CHECK-NEXT: (type $0 (struct (field i32)))
+;; CHECK-NEXT: (type $1 (func (param (ref $2)) (result externref)))
+;; CHECK-NEXT: (type $2 (struct))
;; CHECK-NEXT: )
-;; CHECK-NEXT: (type $9 (func_subtype (param v128) (result f32) $7))
-;; CHECK-NEXT: (type $10 (struct_subtype (field (mut (ref $1)) f64 v128 (mut (ref null $1)) (mut (ref null $0)) (ref $1)) $0))
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $11 (struct))
-;; CHECK-NEXT: (type $12 (struct (field (mut i32) (mut i32) v128)))
+;; CHECK-NEXT: (type $3 (sub $0 (struct (field i32 (ref $5) (ref $5)))))
+;; CHECK-NEXT: (type $4 (sub final $3 (struct (field i32 (ref $5) (ref $5) i8 (ref null $13) (mut i64)))))
+;; CHECK-NEXT: (type $5 (array (mut f64)))
+;; CHECK-NEXT: (type $6 (sub final $1 (func (param anyref) (result externref))))
+;; CHECK-NEXT: (type $7 (sub $2 (struct (field (mut (ref null $14)) (ref $3)))))
+;; CHECK-NEXT: (type $8 (sub $1 (func (param (ref struct)) (result (ref extern)))))
+;; CHECK-NEXT: (type $9 (sub $5 (array (mut f64))))
+;; CHECK-NEXT: (type $10 (sub $8 (func (param (ref any)) (result (ref noextern)))))
+;; CHECK-NEXT: (type $11 (array (mut anyref)))
+;; CHECK-NEXT: (type $12 (sub $2 (struct (field (mut f64)))))
+;; CHECK-NEXT: (type $13 (sub $1 (func (param (ref $2)) (result (ref extern)))))
+;; CHECK-NEXT: (type $14 (array (mut (ref null $14))))
;; CHECK-NEXT: )
;; CHECK-NEXT: (rec
-;; CHECK-NEXT: (type $13 (func (param (ref null $4)) (result f32)))
-;; CHECK-NEXT: (type $14 (array_subtype (mut i16) $2))
-;; CHECK-NEXT: (type $15 (struct (field (mut v128) externref (mut (ref null $15)))))
-;; CHECK-NEXT: (type $16 (struct_subtype (field (mut v128) externref (mut (ref null $15))) $15))
-;; CHECK-NEXT: (type $17 (struct_subtype (field (mut (ref $1)) f64 v128 (mut (ref null $1)) (mut (ref null $0)) (ref $1)) $0))
-;; CHECK-NEXT: (type $18 (func_subtype (param f32) (result f64) $4))
+;; CHECK-NEXT: (type $15 (sub $11 (array (mut anyref))))
+;; CHECK-NEXT: (type $16 (sub $12 (struct (field (mut f64)))))
+;; CHECK-NEXT: (type $17 (sub final (struct (field f32 (mut i32) i8 (ref array)))))
+;; CHECK-NEXT: (type $18 (sub final $11 (array (mut anyref))))
+;; CHECK-NEXT: (type $19 (sub $9 (array (mut f64))))
;; CHECK-NEXT: )
-;; CHECK-NEXT: (type $19 (func (result v128)))
diff --git a/test/lit/isorecursive-good.wast b/test/lit/isorecursive-good.wast
index 8e15d3190..1d5e9c7df 100644
--- a/test/lit/isorecursive-good.wast
+++ b/test/lit/isorecursive-good.wast
@@ -7,66 +7,82 @@
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $super-struct (struct (field i32)))
- (type $super-struct (struct i32))
+ (type $super-struct (sub (struct i32)))
;; CHECK: (type $sub-struct (sub $super-struct (struct (field i32) (field i64))))
(type $sub-struct (sub $super-struct (struct i32 i64)))
+ ;; CHECK: (type $final-struct (sub final $sub-struct (struct (field i32) (field i64) (field f32))))
+ (type $final-struct (sub final $sub-struct (struct i32 i64 f32)))
)
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $super-array (array (ref $super-struct)))
- (type $super-array (array (ref $super-struct)))
+ (type $super-array (sub (array (ref $super-struct))))
;; CHECK: (type $sub-array (sub $super-array (array (ref $sub-struct))))
(type $sub-array (sub $super-array (array (ref $sub-struct))))
+ ;; CHECK: (type $final-array (sub final $sub-array (array (ref $final-struct))))
+ (type $final-array (sub final $sub-array (array (ref $final-struct))))
)
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $super-func (func (param (ref $sub-array)) (result (ref $super-array))))
- (type $super-func (func (param (ref $sub-array)) (result (ref $super-array))))
+ (type $super-func (sub (func (param (ref $sub-array)) (result (ref $super-array)))))
;; CHECK: (type $sub-func (sub $super-func (func (param (ref $super-array)) (result (ref $sub-array)))))
(type $sub-func (sub $super-func (func (param (ref $super-array)) (result (ref $sub-array)))))
+ ;; CHECK: (type $final-func (sub final $sub-func (func (param (ref $super-array)) (result (ref $final-array)))))
+ (type $final-func (sub final $sub-func (func (param (ref $super-array)) (result (ref $final-array)))))
)
+ ;; CHECK: (type $final-root (sub final (struct )))
+ (type $final-root (sub final (struct)))
+
;; CHECK: (func $make-super-struct (type $none_=>_ref|$super-struct|) (result (ref $super-struct))
- ;; CHECK-NEXT: (call $make-sub-struct)
+ ;; CHECK-NEXT: (call $make-final-struct)
;; CHECK-NEXT: )
(func $make-super-struct (result (ref $super-struct))
- (call $make-sub-struct)
+ (call $make-final-struct)
)
- ;; CHECK: (func $make-sub-struct (type $none_=>_ref|$sub-struct|) (result (ref $sub-struct))
+ ;; CHECK: (func $make-final-struct (type $none_=>_ref|$final-struct|) (result (ref $final-struct))
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
- (func $make-sub-struct (result (ref $sub-struct))
+ (func $make-final-struct (result (ref $final-struct))
(unreachable)
)
;; CHECK: (func $make-super-array (type $none_=>_ref|$super-array|) (result (ref $super-array))
- ;; CHECK-NEXT: (call $make-sub-array)
+ ;; CHECK-NEXT: (call $make-final-array)
;; CHECK-NEXT: )
(func $make-super-array (result (ref $super-array))
- (call $make-sub-array)
+ (call $make-final-array)
)
- ;; CHECK: (func $make-sub-array (type $none_=>_ref|$sub-array|) (result (ref $sub-array))
+ ;; CHECK: (func $make-final-array (type $none_=>_ref|$final-array|) (result (ref $final-array))
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
- (func $make-sub-array (result (ref $sub-array))
+ (func $make-final-array (result (ref $final-array))
(unreachable)
)
;; CHECK: (func $make-super-func (type $none_=>_ref|$super-func|) (result (ref $super-func))
- ;; CHECK-NEXT: (call $make-sub-func)
+ ;; CHECK-NEXT: (call $make-final-func)
;; CHECK-NEXT: )
(func $make-super-func (result (ref $super-func))
- (call $make-sub-func)
+ (call $make-final-func)
+ )
+
+ ;; CHECK: (func $make-final-func (type $none_=>_ref|$final-func|) (result (ref $final-func))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $make-final-func (result (ref $final-func))
+ (unreachable)
)
- ;; CHECK: (func $make-sub-func (type $none_=>_ref|$sub-func|) (result (ref $sub-func))
+ ;; CHECK: (func $make-final-root (type $none_=>_ref|$final-root|) (result (ref $final-root))
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
- (func $make-sub-func (result (ref $sub-func))
+ (func $make-final-root (result (ref $final-root))
(unreachable)
)
)
diff --git a/test/lit/passes/type-merging.wast b/test/lit/passes/type-merging.wast
index 639810886..37d5337ac 100644
--- a/test/lit/passes/type-merging.wast
+++ b/test/lit/passes/type-merging.wast
@@ -7,6 +7,8 @@
;; CHECK-NEXT: (type $A (struct (field anyref)))
(type $A (struct_subtype (field anyref) data))
(type $B (struct_subtype (field anyref) $A))
+ ;; CHECK: (type $G (sub final $A (struct (field anyref))))
+
;; CHECK: (type $F (sub $A (struct (field anyref))))
;; CHECK: (type $E (sub $A (struct (field eqref))))
@@ -18,6 +20,7 @@
(type $D (struct_subtype (field (ref any)) $A))
(type $E (struct_subtype (field eqref) $A))
(type $F (struct_subtype (field anyref) $A))
+ (type $G (sub final $A (struct (field anyref))))
)
;; CHECK: (type $none_=>_none (func))
@@ -29,6 +32,7 @@
;; CHECK-NEXT: (local $d (ref null $D))
;; CHECK-NEXT: (local $e (ref null $E))
;; CHECK-NEXT: (local $f (ref null $F))
+ ;; CHECK-NEXT: (local $g (ref null $G))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast null $A
;; CHECK-NEXT: (local.get $a)
@@ -53,6 +57,8 @@
(local $e (ref null $E))
;; $F cannot because it has a cast.
(local $f (ref null $F))
+ ;; $G cannot because it changes finality.
+ (local $g (ref null $G))
;; A cast of $A has no effect.
(drop
diff --git a/test/lit/passes/type-ssa.wast b/test/lit/passes/type-ssa.wast
index 1ed55ff7d..6980cb46e 100644
--- a/test/lit/passes/type-ssa.wast
+++ b/test/lit/passes/type-ssa.wast
@@ -74,6 +74,65 @@
)
)
+;; The same module as before, except that now the type is final, so we cannot
+;; create any subtypes.
+(module
+ ;; CHECK: (type $struct (sub final (struct (field i32))))
+ (type $struct (sub final (struct (field i32))))
+
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (global $g (ref $struct) (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $g (ref $struct) (struct.new $struct
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (global $h (ref $struct) (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $h (ref $struct) (struct.new $struct
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (func $foo (type $none_=>_none)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.new_default $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 10)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo
+ (drop
+ (struct.new_default $struct)
+ )
+ (drop
+ (struct.new $struct
+ (i32.const 10)
+ )
+ )
+ )
+
+ ;; CHECK: (func $another-func (type $none_=>_none)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 100)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $another-func
+ (drop
+ (struct.new $struct
+ (i32.const 100)
+ )
+ )
+ )
+)
+
;; Some of these are uninteresting and should not get a new type.
(module
diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
index b5efc4c85..11da6a35b 100644
--- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
+++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
@@ -1,50 +1,40 @@
total
- [exports] : 9
- [funcs] : 16
- [globals] : 16
+ [exports] : 3
+ [funcs] : 6
+ [globals] : 1
[imports] : 5
[memories] : 1
[memory-data] : 20
- [table-data] : 2
+ [table-data] : 0
[tables] : 1
- [tags] : 1
- [total] : 666
- [vars] : 32
- ArrayFill : 1
- ArrayLen : 1
- ArrayNew : 7
- ArrayNewFixed : 3
- AtomicCmpxchg : 1
- AtomicFence : 2
- AtomicNotify : 1
- Binary : 81
- Block : 84
- Break : 8
- Call : 23
- Const : 152
- Drop : 6
- GlobalGet : 40
- GlobalSet : 38
- I31Get : 1
- I31New : 3
- If : 29
- Load : 19
- LocalGet : 39
- LocalSet : 20
- Loop : 5
- Nop : 9
- RefAs : 5
- RefEq : 2
- RefFunc : 6
- RefIsNull : 2
- RefNull : 9
+ [tags] : 2
+ [total] : 463
+ [vars] : 19
+ ArrayCopy : 1
+ ArrayLen : 6
+ ArrayNew : 8
+ ArraySet : 1
+ AtomicFence : 1
+ Binary : 79
+ Block : 49
+ Break : 5
+ Call : 7
+ CallRef : 2
+ Const : 96
+ Drop : 2
+ GlobalGet : 20
+ GlobalSet : 20
+ If : 17
+ Load : 18
+ LocalGet : 44
+ LocalSet : 34
+ Loop : 6
+ Nop : 6
+ RefAs : 3
+ RefFunc : 2
+ RefNull : 3
Return : 4
- Select : 1
- Store : 4
- StructGet : 1
- StructNew : 10
- Try : 2
- TupleExtract : 1
- TupleMake : 3
- Unary : 23
- Unreachable : 20
+ Store : 2
+ StructNew : 1
+ Unary : 14
+ Unreachable : 12