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