...
1;; Test `call` operator
2
3(module
4 ;; Auxiliary definitions
5 (func $const-i32 (result i32) (i32.const 0x132))
6 (func $const-i64 (result i64) (i64.const 0x164))
7 (func $const-f32 (result f32) (f32.const 0xf32))
8 (func $const-f64 (result f64) (f64.const 0xf64))
9 (func $const-i32-i64 (result i32 i64) (i32.const 0x132) (i64.const 0x164))
10
11 (func $id-i32 (param i32) (result i32) (local.get 0))
12 (func $id-i64 (param i64) (result i64) (local.get 0))
13 (func $id-f32 (param f32) (result f32) (local.get 0))
14 (func $id-f64 (param f64) (result f64) (local.get 0))
15 (func $id-i32-f64 (param i32 f64) (result i32 f64)
16 (local.get 0) (local.get 1)
17 )
18
19 (func $swap-i32-i32 (param i32 i32) (result i32 i32)
20 (local.get 1) (local.get 0)
21 )
22 (func $swap-f32-f64 (param f32 f64) (result f64 f32)
23 (local.get 1) (local.get 0)
24 )
25 (func $swap-f64-i32 (param f64 i32) (result i32 f64)
26 (local.get 1) (local.get 0)
27 )
28
29 (func $f32-i32 (param f32 i32) (result i32) (local.get 1))
30 (func $i32-i64 (param i32 i64) (result i64) (local.get 1))
31 (func $f64-f32 (param f64 f32) (result f32) (local.get 1))
32 (func $i64-f64 (param i64 f64) (result f64) (local.get 1))
33
34 ;; Typing
35
36 (func (export "type-i32") (result i32) (call $const-i32))
37 (func (export "type-i64") (result i64) (call $const-i64))
38 (func (export "type-f32") (result f32) (call $const-f32))
39 (func (export "type-f64") (result f64) (call $const-f64))
40 (func (export "type-i32-i64") (result i32 i64) (call $const-i32-i64))
41
42 (func (export "type-first-i32") (result i32) (call $id-i32 (i32.const 32)))
43 (func (export "type-first-i64") (result i64) (call $id-i64 (i64.const 64)))
44 (func (export "type-first-f32") (result f32) (call $id-f32 (f32.const 1.32)))
45 (func (export "type-first-f64") (result f64) (call $id-f64 (f64.const 1.64)))
46
47 (func (export "type-second-i32") (result i32)
48 (call $f32-i32 (f32.const 32.1) (i32.const 32))
49 )
50 (func (export "type-second-i64") (result i64)
51 (call $i32-i64 (i32.const 32) (i64.const 64))
52 )
53 (func (export "type-second-f32") (result f32)
54 (call $f64-f32 (f64.const 64) (f32.const 32))
55 )
56 (func (export "type-second-f64") (result f64)
57 (call $i64-f64 (i64.const 64) (f64.const 64.1))
58 )
59
60 (func (export "type-all-i32-f64") (result i32 f64)
61 (call $id-i32-f64 (i32.const 32) (f64.const 1.64))
62 )
63 (func (export "type-all-i32-i32") (result i32 i32)
64 (call $swap-i32-i32 (i32.const 1) (i32.const 2))
65 )
66 (func (export "type-all-f32-f64") (result f64 f32)
67 (call $swap-f32-f64 (f32.const 1) (f64.const 2))
68 )
69 (func (export "type-all-f64-i32") (result i32 f64)
70 (call $swap-f64-i32 (f64.const 1) (i32.const 2))
71 )
72
73 ;; Composition
74
75 (func (export "as-binary-all-operands") (result i32)
76 (i32.add (call $swap-i32-i32 (i32.const 3) (i32.const 4)))
77 )
78
79 (func (export "as-mixed-operands") (result i32)
80 (call $swap-i32-i32 (i32.const 3) (i32.const 4))
81 (i32.const 5)
82 (i32.add)
83 (i32.mul)
84 )
85
86 (func (export "as-call-all-operands") (result i32 i32)
87 (call $swap-i32-i32 (call $swap-i32-i32 (i32.const 3) (i32.const 4)))
88 )
89
90 ;; Recursion
91
92 (func $fac (export "fac") (param i64) (result i64)
93 (if (result i64) (i64.eqz (local.get 0))
94 (then (i64.const 1))
95 (else
96 (i64.mul
97 (local.get 0)
98 (call $fac (i64.sub (local.get 0) (i64.const 1)))
99 )
100 )
101 )
102 )
103
104 (func $fac-acc (export "fac-acc") (param i64 i64) (result i64)
105 (if (result i64) (i64.eqz (local.get 0))
106 (then (local.get 1))
107 (else
108 (call $fac-acc
109 (i64.sub (local.get 0) (i64.const 1))
110 (i64.mul (local.get 0) (local.get 1))
111 )
112 )
113 )
114 )
115
116 (func $fib (export "fib") (param i64) (result i64)
117 (if (result i64) (i64.le_u (local.get 0) (i64.const 1))
118 (then (i64.const 1))
119 (else
120 (i64.add
121 (call $fib (i64.sub (local.get 0) (i64.const 2)))
122 (call $fib (i64.sub (local.get 0) (i64.const 1)))
123 )
124 )
125 )
126 )
127
128 (func $even (export "even") (param i64) (result i32)
129 (if (result i32) (i64.eqz (local.get 0))
130 (then (i32.const 44))
131 (else (call $odd (i64.sub (local.get 0) (i64.const 1))))
132 )
133 )
134 (func $odd (export "odd") (param i64) (result i32)
135 (if (result i32) (i64.eqz (local.get 0))
136 (then (i32.const 99))
137 (else (call $even (i64.sub (local.get 0) (i64.const 1))))
138 )
139 )
140
141 ;; Stack exhaustion
142
143 ;; Implementations are required to have every call consume some abstract
144 ;; resource towards exhausting some abstract finite limit, such that
145 ;; infinitely recursive test cases reliably trap in finite time. This is
146 ;; because otherwise applications could come to depend on it on those
147 ;; implementations and be incompatible with implementations that don't do
148 ;; it (or don't do it under the same circumstances).
149
150 (func $runaway (export "runaway") (call $runaway))
151
152 (func $mutual-runaway1 (export "mutual-runaway") (call $mutual-runaway2))
153 (func $mutual-runaway2 (call $mutual-runaway1))
154
155 ;; As parameter of control constructs and instructions
156
157 (memory 1)
158
159 (func (export "as-select-first") (result i32)
160 (select (call $const-i32) (i32.const 2) (i32.const 3))
161 )
162 (func (export "as-select-mid") (result i32)
163 (select (i32.const 2) (call $const-i32) (i32.const 3))
164 )
165 (func (export "as-select-last") (result i32)
166 (select (i32.const 2) (i32.const 3) (call $const-i32))
167 )
168
169 (func (export "as-if-condition") (result i32)
170 (if (result i32) (call $const-i32) (then (i32.const 1)) (else (i32.const 2)))
171 )
172
173 (func (export "as-br_if-first") (result i32)
174 (block (result i32) (br_if 0 (call $const-i32) (i32.const 2)))
175 )
176 (func (export "as-br_if-last") (result i32)
177 (block (result i32) (br_if 0 (i32.const 2) (call $const-i32)))
178 )
179
180 (func (export "as-br_table-first") (result i32)
181 (block (result i32) (call $const-i32) (i32.const 2) (br_table 0 0))
182 )
183 (func (export "as-br_table-last") (result i32)
184 (block (result i32) (i32.const 2) (call $const-i32) (br_table 0 0))
185 )
186
187 (func $func (param i32 i32) (result i32) (local.get 0))
188 (type $check (func (param i32 i32) (result i32)))
189 (table funcref (elem $func))
190 (func (export "as-call_indirect-first") (result i32)
191 (block (result i32)
192 (call_indirect (type $check)
193 (call $const-i32) (i32.const 2) (i32.const 0)
194 )
195 )
196 )
197 (func (export "as-call_indirect-mid") (result i32)
198 (block (result i32)
199 (call_indirect (type $check)
200 (i32.const 2) (call $const-i32) (i32.const 0)
201 )
202 )
203 )
204 (func (export "as-call_indirect-last") (result i32)
205 (block (result i32)
206 (call_indirect (type $check)
207 (i32.const 1) (i32.const 2) (call $const-i32)
208 )
209 )
210 )
211
212 (func (export "as-store-first")
213 (call $const-i32) (i32.const 1) (i32.store)
214 )
215 (func (export "as-store-last")
216 (i32.const 10) (call $const-i32) (i32.store)
217 )
218
219 (func (export "as-memory.grow-value") (result i32)
220 (memory.grow (call $const-i32))
221 )
222 (func (export "as-return-value") (result i32)
223 (call $const-i32) (return)
224 )
225 (func (export "as-drop-operand")
226 (call $const-i32) (drop)
227 )
228 (func (export "as-br-value") (result i32)
229 (block (result i32) (br 0 (call $const-i32)))
230 )
231 (func (export "as-local.set-value") (result i32)
232 (local i32) (local.set 0 (call $const-i32)) (local.get 0)
233 )
234 (func (export "as-local.tee-value") (result i32)
235 (local i32) (local.tee 0 (call $const-i32))
236 )
237 (global $a (mut i32) (i32.const 10))
238 (func (export "as-global.set-value") (result i32)
239 (global.set $a (call $const-i32))
240 (global.get $a)
241 )
242 (func (export "as-load-operand") (result i32)
243 (i32.load (call $const-i32))
244 )
245
246 (func $dummy (param i32) (result i32) (local.get 0))
247 (func $du (param f32) (result f32) (local.get 0))
248 (func (export "as-unary-operand") (result f32)
249 (block (result f32) (f32.sqrt (call $du (f32.const 0x0p+0))))
250 )
251
252 (func (export "as-binary-left") (result i32)
253 (block (result i32) (i32.add (call $dummy (i32.const 1)) (i32.const 10)))
254 )
255 (func (export "as-binary-right") (result i32)
256 (block (result i32) (i32.sub (i32.const 10) (call $dummy (i32.const 1))))
257 )
258
259 (func (export "as-test-operand") (result i32)
260 (block (result i32) (i32.eqz (call $dummy (i32.const 1))))
261 )
262
263 (func (export "as-compare-left") (result i32)
264 (block (result i32) (i32.le_u (call $dummy (i32.const 1)) (i32.const 10)))
265 )
266 (func (export "as-compare-right") (result i32)
267 (block (result i32) (i32.ne (i32.const 10) (call $dummy (i32.const 1))))
268 )
269
270 (func (export "as-convert-operand") (result i64)
271 (block (result i64) (i64.extend_i32_s (call $dummy (i32.const 1))))
272 )
273
274 ;; Test correct argument passing
275
276 (func $return-from-long-argument-list-helper (param f32 i32 i32 f64 f32 f32 f32 f64 f32 i32 i32 f32 f64 i64 i64 i32 i64 i64 f32 i64 i64 i64 i32 f32 f32 f32 f64 f32 i32 i64 f32 f64 f64 f32 i32 f32 f32 f64 i64 f64 i32 i64 f32 f64 i32 i32 i32 i64 f64 i32 i64 i64 f64 f64 f64 f64 f64 f64 i32 f32 f64 f64 i32 i64 f32 f32 f32 i32 f64 f64 f64 f64 f64 f32 i64 i64 i32 i32 i32 f32 f64 i32 i64 f32 f32 f32 i32 i32 f32 f64 i64 f32 f64 f32 f32 f32 i32 f32 i64 i32) (result i32)
277 (local.get 99)
278 )
279
280 (func (export "return-from-long-argument-list") (param i32) (result i32)
281 (call $return-from-long-argument-list-helper (f32.const 0) (i32.const 0) (i32.const 0) (f64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f64.const 0) (f32.const 0) (i32.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (i64.const 0) (i64.const 0) (i32.const 0) (i64.const 0) (i64.const 0) (f32.const 0) (i64.const 0) (i64.const 0) (i64.const 0) (i32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f64.const 0) (f32.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f64.const 0) (f64.const 0) (f32.const 0) (i32.const 0) (f32.const 0) (f32.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f64.const 0) (i32.const 0) (i32.const 0) (i32.const 0) (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (i32.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f64.const 0) (f32.const 0) (i64.const 0) (i64.const 0) (i32.const 0) (i32.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (i32.const 0) (i32.const 0) (f32.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (f64.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (i32.const 0) (f32.const 0) (i64.const 0) (local.get 0))
282 )
283)
284
285(assert_return (invoke "type-i32") (i32.const 0x132))
286(assert_return (invoke "type-i64") (i64.const 0x164))
287(assert_return (invoke "type-f32") (f32.const 0xf32))
288(assert_return (invoke "type-f64") (f64.const 0xf64))
289(assert_return (invoke "type-i32-i64") (i32.const 0x132) (i64.const 0x164))
290
291(assert_return (invoke "type-first-i32") (i32.const 32))
292(assert_return (invoke "type-first-i64") (i64.const 64))
293(assert_return (invoke "type-first-f32") (f32.const 1.32))
294(assert_return (invoke "type-first-f64") (f64.const 1.64))
295
296(assert_return (invoke "type-second-i32") (i32.const 32))
297(assert_return (invoke "type-second-i64") (i64.const 64))
298(assert_return (invoke "type-second-f32") (f32.const 32))
299(assert_return (invoke "type-second-f64") (f64.const 64.1))
300
301(assert_return (invoke "type-all-i32-f64") (i32.const 32) (f64.const 1.64))
302(assert_return (invoke "type-all-i32-i32") (i32.const 2) (i32.const 1))
303(assert_return (invoke "type-all-f32-f64") (f64.const 2) (f32.const 1))
304(assert_return (invoke "type-all-f64-i32") (i32.const 2) (f64.const 1))
305
306(assert_return (invoke "as-binary-all-operands") (i32.const 7))
307(assert_return (invoke "as-mixed-operands") (i32.const 32))
308(assert_return (invoke "as-call-all-operands") (i32.const 3) (i32.const 4))
309
310(assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
311(assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
312(assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
313(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
314(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
315(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
316(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
317(assert_return
318 (invoke "fac-acc" (i64.const 25) (i64.const 1))
319 (i64.const 7034535277573963776)
320)
321
322(assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
323(assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
324(assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
325(assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
326(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
327
328(assert_return (invoke "even" (i64.const 0)) (i32.const 44))
329(assert_return (invoke "even" (i64.const 1)) (i32.const 99))
330(assert_return (invoke "even" (i64.const 100)) (i32.const 44))
331(assert_return (invoke "even" (i64.const 77)) (i32.const 99))
332(assert_return (invoke "odd" (i64.const 0)) (i32.const 99))
333(assert_return (invoke "odd" (i64.const 1)) (i32.const 44))
334(assert_return (invoke "odd" (i64.const 200)) (i32.const 99))
335(assert_return (invoke "odd" (i64.const 77)) (i32.const 44))
336
337(assert_exhaustion (invoke "runaway") "call stack exhausted")
338(assert_exhaustion (invoke "mutual-runaway") "call stack exhausted")
339
340(assert_return (invoke "as-select-first") (i32.const 0x132))
341(assert_return (invoke "as-select-mid") (i32.const 2))
342(assert_return (invoke "as-select-last") (i32.const 2))
343
344(assert_return (invoke "as-if-condition") (i32.const 1))
345
346(assert_return (invoke "as-br_if-first") (i32.const 0x132))
347(assert_return (invoke "as-br_if-last") (i32.const 2))
348
349(assert_return (invoke "as-br_table-first") (i32.const 0x132))
350(assert_return (invoke "as-br_table-last") (i32.const 2))
351
352(assert_return (invoke "as-call_indirect-first") (i32.const 0x132))
353(assert_return (invoke "as-call_indirect-mid") (i32.const 2))
354(assert_trap (invoke "as-call_indirect-last") "undefined element")
355
356(assert_return (invoke "as-store-first"))
357(assert_return (invoke "as-store-last"))
358
359(assert_return (invoke "as-memory.grow-value") (i32.const 1))
360(assert_return (invoke "as-return-value") (i32.const 0x132))
361(assert_return (invoke "as-drop-operand"))
362(assert_return (invoke "as-br-value") (i32.const 0x132))
363(assert_return (invoke "as-local.set-value") (i32.const 0x132))
364(assert_return (invoke "as-local.tee-value") (i32.const 0x132))
365(assert_return (invoke "as-global.set-value") (i32.const 0x132))
366(assert_return (invoke "as-load-operand") (i32.const 1))
367
368(assert_return (invoke "as-unary-operand") (f32.const 0x0p+0))
369(assert_return (invoke "as-binary-left") (i32.const 11))
370(assert_return (invoke "as-binary-right") (i32.const 9))
371(assert_return (invoke "as-test-operand") (i32.const 0))
372(assert_return (invoke "as-compare-left") (i32.const 1))
373(assert_return (invoke "as-compare-right") (i32.const 1))
374(assert_return (invoke "as-convert-operand") (i64.const 1))
375
376(assert_return (invoke "return-from-long-argument-list" (i32.const 42)) (i32.const 42))
377
378;; Invalid typing
379
380(assert_invalid
381 (module
382 (func $type-void-vs-num (i32.eqz (call 1)))
383 (func)
384 )
385 "type mismatch"
386)
387(assert_invalid
388 (module
389 (func $type-num-vs-num (i32.eqz (call 1)))
390 (func (result i64) (i64.const 1))
391 )
392 "type mismatch"
393)
394
395(assert_invalid
396 (module
397 (func $arity-0-vs-1 (call 1))
398 (func (param i32))
399 )
400 "type mismatch"
401)
402(assert_invalid
403 (module
404 (func $arity-0-vs-2 (call 1))
405 (func (param f64 i32))
406 )
407 "type mismatch"
408)
409(assert_invalid
410 (module
411 (func $arity-1-vs-0 (call 1 (i32.const 1)))
412 (func)
413 )
414 "type mismatch"
415)
416(assert_invalid
417 (module
418 (func $arity-2-vs-0 (call 1 (f64.const 2) (i32.const 1)))
419 (func)
420 )
421 "type mismatch"
422)
423
424(assert_invalid
425 (module
426 (func $type-first-void-vs-num (call 1 (nop) (i32.const 1)))
427 (func (param i32 i32))
428 )
429 "type mismatch"
430)
431(assert_invalid
432 (module
433 (func $type-second-void-vs-num (call 1 (i32.const 1) (nop)))
434 (func (param i32 i32))
435 )
436 "type mismatch"
437)
438(assert_invalid
439 (module
440 (func $type-first-num-vs-num (call 1 (f64.const 1) (i32.const 1)))
441 (func (param i32 f64))
442 )
443 "type mismatch"
444)
445(assert_invalid
446 (module
447 (func $type-second-num-vs-num (call 1 (i32.const 1) (f64.const 1)))
448 (func (param f64 i32))
449 )
450 "type mismatch"
451)
452
453(assert_invalid
454 (module
455 (func $type-first-empty-in-block
456 (block (call 1))
457 )
458 (func (param i32))
459 )
460 "type mismatch"
461)
462(assert_invalid
463 (module
464 (func $type-second-empty-in-block
465 (block (call 1 (i32.const 0)))
466 )
467 (func (param i32 i32))
468 )
469 "type mismatch"
470)
471(assert_invalid
472 (module
473 (func $type-first-empty-in-loop
474 (loop (call 1))
475 )
476 (func (param i32))
477 )
478 "type mismatch"
479)
480(assert_invalid
481 (module
482 (func $type-second-empty-in-loop
483 (loop (call 1 (i32.const 0)))
484 )
485 (func (param i32 i32))
486 )
487 "type mismatch"
488)
489(assert_invalid
490 (module
491 (func $type-first-empty-in-then
492 (if (i32.const 0) (then (call 1)))
493 )
494 (func (param i32))
495 )
496 "type mismatch"
497)
498(assert_invalid
499 (module
500 (func $type-second-empty-in-then
501 (if (i32.const 0) (then (call 1 (i32.const 0))))
502 )
503 (func (param i32 i32))
504 )
505 "type mismatch"
506)
507
508
509;; Unbound function
510
511(assert_invalid
512 (module (func $unbound-func (call 1)))
513 "unknown function"
514)
515(assert_invalid
516 (module (func $large-func (call 1012321300)))
517 "unknown function"
518)
View as plain text