|
65 | 65 | (assert_return (invoke "args-null" (i32.const 3)) (i32.const 3))
|
66 | 66 | (assert_return (invoke "args-f" (i32.const 3)) (i32.const 9))
|
67 | 67 |
|
| 68 | + |
68 | 69 | ;; https://github.com/WebAssembly/gc/issues/516
|
| 70 | +;; Tests that validators are correctly doing |
| 71 | +;; |
| 72 | +;; pop_operands(label_types) |
| 73 | +;; push_operands(label_types) |
| 74 | +;; |
| 75 | +;; for validating br_on_null, rather than incorrectly doing either |
| 76 | +;; |
| 77 | +;; push_operands(pop_operands(label_types)) |
| 78 | +;; |
| 79 | +;; or just inspecting the types on the stack without any pushing or |
| 80 | +;; popping, neither of which handle subtyping correctly. |
69 | 81 | (assert_invalid
|
70 |
| - (module |
71 |
| - (type $ty (func)) |
72 |
| - |
73 |
| - (func $ty_ref_to_func_ref (param (ref null $ty)) (result funcref) |
74 |
| - local.get 0 |
75 |
| - ) |
76 |
| - |
77 |
| - (func (param funcref) (result funcref) |
78 |
| - ref.null $ty |
79 |
| - local.get 0 |
80 |
| - |
81 |
| - ;; This instruction is typed `[funcref funcref] -> [funcref (ref |
82 |
| - ;; func)]`. The stack coming into this instruction is `[(ref null $ty) |
83 |
| - ;; funcref]` which matches because of `(ref null $ty) <: funcref`. However, |
84 |
| - ;; that subtyping relation doesn't mean that this instruction can *push* a |
85 |
| - ;; `(ref null $ty)`. The label type effectively erases the `(ref null |
86 |
| - ;; $ty)`, turning it into an `funcref`. Finally, a type mismatch error |
87 |
| - ;; should be reported at the `call` instruction below, which expects a |
88 |
| - ;; `(ref null $ty)` but is given the `funcref` (that is "actually" a `(ref |
89 |
| - ;; null $ty)`). |
90 |
| - ;; |
91 |
| - ;; This tests that validators are correctly doing |
92 |
| - ;; |
93 |
| - ;; pop_operands(label_types) |
94 |
| - ;; push_operands(label_types) |
95 |
| - ;; |
96 |
| - ;; rather than incorrectly doing either |
97 |
| - ;; |
98 |
| - ;; push_operands(pop_operands(label_types)) |
99 |
| - ;; |
100 |
| - ;; or just inspecting the types on the stack without any pushing or |
101 |
| - ;; popping, neither of which handle subtyping correctly. |
102 |
| - br_on_null 0 |
103 |
| - |
104 |
| - drop |
105 |
| - call $ty_ref_to_func_ref |
106 |
| - ) |
107 |
| - ) |
108 |
| -"type mismatch" |
| 82 | + (module |
| 83 | + (type $t (func)) |
| 84 | + (func $f (param (ref null $t)) (result funcref) (local.get 0)) |
| 85 | + (func (param funcref) (result funcref) |
| 86 | + (ref.null $t) |
| 87 | + (local.get 0) |
| 88 | + (br_on_null 0) ;; only leaves two funcref's on the stack |
| 89 | + (drop) |
| 90 | + (call $f) |
| 91 | + ) |
| 92 | + ) |
| 93 | + "type mismatch" |
109 | 94 | )
|
0 commit comments