blob: 1fd470ff8229ad9695bed07d405d3da5d12ccab8 [file] [log] [blame] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt -all --preserve-type-order --string-lowering -S -o - | filecheck %s
(module
(rec
;; CHECK: (type $0 (func))
;; CHECK: (type $1 (array (mut i16)))
;; CHECK: (rec
;; CHECK-NEXT: (type $struct-of-string (struct (field externref) (field i32) (field anyref)))
(type $struct-of-string (struct (field stringref) (field i32) (field anyref)))
;; CHECK: (type $struct-of-array (struct (field (ref $1))))
(type $struct-of-array (struct (field (ref $array16))))
;; CHECK: (type $array16-imm (array i32))
(type $array16-imm (array i32))
;; CHECK: (type $array32 (array (mut i32)))
(type $array32 (array (mut i32)))
;; CHECK: (type $array16-open (sub (array (mut i16))))
(type $array16-open (sub (array (mut i16))))
;; CHECK: (type $array16-child (sub $array16-open (array (mut i16))))
(type $array16-child (sub $array16-open (array (mut i16))))
;; CHECK: (type $array16 (array (mut i16)))
(type $array16 (array (mut i16)))
)
;; CHECK: (type $9 (func (param (ref $1))))
;; CHECK: (type $10 (func (param externref externref) (result (ref extern))))
;; CHECK: (type $11 (func (param externref (ref $1)) (result i32)))
;; CHECK: (type $12 (func (param externref externref) (result i32)))
;; CHECK: (type $13 (func (param externref) (result i32)))
;; CHECK: (type $14 (func (param externref) (result externref)))
;; CHECK: (type $15 (func (param externref)))
;; CHECK: (type $16 (func (result externref)))
;; CHECK: (type $17 (func (param externref externref) (result i32)))
;; CHECK: (type $18 (func (param externref i32 externref)))
;; CHECK: (type $19 (func (param (ref null $1) i32 i32) (result (ref extern))))
;; CHECK: (type $20 (func (param i32) (result (ref extern))))
;; CHECK: (type $21 (func (param externref externref) (result (ref extern))))
;; CHECK: (type $22 (func (param externref (ref null $1) i32) (result i32)))
;; CHECK: (type $23 (func (param externref) (result i32)))
;; CHECK: (type $24 (func (param externref i32) (result i32)))
;; CHECK: (type $25 (func (param externref i32 i32) (result (ref extern))))
;; CHECK: (import "string.const" "0" (global $"string.const_\"exported\"" (ref extern)))
;; CHECK: (import "string.const" "1" (global $"string.const_\"value\"" (ref extern)))
;; CHECK: (import "colliding" "name" (func $fromCodePoint (type $0)))
(import "colliding" "name" (func $fromCodePoint))
;; CHECK: (import "wasm:js-string" "fromCharCodeArray" (func $fromCharCodeArray (type $19) (param (ref null $1) i32 i32) (result (ref extern))))
;; CHECK: (import "wasm:js-string" "fromCodePoint" (func $fromCodePoint_18 (type $20) (param i32) (result (ref extern))))
;; CHECK: (import "wasm:js-string" "concat" (func $concat (type $21) (param externref externref) (result (ref extern))))
;; CHECK: (import "wasm:js-string" "intoCharCodeArray" (func $intoCharCodeArray (type $22) (param externref (ref null $1) i32) (result i32)))
;; CHECK: (import "wasm:js-string" "equals" (func $equals (type $17) (param externref externref) (result i32)))
;; CHECK: (import "wasm:js-string" "compare" (func $compare (type $17) (param externref externref) (result i32)))
;; CHECK: (import "wasm:js-string" "length" (func $length (type $23) (param externref) (result i32)))
;; CHECK: (import "wasm:js-string" "charCodeAt" (func $charCodeAt (type $24) (param externref i32) (result i32)))
;; CHECK: (import "wasm:js-string" "substring" (func $substring (type $25) (param externref i32 i32) (result (ref extern))))
;; CHECK: (global $string externref (ref.null noextern))
(global $string stringref (ref.null string)) ;; Test we update global nulls.
;; CHECK: (export "export.1" (func $exported-string-returner))
;; CHECK: (export "export.2" (func $exported-string-receiver))
;; CHECK: (func $string.new.gc (type $9) (param $array16 (ref $1))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $fromCharCodeArray
;; CHECK-NEXT: (local.get $array16)
;; CHECK-NEXT: (i32.const 7)
;; CHECK-NEXT: (i32.const 8)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.new.gc (param $array16 (ref $array16))
(drop
(string.new_wtf16_array
(local.get $array16)
(i32.const 7)
(i32.const 8)
)
)
)
;; CHECK: (func $string.from_code_point (type $16) (result externref)
;; CHECK-NEXT: (call $fromCodePoint_18
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.from_code_point (result stringref)
(string.from_code_point
(i32.const 1)
)
)
;; CHECK: (func $string.concat (type $10) (param $0 externref) (param $1 externref) (result (ref extern))
;; CHECK-NEXT: (call $concat
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.concat (param stringref stringref) (result (ref string))
(string.concat
(local.get 0)
(local.get 1)
)
)
;; CHECK: (func $string.encode (type $11) (param $ref externref) (param $array16 (ref $1)) (result i32)
;; CHECK-NEXT: (call $intoCharCodeArray
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: (local.get $array16)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.encode (param $ref stringref) (param $array16 (ref $array16)) (result i32)
(string.encode_wtf16_array
(local.get $ref)
(local.get $array16)
(i32.const 10)
)
)
;; CHECK: (func $string.eq (type $12) (param $a externref) (param $b externref) (result i32)
;; CHECK-NEXT: (call $equals
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: (local.get $b)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.eq (param $a stringref) (param $b stringref) (result i32)
(string.eq
(local.get $a)
(local.get $b)
)
)
;; CHECK: (func $string.compare (type $12) (param $a externref) (param $b externref) (result i32)
;; CHECK-NEXT: (call $compare
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: (local.get $b)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.compare (param $a stringref) (param $b stringref) (result i32)
(string.compare
(local.get $a)
(local.get $b)
)
)
;; CHECK: (func $string.length (type $13) (param $ref externref) (result i32)
;; CHECK-NEXT: (call $length
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.length (param $ref stringref) (result i32)
(string.measure_wtf16
(local.get $ref)
)
)
;; CHECK: (func $string.get_codeunit (type $13) (param $ref externref) (result i32)
;; CHECK-NEXT: (call $charCodeAt
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.get_codeunit (param $ref stringref) (result i32)
(stringview_wtf16.get_codeunit
(local.get $ref)
(i32.const 2)
)
)
;; CHECK: (func $string.slice (type $14) (param $ref externref) (result externref)
;; CHECK-NEXT: (call $substring
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: (i32.const 3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $string.slice (param $ref stringref) (result stringref)
(stringview_wtf16.slice
(local.get $ref)
(i32.const 2)
(i32.const 3)
)
)
;; CHECK: (func $if.string (type $14) (param $ref externref) (result externref)
;; CHECK-NEXT: (if (result externref)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (then
;; CHECK-NEXT: (ref.null noextern)
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if.string (param $ref stringref) (result stringref)
(if (result stringref)
(i32.const 0)
(then
(ref.null none) ;; this will turn into noextern
)
(else
(local.get $ref)
)
)
)
;; CHECK: (func $if.string.flip (type $14) (param $ref externref) (result externref)
;; CHECK-NEXT: (if (result externref)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (then
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (ref.null noextern)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if.string.flip (param $ref stringref) (result stringref)
;; As above but with flipped arms.
(if (result stringref)
(i32.const 0)
(then
(local.get $ref)
)
(else
(ref.null none)
)
)
)
;; CHECK: (func $exported-string-returner (type $16) (result externref)
;; CHECK-NEXT: (global.get $"string.const_\"exported\"")
;; CHECK-NEXT: )
(func $exported-string-returner (export "export.1") (result stringref)
;; We should update the signature of this function even though it is public
;; (exported).
(string.const "exported")
)
;; CHECK: (func $exported-string-receiver (type $18) (param $x externref) (param $y i32) (param $z externref)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $z)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $exported-string-receiver (export "export.2") (param $x stringref) (param $y i32) (param $z stringref)
;; We should update the signature of this function even though it is public
;; (exported).
(drop
(local.get $x)
)
(drop
(local.get $y)
)
(drop
(local.get $z)
)
)
;; CHECK: (func $use-struct-of-array (type $0)
;; CHECK-NEXT: (local $array16 (ref $1))
;; CHECK-NEXT: (local $open (ref $array16-open))
;; CHECK-NEXT: (local $child (ref $array16-child))
;; CHECK-NEXT: (local $32 (ref $array32))
;; CHECK-NEXT: (local $imm (ref $array16-imm))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $fromCharCodeArray
;; CHECK-NEXT: (struct.get $struct-of-array 0
;; CHECK-NEXT: (struct.new $struct-of-array
;; CHECK-NEXT: (array.new_fixed $1 2
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $use-struct-of-array
;; The array type here should switch to the new 16-bit array type that we
;; use for the new imports, so that it is compatible with them. Without
;; that, calling the import as we do below will fail.
(local $array16 (ref $array16))
;; In comparison, the array16-open param should remain as it is: it is an
;; open type which is different then the one we care about.
(local $open (ref $array16-open))
;; Likewise a child of that open type is also ignored.
(local $child (ref $array16-child))
;; Another array size is also ignored.
(local $32 (ref $array32))
;; An immutable array is also ignored.
(local $imm (ref $array16-imm))
(drop
(string.new_wtf16_array
(struct.get $struct-of-array 0
(struct.new $struct-of-array
(array.new_fixed $array16 2
(i32.const 10)
(i32.const 20)
)
)
)
(i32.const 0)
(i32.const 1)
)
)
)
;; CHECK: (func $struct-of-string (type $0)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct-of-string
;; CHECK-NEXT: (ref.null noextern)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct-of-string
;; CHECK-NEXT: (global.get $"string.const_\"value\"")
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct-of-string)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $struct-of-string
;; Test lowering of struct fields from stringref to externref.
(drop
(struct.new $struct-of-string
(ref.null none) ;; This null must be fixed to be ext.
(i32.const 10)
(ref.null none) ;; Nothing to do here (field remains anyref).
)
)
(drop
(struct.new $struct-of-string
(string.const "value") ;; Nothing to do besides change to a global.
(i32.const 10)
(ref.null none)
)
)
(drop
(struct.new_default $struct-of-string) ;; Nothing to do here.
)
)
;; CHECK: (func $call-param-null (type $15) (param $str externref)
;; CHECK-NEXT: (call $call-param-null
;; CHECK-NEXT: (ref.null noextern)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $call-param-null (param $str stringref)
;; After the lowering this null must be an ext.
(call $call-param-null
(ref.null string)
)
)
)