File tree Expand file tree Collapse file tree 2 files changed +43
-21
lines changed Expand file tree Collapse file tree 2 files changed +43
-21
lines changed Original file line number Diff line number Diff line change 64
64
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
+
68
+ ;; https://github.com/WebAssembly/gc/issues/516
69
+ (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"
109
+ )
Original file line number Diff line number Diff line change 280
280
)
281
281
" type mismatch"
282
282
)
283
-
284
- ;; https://github.com/WebAssembly/gc/issues/516
285
- (assert_invalid
286
- (module
287
- (func (param anyref ) (result anyref )
288
- ref.null struct
289
- local.get 0
290
- ;; This instruction is typed `[anyref anyref] -> [anyref (ref any)]`. The stack
291
- ;; coming into this instruction is `[structref anyref]` which matches because of
292
- ;; `structref <: anyref`. However, that subtyping relation doesn't mean that this
293
- ;; instruction can *push* a `structref`. The label type effectively erases the
294
- ;; `structref`, turning it into an `anyref`. Finally, a type mismatch error should
295
- ;; be reported at the `br_on_cast_fail` instruction, which expects a `structref`
296
- ;; but is given the `anyref` (that is "actually" a `structref`).
297
- br_on_null 0
298
- drop
299
- br_on_cast_fail 0 structref structref
300
- )
301
- )
302
- " type mismatch"
303
- )
You can’t perform that action at this time.
0 commit comments