diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/example/type-builder.cpp | 39 | ||||
-rw-r--r-- | test/example/type-builder.txt | 51 | ||||
-rw-r--r-- | test/lit/passes/roundtrip-gc-types.wast | 27 |
3 files changed, 113 insertions, 4 deletions
diff --git a/test/example/type-builder.cpp b/test/example/type-builder.cpp index a228697e9..8d87c5054 100644 --- a/test/example/type-builder.cpp +++ b/test/example/type-builder.cpp @@ -103,6 +103,32 @@ void test_canonicalization() { assert(built[3] == sig); } +// Check that defined basic HeapTypes are handled correctly. +void test_basic() { + std::cout << ";; Test basic\n"; + + TypeBuilder builder(6); + + Type anyref = builder.getTempRefType(builder[4], Nullable); + Type i31ref = builder.getTempRefType(builder[5], NonNullable); + + builder[0] = Signature(Type::anyref, Type::i31ref); + builder[1] = Signature(anyref, Type::i31ref); + builder[2] = Signature(Type::anyref, i31ref); + builder[3] = Signature(anyref, i31ref); + builder[4] = HeapType::any; + builder[5] = HeapType::i31; + + std::vector<HeapType> built = builder.build(); + + assert(built[0] == HeapType(Signature(Type::anyref, Type::i31ref))); + assert(built[1] == built[0]); + assert(built[2] == built[1]); + assert(built[3] == built[2]); + assert(built[4] == HeapType::any); + assert(built[5] == HeapType::i31); +} + void test_recursive() { std::cout << ";; Test recursive types\n"; @@ -467,8 +493,13 @@ void test_lub() { } int main() { - test_builder(); - test_canonicalization(); - test_recursive(); - test_lub(); + // Run the tests twice to ensure things still work when the global stores are + // already populated. + for (size_t i = 0; i < 2; ++i) { + test_builder(); + test_canonicalization(); + test_basic(); + test_recursive(); + test_lub(); + } } diff --git a/test/example/type-builder.txt b/test/example/type-builder.txt index d9f469461..a219816e6 100644 --- a/test/example/type-builder.txt +++ b/test/example/type-builder.txt @@ -21,6 +21,57 @@ After building types: (rtt 0 $array) => (rtt 0 (array (mut externref))) ;; Test canonicalization +;; Test basic +;; Test recursive types +(func (result (ref null ...1))) + +(func (result (ref null ...1))) +(func (result (ref null ...1))) + +(func (result (ref null ...1))) +(func (result (ref null ...1))) +(func (result (ref null ...1))) +(func (result (ref null ...1))) +(func (result (ref null ...1))) + +(func (result (ref null ...1) (ref null (func)))) +(func (result (ref null ...1) (ref null (func)))) +(func) +(func) +(func (result (ref null (func (result ...1 (ref null (func))))))) +(func (result (ref null (func (result ...1 (ref null (func))))))) + +(func (result (ref null ...1))) +(func (result (ref null ...1))) + +(func (param anyref) (result (ref null ...1))) +(func (param anyref) (result (ref null ...1))) + +;; Test LUBs +;; Test TypeBuilder +Before setting heap types: +(ref $sig) => [T](ref [T](func)) +(ref $struct) => [T](ref [T](func)) +(ref $array) => [T](ref [T](func)) +(ref null $array) => [T](ref null [T](func)) +(rtt 0 $array) => [T](rtt 0 [T](func)) + +After setting heap types: +(ref $sig) => [T](ref [T](func (param [T](ref [T](struct (field [T](ref null [T](array (mut externref))) (mut [T](rtt 0 [T](array (mut externref)))))))) (result [T](ref [T](array (mut externref))) i32))) +(ref $struct) => [T](ref [T](struct (field [T](ref null [T](array (mut externref))) (mut [T](rtt 0 [T](array (mut externref))))))) +(ref $array) => [T](ref [T](array (mut externref))) +(ref null $array) => [T](ref null [T](array (mut externref))) +(rtt 0 $array) => [T](rtt 0 [T](array (mut externref))) + +After building types: +(ref $sig) => (ref (func (param (ref (struct (field (ref null (array (mut externref))) (mut (rtt 0 (array (mut externref)))))))) (result (ref (array (mut externref))) i32))) +(ref $struct) => (ref (struct (field (ref null (array (mut externref))) (mut (rtt 0 (array (mut externref))))))) +(ref $array) => (ref (array (mut externref))) +(ref null $array) => (ref null (array (mut externref))) +(rtt 0 $array) => (rtt 0 (array (mut externref))) + +;; Test canonicalization +;; Test basic ;; Test recursive types (func (result (ref null ...1))) diff --git a/test/lit/passes/roundtrip-gc-types.wast b/test/lit/passes/roundtrip-gc-types.wast new file mode 100644 index 000000000..449df6639 --- /dev/null +++ b/test/lit/passes/roundtrip-gc-types.wast @@ -0,0 +1,27 @@ +;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s + +;; Regression test for an issue in which roundtripping failed to reproduce the +;; original types because type canonicalization was incorrect when the canonical +;; types already existed in the store. + +;; CHECK: (module +;; CHECK-NEXT: (type $A (struct (field (ref $C)))) +;; CHECK-NEXT: (type $B (func (param (ref $A)) (result (ref $B)))) +;; CHECK-NEXT: (type $C (struct (field (mut (ref $B))))) +;; CHECK-NEXT: (type $D (struct (field (ref $C)) (field (ref $A)))) +;; CHECK-NEXT: (global $g0 (rtt 0 $A) (rtt.canon $A)) +;; CHECK-NEXT: (global $g1 (rtt 1 $D) (rtt.sub $D +;; CHECK-NEXT: (global.get $g0) +;; CHECK-NEXT: )) +;; CHECK-NEXT: ) + +(module + (type $A (struct (field (ref $C)))) + (type $B (func (param (ref $A)) (result (ref $B)))) + (type $C (struct (field (mut (ref $B))))) + (type $D (struct (field (ref $C)) (field (ref $A)))) + (global $g0 (rtt 0 $A) (rtt.canon $A)) + (global $g1 (rtt 1 $D) (rtt.sub $D + (global.get $g0) + )) +) |