1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
# Verify stacky non-nullable tuples binary can be parsed correctly. The wasm
# contains code that uses pops to get a tuple and store it in a local, then
# reads those values. The file contains this:
#
# (module
# (type $A (struct (field (mut i32))))
# (type $B (struct (field (mut i32)) (field (mut i32))))
# (tag $tag$0 (param (ref $A) (ref $B)))
# (func $foo
# (local $temp ((ref null $A) (ref null $B)))
# (try $label$3
# (do
# (nop)
# )
# (catch $tag$0
# (local.set $temp
# (pop (ref $A) (ref $B))
# )
# (drop
# (ref.as_non_null
# (tuple.extract 0
# (local.get $temp)
# )
# )
# )
# (drop
# (ref.as_non_null
# (tuple.extract 1
# (local.get $temp)
# )
# )
# )
# (unreachable)
# )
# )
# )
# )
RUN: wasm-opt -all --enable-gc-nn-locals %s.wasm -all --print
# CHECK: (module
# CHECK-NEXT: (type ${mut:i32} (struct (field (mut i32))))
# CHECK-NEXT: (type ${mut:i32_mut:i32} (struct (field (mut i32)) (field (mut i32))))
# CHECK-NEXT: (type $ref|{mut:i32}|_ref|{mut:i32_mut:i32}|_=>_none (func (param (ref ${mut:i32}) (ref ${mut:i32_mut:i32}))))
# CHECK-NEXT: (type $none_=>_none (func))
# CHECK-NEXT: (tag $tag$0 (param (ref ${mut:i32}) (ref ${mut:i32_mut:i32})))
# CHECK-NEXT: (func $0
# CHECK-NEXT: (local $0 (ref null ${mut:i32}))
# CHECK-NEXT: (local $1 (ref null ${mut:i32_mut:i32}))
# CHECK-NEXT: (local $2 (ref null ${mut:i32_mut:i32}))
# CHECK-NEXT: (local $3 ((ref ${mut:i32}) (ref ${mut:i32_mut:i32})))
# CHECK-NEXT: (local $4 (ref ${mut:i32}))
# CHECK-NEXT: (local $5 (ref null ${mut:i32}))
# CHECK-NEXT: (local $6 (ref null ${mut:i32}))
# CHECK-NEXT: (try $label$3
# CHECK-NEXT: (do
# CHECK-NEXT: (nop)
# CHECK-NEXT: )
# CHECK-NEXT: (catch $tag$0
# CHECK-NEXT: (local.set $3
# CHECK-NEXT: (pop (ref ${mut:i32}) (ref ${mut:i32_mut:i32}))
# CHECK-NEXT: )
# CHECK-NEXT: (local.set $0
# CHECK-NEXT: (block (result (ref ${mut:i32}))
# CHECK-NEXT: (local.set $4
# CHECK-NEXT: (tuple.extract 0
# CHECK-NEXT: (local.get $3)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: (local.set $1
# CHECK-NEXT: (tuple.extract 1
# CHECK-NEXT: (local.get $3)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: (local.get $4)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: (drop
# CHECK-NEXT: (ref.as_non_null
# CHECK-NEXT: (block (result (ref null ${mut:i32}))
# CHECK-NEXT: (local.set $5
# CHECK-NEXT: (local.get $0)
# CHECK-NEXT: )
# CHECK-NEXT: (drop
# CHECK-NEXT: (local.get $1)
# CHECK-NEXT: )
# CHECK-NEXT: (local.get $5)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: (drop
# CHECK-NEXT: (block (result (ref null ${mut:i32}))
# CHECK-NEXT: (local.set $6
# CHECK-NEXT: (local.get $0)
# CHECK-NEXT: )
# CHECK-NEXT: (local.set $2
# CHECK-NEXT: (local.get $1)
# CHECK-NEXT: )
# CHECK-NEXT: (local.get $6)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: (drop
# CHECK-NEXT: (ref.as_non_null
# CHECK-NEXT: (local.get $2)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: (unreachable)
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT: )
# CHECK-NEXT:
|