diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-07-28 12:00:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-28 19:00:11 +0000 |
commit | 8670f15676b3c6406d6e82327a7258c7c4d08b43 (patch) | |
tree | 59338a9debe510a297b90dd7d51eedf209010f02 /test | |
parent | be580c66645cdea13c8e8b3b77f12ef3a52e5f2e (diff) | |
download | binaryen-8670f15676b3c6406d6e82327a7258c7c4d08b43.tar.gz binaryen-8670f15676b3c6406d6e82327a7258c7c4d08b43.tar.bz2 binaryen-8670f15676b3c6406d6e82327a7258c7c4d08b43.zip |
Support subtyping in tail calls (#4032)
The tail call spec does not include subtyping because it is based on the
upstream spec, which does not contain subtyping. However, there is no reason
that subtyping shouldn't apply to tail calls like it does for any other call or
return. Update the validator to allow subtyping and avoid a related null pointer
dereference while we're at it.
Do not run the test in with --nominal because it is buggy in that mode.
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/tail-call.wast | 78 | ||||
-rw-r--r-- | test/tail-call.wast | 11 |
2 files changed, 78 insertions, 11 deletions
diff --git a/test/lit/tail-call.wast b/test/lit/tail-call.wast new file mode 100644 index 000000000..92dfdbb4e --- /dev/null +++ b/test/lit/tail-call.wast @@ -0,0 +1,78 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; Check that tail calls are parsed, validated, and printed correctly + +;; RUN: foreach %s %t wasm-opt -all -S -o - | filecheck %s +;; TODO: --nominal as well + +(module + + ;; CHECK: (type $void (func)) + (type $void (func)) + + ;; CHECK: (table $t 1 1 funcref) + (table $t 1 1 funcref) + + ;; CHECK: (elem $e (i32.const 0) $foo) + (elem $e (i32.const 0) $foo) + + ;; CHECK: (func $foo + ;; CHECK-NEXT: (return_call $bar) + ;; CHECK-NEXT: ) + (func $foo + (return_call $bar) + ) + + ;; CHECK: (func $bar + ;; CHECK-NEXT: (return_call_indirect $t (type $void) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $bar + (return_call_indirect (type $void) (i32.const 0)) + ) +) + +;; Check GC types and subtyping +(module + ;; CHECK: (type $return-B (func (result (ref $B)))) + (type $return-B (func (result (ref $B)))) + + ;; CHECK: (type $return-A (func (result (ref null $A)))) + (type $return-A (func (result (ref null $A)))) + + ;; CHECK: (type $A (struct (field i32))) + (type $A (struct i32)) + + ;; CHECK: (type $B (struct (field i32) (field i32))) + (type $B (struct i32 i32) (supertype $A)) + + ;; CHECK: (table $t 1 1 funcref) + (table $t 1 1 funcref) + + ;; CHECK: (elem $e (i32.const 0) $callee) + (elem $e (i32.const 0) $callee) + + ;; CHECK: (func $caller (result (ref null $A)) + ;; CHECK-NEXT: (return_call $callee) + ;; CHECK-NEXT: ) + (func $caller (type $return-A) + (return_call $callee) + ) + + ;; CHECK: (func $caller-indirect (result (ref $B)) + ;; CHECK-NEXT: (return_call_indirect $t (type $return-B) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $caller-indirect (type $return-B) + (return_call_indirect $t (type $return-B) (i32.const 0)) + ) + + ;; CHECK: (func $callee (result (ref $B)) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $callee (type $return-B) + (unreachable) + ) +) diff --git a/test/tail-call.wast b/test/tail-call.wast deleted file mode 100644 index ceea1239e..000000000 --- a/test/tail-call.wast +++ /dev/null @@ -1,11 +0,0 @@ -(module - (type $void (func)) - (table 1 1 funcref) - (elem (i32.const 0) $foo) - (func $foo - (return_call $bar) - ) - (func $bar - (return_call_indirect (type $void) (i32.const 0)) - ) -)
\ No newline at end of file |