;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: wasm-opt %s -all -o %t.text.wast -g -S ;; RUN: wasm-as %s -all -g -o %t.wasm ;; RUN: wasm-dis %t.wasm -all -o %t.bin.wast ;; RUN: wasm-as %s -all -o %t.nodebug.wasm ;; RUN: wasm-dis %t.nodebug.wasm -all -o %t.bin.nodebug.wast ;; RUN: cat %t.text.wast | filecheck %s --check-prefix=CHECK-TEXT ;; RUN: cat %t.bin.wast | filecheck %s --check-prefix=CHECK-BIN ;; RUN: cat %t.bin.nodebug.wast | filecheck %s --check-prefix=CHECK-BIN-NODEBUG ;; Test that we can roundtrip struct and array types (module ;; Arrays ;; CHECK-TEXT: (type $struct-rec-one (sub (struct (field (ref $struct-rec-one))))) ;; CHECK-TEXT: (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two))))) ;; CHECK-TEXT: (type $vector-i32 (array i32)) ;; CHECK-BIN: (type $struct-rec-one (sub (struct (field (ref $struct-rec-one))))) ;; CHECK-BIN: (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two))))) ;; CHECK-BIN: (type $vector-i32 (array i32)) (type $vector-i32 (array i32)) ;; CHECK-TEXT: (type $struct-any (sub (struct (field (ref any))))) ;; CHECK-TEXT: (type $struct-i31 (sub $struct-any (struct (field (ref i31))))) ;; CHECK-TEXT: (type $5 (func (param (ref $vector-i32) (ref null $vector-i32)))) ;; CHECK-TEXT: (type $vector-any (sub (array (ref any)))) ;; CHECK-BIN: (type $struct-any (sub (struct (field (ref any))))) ;; CHECK-BIN: (type $struct-i31 (sub $struct-any (struct (field (ref i31))))) ;; CHECK-BIN: (type $5 (func (param (ref $vector-i32) (ref null $vector-i32)))) ;; CHECK-BIN: (type $vector-any (sub (array (ref any)))) (type $vector-any (sub (array (ref any)))) ;; CHECK-TEXT: (type $vector-i31 (sub $vector-any (array (ref i31)))) ;; CHECK-BIN: (type $vector-i31 (sub $vector-any (array (ref i31)))) (type $vector-i31 (sub $vector-any (array (ref i31)))) ;; Structs (type $struct-any (sub (struct (field (ref any)) ))) (type $struct-i31 (sub $struct-any (struct (field (ref i31)) ))) ;; CHECK-TEXT: (type $8 (func (param (ref $vector-i31) (ref $vector-any)))) ;; CHECK-TEXT: (type $9 (func (param (ref $struct-i31) (ref $struct-any)))) ;; CHECK-TEXT: (type $struct-i31_any (sub $struct-i31 (struct (field (ref i31)) (field (ref any))))) ;; CHECK-BIN: (type $8 (func (param (ref $vector-i31) (ref $vector-any)))) ;; CHECK-BIN: (type $9 (func (param (ref $struct-i31) (ref $struct-any)))) ;; CHECK-BIN: (type $struct-i31_any (sub $struct-i31 (struct (field (ref i31)) (field (ref any))))) (type $struct-i31_any (sub $struct-i31(struct (field (ref i31)) (field (ref any)) ))) ;; Recursive structs (type $struct-rec-one (sub (struct (field (ref $struct-rec-one)) ))) (type $struct-rec-two (sub $struct-rec-one (struct (field (ref $struct-rec-two)) (field (ref $struct-rec-two)) ))) ;; CHECK-TEXT: (type $11 (func (param (ref $struct-i31) (ref $struct-i31_any)))) ;; CHECK-TEXT: (type $12 (func (param (ref $struct-rec-one) (ref $struct-rec-two)))) ;; CHECK-TEXT: (func $foo (type $5) (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) ;; CHECK-TEXT-NEXT: (local.set $yes-null ;; CHECK-TEXT-NEXT: (local.get $no-null) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (type $11 (func (param (ref $struct-i31) (ref $struct-i31_any)))) ;; CHECK-BIN: (type $12 (func (param (ref $struct-rec-one) (ref $struct-rec-two)))) ;; CHECK-BIN: (func $foo (type $5) (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) ;; CHECK-BIN-NEXT: (local.set $yes-null ;; CHECK-BIN-NEXT: (local.get $no-null) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $foo (param $no-null (ref $vector-i32)) (param $yes-null (ref null $vector-i32)) ;; ok to set a non-nullable reference to a nullable target (local.set $yes-null (local.get $no-null)) ) ;; CHECK-TEXT: (func $bar (type $8) (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) ;; CHECK-TEXT-NEXT: (local.set $v-any ;; CHECK-TEXT-NEXT: (local.get $v-i31) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $bar (type $8) (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) ;; CHECK-BIN-NEXT: (local.set $v-any ;; CHECK-BIN-NEXT: (local.get $v-i31) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $bar (param $v-i31 (ref $vector-i31)) (param $v-any (ref $vector-any)) ;; ok to set a vector of (immutable) i31s to a vector of anyies (local.set $v-any (local.get $v-i31)) ) ;; CHECK-TEXT: (func $baz (type $9) (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) ;; CHECK-TEXT-NEXT: (local.set $s-any ;; CHECK-TEXT-NEXT: (local.get $s-i31) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $baz (type $9) (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) ;; CHECK-BIN-NEXT: (local.set $s-any ;; CHECK-BIN-NEXT: (local.get $s-i31) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $baz (param $s-i31 (ref $struct-i31)) (param $s-any (ref $struct-any)) ;; ok to set a struct of an (immutable) i31 to a one of an any (local.set $s-any (local.get $s-i31)) ) ;; CHECK-TEXT: (func $boo (type $11) (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) ;; CHECK-TEXT-NEXT: (local.set $s-i31 ;; CHECK-TEXT-NEXT: (local.get $s-i31_any) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $boo (type $11) (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) ;; CHECK-BIN-NEXT: (local.set $s-i31 ;; CHECK-BIN-NEXT: (local.get $s-i31_any) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $boo (param $s-i31 (ref $struct-i31)) (param $s-i31_any (ref $struct-i31_any)) ;; also ok to have extra fields (local.set $s-i31 (local.get $s-i31_any)) ) ;; CHECK-TEXT: (func $coinductive (type $12) (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) ;; CHECK-TEXT-NEXT: (local.set $rec-one ;; CHECK-TEXT-NEXT: (local.get $rec-two) ;; CHECK-TEXT-NEXT: ) ;; CHECK-TEXT-NEXT: ) ;; CHECK-BIN: (func $coinductive (type $12) (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) ;; CHECK-BIN-NEXT: (local.set $rec-one ;; CHECK-BIN-NEXT: (local.get $rec-two) ;; CHECK-BIN-NEXT: ) ;; CHECK-BIN-NEXT: ) (func $coinductive (param $rec-one (ref $struct-rec-one)) (param $rec-two (ref $struct-rec-two)) ;; Do not infinitely recurse when determining this subtype relation! (local.set $rec-one (local.get $rec-two)) ) ) ;; CHECK-BIN-NODEBUG: (type $0 (sub (struct (field (ref $0))))) ;; CHECK-BIN-NODEBUG: (type $1 (sub $0 (struct (field (ref $1)) (field (ref $1))))) ;; CHECK-BIN-NODEBUG: (type $2 (array i32)) ;; CHECK-BIN-NODEBUG: (type $3 (sub (struct (field (ref any))))) ;; CHECK-BIN-NODEBUG: (type $4 (sub $3 (struct (field (ref i31))))) ;; CHECK-BIN-NODEBUG: (type $5 (func (param (ref $2) (ref null $2)))) ;; CHECK-BIN-NODEBUG: (type $6 (sub (array (ref any)))) ;; CHECK-BIN-NODEBUG: (type $7 (sub $6 (array (ref i31)))) ;; CHECK-BIN-NODEBUG: (type $8 (func (param (ref $7) (ref $6)))) ;; CHECK-BIN-NODEBUG: (type $9 (func (param (ref $4) (ref $3)))) ;; CHECK-BIN-NODEBUG: (type $10 (sub $4 (struct (field (ref i31)) (field (ref any))))) ;; CHECK-BIN-NODEBUG: (type $11 (func (param (ref $4) (ref $10)))) ;; CHECK-BIN-NODEBUG: (type $12 (func (param (ref $0) (ref $1)))) ;; CHECK-BIN-NODEBUG: (func $0 (type $5) (param $0 (ref $2)) (param $1 (ref null $2)) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $1 (type $8) (param $0 (ref $7)) (param $1 (ref $6)) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $2 (type $9) (param $0 (ref $4)) (param $1 (ref $3)) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $1 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $0) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $3 (type $11) (param $0 (ref $4)) (param $1 (ref $10)) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG: (func $4 (type $12) (param $0 (ref $0)) (param $1 (ref $1)) ;; CHECK-BIN-NODEBUG-NEXT: (local.set $0 ;; CHECK-BIN-NODEBUG-NEXT: (local.get $1) ;; CHECK-BIN-NODEBUG-NEXT: ) ;; CHECK-BIN-NODEBUG-NEXT: )