summaryrefslogtreecommitdiff
path: root/test/lit/binary/stacky-nn-tuple.test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-03-31 10:48:43 -0700
committerGitHub <noreply@github.com>2022-03-31 10:48:43 -0700
commit33fe4f12bd30739790da3d34f5fae844f47a327f (patch)
tree5c131f3bc288b3f637255628a4f476946245eb57 /test/lit/binary/stacky-nn-tuple.test
parent1d24b83eaf710510c132091db89715607d64eea7 (diff)
downloadbinaryen-33fe4f12bd30739790da3d34f5fae844f47a327f.tar.gz
binaryen-33fe4f12bd30739790da3d34f5fae844f47a327f.tar.bz2
binaryen-33fe4f12bd30739790da3d34f5fae844f47a327f.zip
[Wasm GC] Fix stacky non-nullable tuples (#4561)
#4555 fixed validation for such tuples, but we also did not handle them in "stacky" code using pops etc., due to a logic bug in the binary reading code.
Diffstat (limited to 'test/lit/binary/stacky-nn-tuple.test')
-rw-r--r--test/lit/binary/stacky-nn-tuple.test112
1 files changed, 112 insertions, 0 deletions
diff --git a/test/lit/binary/stacky-nn-tuple.test b/test/lit/binary/stacky-nn-tuple.test
new file mode 100644
index 000000000..41abc1d7d
--- /dev/null
+++ b/test/lit/binary/stacky-nn-tuple.test
@@ -0,0 +1,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: