1+ (module definition
2+ (type $f (func ))
3+ (import " " " " (func $1 (exact (type 0 ))))
4+ ;; (import "" "" (func $2 (exact (type $f) (param) (result)))) ;; TODO: parser support
5+ (import " " " " (func $2 (exact (type $f ))))
6+ (import " " " " (func $3 (exact (type 1 )))) ;; Implicitly defined next
7+ (import " " " " (func $4 (exact (param i32 ) (result i64 ))))
8+
9+ (func $5 (import " " " " ) (exact (type 0 )))
10+ ;; (func $6 (import "" "") (exact (type $f) (param) (result))) ;; TODO: parser support
11+ (func $6 (import " " " " ) (exact (type $f )))
12+ ;; (func $7 (import "" "") (exact (type 2))) ;; Implicitly defined next
13+ ;; (func $8 (import "" "") (exact (param i64) (result i32))) ;; TODO: parser support
14+
15+ (global (ref (exact $f )) (ref.func $1 ))
16+ (global (ref (exact $f )) (ref.func $2 ))
17+ (global (ref (exact 1 )) (ref.func $3 ))
18+ (global (ref (exact 1 )) (ref.func $4 ))
19+ (global (ref (exact $f )) (ref.func $5 ))
20+ (global (ref (exact $f )) (ref.func $6 ))
21+ ;; (global (ref (exact 2)) (ref.func $7))
22+ ;; (global (ref (exact 2)) (ref.func $8))
23+ )
24+
25+ ;; References to inexact imports are not exact.
26+
27+ (assert_invalid
28+ (module
29+ (type $f (func ))
30+ (import " " " " (func $1 (type $f )))
31+ (global (ref (exact $f )) (ref.func $1 ))
32+ )
33+ " type mismatch"
34+ )
35+
36+ (assert_invalid
37+ (module
38+ (type $f (func ))
39+ (import " " " " (func $1 (type $f )))
40+ (elem declare func $1 )
41+ (func (result (ref (exact $f )))
42+ (ref.func $1 )
43+ )
44+ )
45+ " type mismatch"
46+ )
47+
48+ ;; Inexact imports can still be referenced inexactly, though.
49+
50+ (module definition
51+ (type $f (func ))
52+ (import " " " " (func $1 (type $f )))
53+ (global (ref $f ) (ref.func $1 ))
54+ (func (result (ref $f ))
55+ (ref.func $1 )
56+ )
57+ )
58+
59+ ;; Define a function and export it exactly.
60+ (module $A
61+ (type $f (func ))
62+ (func (export " f" ) (type $f ))
63+ )
64+ (register " A" )
65+
66+ ;; Import and re-export inexactly.
67+ (module $B
68+ (type $f (func ))
69+ ;; (func (import "A" "f") (export "f") (type $f))
70+ (func (import " A" " f" ) (type $f ))
71+ (export " f" (func 0 ))
72+ )
73+ (register " B" )
74+
75+ ;; The export from A is exact.
76+ (module
77+ (type $f (func ))
78+ (import " A" " f" (func (exact (type $f ))))
79+ )
80+
81+ ;; The export from B is _statically_ inexact, but instantiation checks
82+ ;; the dynamic types of imports, so this link still succeeds.
83+ (module
84+ (type $f (func ))
85+ (import " B" " f" (func (exact (type $f ))))
86+ )
87+
88+ ;; Even when the function is imported inexactly, it can still be cast to its
89+ ;; exact type.
90+ (module
91+ (type $f (func ))
92+ (import " A" " f" (func $1 (type $f )))
93+ (elem declare func $1 )
94+ (func (export " exact-test" ) (result i32 )
95+ (ref.test (ref (exact $f )) (ref.func $1 ))
96+ )
97+ (func (export " exact-cast" ) (result (ref (exact $f )))
98+ (ref.cast (ref (exact $f )) (ref.func $1 ))
99+ )
100+ (func (export " exact-br-on-cast" ) (result funcref )
101+ (br_on_cast 0 funcref (ref (exact $f )) (ref.func $1 ))
102+ (unreachable )
103+ )
104+ (func (export " exact-br-on-cast-fail" ) (result funcref )
105+ (block (result funcref )
106+ (br_on_cast_fail 0 funcref (ref (exact $f )) (ref.func $1 ))
107+ (return )
108+ )
109+ (unreachable )
110+ )
111+ )
112+
113+ (assert_return (invoke " exact-test" ) (i32.const 1 ))
114+ (assert_return (invoke " exact-cast" ) (ref.func ))
115+ (assert_return (invoke " exact-br-on-cast" ) (ref.func ))
116+ (assert_return (invoke " exact-br-on-cast-fail" ) (ref.func ))
117+
118+ ;; Define a function with a type that has a supertype.
119+ (module $C
120+ (type $super (sub (func )))
121+ (type $sub (sub $super (func )))
122+ (func (export " f" ) (type $sub ))
123+ (func (export " g" ) (type $super ))
124+ )
125+ (register " C" )
126+
127+ ;; TODO: Fix function type checking on linking.
128+
129+ ;; ;; We should not be able to import the function with the exact supertype.
130+ ;; (assert_unlinkable
131+ ;; (module
132+ ;; (type $super (sub (func)))
133+ ;; (type $sub (sub $super (func)))
134+ ;; (import "C" "f" (func (exact (type $super))))
135+ ;; )
136+ ;; "incompatible import type"
137+ ;; )
138+
139+ ;; But we can still import it and re-export it inexactly with the supertype.
140+ (module $D
141+ (type $super (sub (func )))
142+ (type $sub (sub $super (func )))
143+ (import " C" " f" (func (type $super )))
144+ (export " f" (func 0 ))
145+ )
146+ (register " D" )
147+
148+ ;; As before, we can still import the function with its real dynamic type.
149+ (module
150+ (type $super (sub (func )))
151+ (type $sub (sub $super (func )))
152+ (import " D" " f" (func (exact (type $sub ))))
153+ )
154+
155+ ;; As before, even when the function is imported inexactly (this time with its
156+ ;; supertype), it can still be cast to its exact type.
157+ (module
158+ (type $super (sub (func )))
159+ (type $sub (sub $super (func )))
160+ (import " C" " f" (func $1 (type $super )))
161+ (elem declare func $1 )
162+ (func (export " exact-test" ) (result i32 )
163+ (ref.test (ref (exact $sub )) (ref.func $1 ))
164+ )
165+ (func (export " exact-cast" ) (result (ref (exact $sub )))
166+ (ref.cast (ref (exact $sub )) (ref.func $1 ))
167+ )
168+ (func (export " exact-br-on-cast" ) (result funcref )
169+ (br_on_cast 0 funcref (ref (exact $sub )) (ref.func $1 ))
170+ (unreachable )
171+ )
172+ (func (export " exact-br-on-cast-fail" ) (result funcref )
173+ (block (result funcref )
174+ (br_on_cast_fail 0 funcref (ref (exact $sub )) (ref.func $1 ))
175+ (return )
176+ )
177+ (unreachable )
178+ )
179+ )
180+
181+ (assert_return (invoke " exact-test" ) (i32.const 1 ))
182+ (assert_return (invoke " exact-cast" ) (ref.func ))
183+ (assert_return (invoke " exact-br-on-cast" ) (ref.func ))
184+ (assert_return (invoke " exact-br-on-cast-fail" ) (ref.func ))
185+
186+ ;; But if we import a function whose dynamic type is the supertype, the same
187+ ;; casts will fail.
188+ (module
189+ (type $super (sub (func )))
190+ (type $sub (sub $super (func )))
191+ (import " C" " g" (func $1 (type $super )))
192+ (elem declare func $1 )
193+ (func (export " exact-test" ) (result i32 )
194+ (ref.test (ref (exact $sub )) (ref.func $1 ))
195+ )
196+ (func (export " exact-cast" ) (result (ref (exact $sub )))
197+ (ref.cast (ref (exact $sub )) (ref.func $1 ))
198+ )
199+ (func (export " exact-br-on-cast" ) (result funcref )
200+ (br_on_cast 0 funcref (ref (exact $sub )) (ref.func $1 ))
201+ (unreachable )
202+ )
203+ (func (export " exact-br-on-cast-fail" ) (result funcref )
204+ (block (result funcref )
205+ (br_on_cast_fail 0 funcref (ref (exact $sub )) (ref.func $1 ))
206+ (return )
207+ )
208+ (unreachable )
209+ )
210+ )
211+
212+ (assert_return (invoke " exact-test" ) (i32.const 0 ))
213+ (assert_trap (invoke " exact-cast" ) " cast failure" )
214+ (assert_trap (invoke " exact-br-on-cast" ) " unreachable" )
215+ (assert_trap (invoke " exact-br-on-cast-fail" ) " unreachable" )
216+
217+
218+ ;; Test the binary format
219+
220+ ;; Exact function imports use 0x20.
221+ (module definition binary
222+ " \00 asm" " \01\00\00\00 "
223+ " \01 " ;; Type section id
224+ " \04 " ;; Type section length
225+ " \01 " ;; Types vector length
226+ " \60 " ;; Function
227+ " \00 " ;; Number of params
228+ " \00 " ;; Number of results
229+ " \02 " ;; Import section id
230+ " \05 " ;; Import section length
231+ " \01 " ;; Import vector length
232+ " \00 " ;; Module name length
233+ " \00 " ;; Base name length
234+ " \20 " ;; Exact function
235+ " \00 " ;; Type index
236+ )
237+
238+ ;; 0x20 is malformed in exports.
239+ (assert_malformed
240+ (module binary
241+ " \00 asm" " \01\00\00\00 "
242+ " \01 " ;; Type section id
243+ " \04 " ;; Type section length
244+ " \01 " ;; Types vector length
245+ " \60 " ;; Function
246+ " \00 " ;; Number of params
247+ " \00 " ;; Number of results
248+ " \03 " ;; Function section id
249+ " \02 " ;; Function section length
250+ " \01 " ;; Function vector length
251+ " \00 " ;; Type index
252+ " \07 " ;; Export section id
253+ " \04 " ;; Export section length
254+ " \01 " ;; Export vector length
255+ " \00 " ;; Name length
256+ " \20 " ;; Exact func (malformed)
257+ " \00 " ;; Function index
258+ " \0a " ;; Code section
259+ " \04 " ;; Code section length
260+ " \01 " ;; Code vector length
261+ " \02 " ;; Function length
262+ " \00 " ;; Type index
263+ " \0b " ;; End
264+ )
265+ " malformed export kind"
266+ )
0 commit comments