# 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 %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: