1ecd9b7baf06135766cba00bf1c70c225da8cfb7
[platform/framework/web/lwnode.git] /
1 ;; Test `call_indirect` operator
2
3 (module
4   ;; Auxiliary definitions
5   (type $proc (func))
6   (type $out-i32 (func (result i32)))
7   (type $out-i64 (func (result i64)))
8   (type $out-f32 (func (result f32)))
9   (type $out-f64 (func (result f64)))
10   (type $out-f64-i32 (func (result f64 i32)))
11   (type $over-i32 (func (param i32) (result i32)))
12   (type $over-i64 (func (param i64) (result i64)))
13   (type $over-f32 (func (param f32) (result f32)))
14   (type $over-f64 (func (param f64) (result f64)))
15   (type $over-i32-f64 (func (param i32 f64) (result i32 f64)))
16   (type $swap-i32-i64 (func (param i32 i64) (result i64 i32)))
17   (type $f32-i32 (func (param f32 i32) (result i32)))
18   (type $i32-i64 (func (param i32 i64) (result i64)))
19   (type $f64-f32 (func (param f64 f32) (result f32)))
20   (type $i64-f64 (func (param i64 f64) (result f64)))
21   (type $over-i32-duplicate (func (param i32) (result i32)))
22   (type $over-i64-duplicate (func (param i64) (result i64)))
23   (type $over-f32-duplicate (func (param f32) (result f32)))
24   (type $over-f64-duplicate (func (param f64) (result f64)))
25
26   (func $const-i32 (type $out-i32) (i32.const 0x132))
27   (func $const-i64 (type $out-i64) (i64.const 0x164))
28   (func $const-f32 (type $out-f32) (f32.const 0xf32))
29   (func $const-f64 (type $out-f64) (f64.const 0xf64))
30   (func $const-f64-i32 (type $out-f64-i32) (f64.const 0xf64) (i32.const 32))
31
32   (func $id-i32 (type $over-i32) (local.get 0))
33   (func $id-i64 (type $over-i64) (local.get 0))
34   (func $id-f32 (type $over-f32) (local.get 0))
35   (func $id-f64 (type $over-f64) (local.get 0))
36   (func $id-i32-f64 (type $over-i32-f64) (local.get 0) (local.get 1))
37   (func $swap-i32-i64 (type $swap-i32-i64) (local.get 1) (local.get 0))
38
39   (func $i32-i64 (type $i32-i64) (local.get 1))
40   (func $i64-f64 (type $i64-f64) (local.get 1))
41   (func $f32-i32 (type $f32-i32) (local.get 1))
42   (func $f64-f32 (type $f64-f32) (local.get 1))
43
44   (func $over-i32-duplicate (type $over-i32-duplicate) (local.get 0))
45   (func $over-i64-duplicate (type $over-i64-duplicate) (local.get 0))
46   (func $over-f32-duplicate (type $over-f32-duplicate) (local.get 0))
47   (func $over-f64-duplicate (type $over-f64-duplicate) (local.get 0))
48
49   (table funcref
50     (elem
51       $const-i32 $const-i64 $const-f32 $const-f64  ;; 0..3
52       $id-i32 $id-i64 $id-f32 $id-f64              ;; 4..7
53       $f32-i32 $i32-i64 $f64-f32 $i64-f64          ;; 9..11
54       $fac-i64 $fib-i64 $even $odd                 ;; 12..15
55       $runaway $mutual-runaway1 $mutual-runaway2   ;; 16..18
56       $over-i32-duplicate $over-i64-duplicate      ;; 19..20
57       $over-f32-duplicate $over-f64-duplicate      ;; 21..22
58       $fac-i32 $fac-f32 $fac-f64                   ;; 23..25
59       $fib-i32 $fib-f32 $fib-f64                   ;; 26..28
60       $const-f64-i32 $id-i32-f64 $swap-i32-i64     ;; 29..31
61     )
62   )
63
64   ;; Syntax
65
66   (func
67     (call_indirect (i32.const 0))
68     (call_indirect (param i64) (i64.const 0) (i32.const 0))
69     (call_indirect (param i64) (param) (param f64 i32 i64)
70       (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0)
71     )
72     (call_indirect (result) (i32.const 0))
73     (drop (i32.eqz (call_indirect (result i32) (i32.const 0))))
74     (drop (i32.eqz (call_indirect (result i32) (result) (i32.const 0))))
75     (drop (i32.eqz
76       (call_indirect (param i64) (result i32) (i64.const 0) (i32.const 0))
77     ))
78     (drop (i32.eqz
79       (call_indirect
80         (param) (param i64) (param) (param f64 i32 i64) (param) (param)
81         (result) (result i32) (result) (result)
82         (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0)
83       )
84     ))
85     (drop (i64.eqz
86       (call_indirect (type $over-i64) (param i64) (result i64)
87         (i64.const 0) (i32.const 0)
88       )
89     ))
90   )
91
92   ;; Typing
93
94   (func (export "type-i32") (result i32)
95     (call_indirect (type $out-i32) (i32.const 0))
96   )
97   (func (export "type-i64") (result i64)
98     (call_indirect (type $out-i64) (i32.const 1))
99   )
100   (func (export "type-f32") (result f32)
101     (call_indirect (type $out-f32) (i32.const 2))
102   )
103   (func (export "type-f64") (result f64)
104     (call_indirect (type $out-f64) (i32.const 3))
105   )
106   (func (export "type-f64-i32") (result f64 i32)
107     (call_indirect (type $out-f64-i32) (i32.const 29))
108   )
109
110   (func (export "type-index") (result i64)
111     (call_indirect (type $over-i64) (i64.const 100) (i32.const 5))
112   )
113
114   (func (export "type-first-i32") (result i32)
115     (call_indirect (type $over-i32) (i32.const 32) (i32.const 4))
116   )
117   (func (export "type-first-i64") (result i64)
118     (call_indirect (type $over-i64) (i64.const 64) (i32.const 5))
119   )
120   (func (export "type-first-f32") (result f32)
121     (call_indirect (type $over-f32) (f32.const 1.32) (i32.const 6))
122   )
123   (func (export "type-first-f64") (result f64)
124     (call_indirect (type $over-f64) (f64.const 1.64) (i32.const 7))
125   )
126
127   (func (export "type-second-i32") (result i32)
128     (call_indirect (type $f32-i32) (f32.const 32.1) (i32.const 32) (i32.const 8))
129   )
130   (func (export "type-second-i64") (result i64)
131     (call_indirect (type $i32-i64) (i32.const 32) (i64.const 64) (i32.const 9))
132   )
133   (func (export "type-second-f32") (result f32)
134     (call_indirect (type $f64-f32) (f64.const 64) (f32.const 32) (i32.const 10))
135   )
136   (func (export "type-second-f64") (result f64)
137     (call_indirect (type $i64-f64) (i64.const 64) (f64.const 64.1) (i32.const 11))
138   )
139
140   (func (export "type-all-f64-i32") (result f64 i32)
141     (call_indirect (type $out-f64-i32) (i32.const 29))
142   )
143   (func (export "type-all-i32-f64") (result i32 f64)
144     (call_indirect (type $over-i32-f64)
145       (i32.const 1) (f64.const 2) (i32.const 30)
146     )
147   )
148   (func (export "type-all-i32-i64") (result i64 i32)
149     (call_indirect (type $swap-i32-i64)
150       (i32.const 1) (i64.const 2) (i32.const 31)
151     )
152   )
153
154   ;; Dispatch
155
156   (func (export "dispatch") (param i32 i64) (result i64)
157     (call_indirect (type $over-i64) (local.get 1) (local.get 0))
158   )
159
160   (func (export "dispatch-structural-i64") (param i32) (result i64)
161     (call_indirect (type $over-i64-duplicate) (i64.const 9) (local.get 0))
162   )
163   (func (export "dispatch-structural-i32") (param i32) (result i32)
164     (call_indirect (type $over-i32-duplicate) (i32.const 9) (local.get 0))
165   )
166   (func (export "dispatch-structural-f32") (param i32) (result f32)
167     (call_indirect (type $over-f32-duplicate) (f32.const 9.0) (local.get 0))
168   )
169   (func (export "dispatch-structural-f64") (param i32) (result f64)
170     (call_indirect (type $over-f64-duplicate) (f64.const 9.0) (local.get 0))
171   )
172
173   ;; Recursion
174
175   (func $fac-i64 (export "fac-i64") (type $over-i64)
176     (if (result i64) (i64.eqz (local.get 0))
177       (then (i64.const 1))
178       (else
179         (i64.mul
180           (local.get 0)
181           (call_indirect (type $over-i64)
182             (i64.sub (local.get 0) (i64.const 1))
183             (i32.const 12)
184           )
185         )
186       )
187     )
188   )
189
190   (func $fib-i64 (export "fib-i64") (type $over-i64)
191     (if (result i64) (i64.le_u (local.get 0) (i64.const 1))
192       (then (i64.const 1))
193       (else
194         (i64.add
195           (call_indirect (type $over-i64)
196             (i64.sub (local.get 0) (i64.const 2))
197             (i32.const 13)
198           )
199           (call_indirect (type $over-i64)
200             (i64.sub (local.get 0) (i64.const 1))
201             (i32.const 13)
202           )
203         )
204       )
205     )
206   )
207
208   (func $fac-i32 (export "fac-i32") (type $over-i32)
209     (if (result i32) (i32.eqz (local.get 0))
210       (then (i32.const 1))
211       (else
212         (i32.mul
213           (local.get 0)
214           (call_indirect (type $over-i32)
215             (i32.sub (local.get 0) (i32.const 1))
216             (i32.const 23)
217           )
218         )
219       )
220     )
221   )
222
223   (func $fac-f32 (export "fac-f32") (type $over-f32)
224     (if (result f32) (f32.eq (local.get 0) (f32.const 0.0))
225       (then (f32.const 1.0))
226       (else
227         (f32.mul
228           (local.get 0)
229           (call_indirect (type $over-f32)
230             (f32.sub (local.get 0) (f32.const 1.0))
231             (i32.const 24)
232           )
233         )
234       )
235     )
236   )
237
238   (func $fac-f64 (export "fac-f64") (type $over-f64)
239     (if (result f64) (f64.eq (local.get 0) (f64.const 0.0))
240       (then (f64.const 1.0))
241       (else
242         (f64.mul
243           (local.get 0)
244           (call_indirect (type $over-f64)
245             (f64.sub (local.get 0) (f64.const 1.0))
246             (i32.const 25)
247           )
248         )
249       )
250     )
251   )
252
253   (func $fib-i32 (export "fib-i32") (type $over-i32)
254     (if (result i32) (i32.le_u (local.get 0) (i32.const 1))
255       (then (i32.const 1))
256       (else
257         (i32.add
258           (call_indirect (type $over-i32)
259             (i32.sub (local.get 0) (i32.const 2))
260             (i32.const 26)
261           )
262           (call_indirect (type $over-i32)
263             (i32.sub (local.get 0) (i32.const 1))
264             (i32.const 26)
265           )
266         )
267       )
268     )
269   )
270
271   (func $fib-f32 (export "fib-f32") (type $over-f32)
272     (if (result f32) (f32.le (local.get 0) (f32.const 1.0))
273       (then (f32.const 1.0))
274       (else
275         (f32.add
276           (call_indirect (type $over-f32)
277             (f32.sub (local.get 0) (f32.const 2.0))
278             (i32.const 27)
279           )
280           (call_indirect (type $over-f32)
281             (f32.sub (local.get 0) (f32.const 1.0))
282             (i32.const 27)
283           )
284         )
285       )
286     )
287   )
288
289   (func $fib-f64 (export "fib-f64") (type $over-f64)
290     (if (result f64) (f64.le (local.get 0) (f64.const 1.0))
291       (then (f64.const 1.0))
292       (else
293         (f64.add
294           (call_indirect (type $over-f64)
295             (f64.sub (local.get 0) (f64.const 2.0))
296             (i32.const 28)
297           )
298           (call_indirect (type $over-f64)
299             (f64.sub (local.get 0) (f64.const 1.0))
300             (i32.const 28)
301           )
302         )
303       )
304     )
305   )
306
307   (func $even (export "even") (param i32) (result i32)
308     (if (result i32) (i32.eqz (local.get 0))
309       (then (i32.const 44))
310       (else
311         (call_indirect (type $over-i32)
312           (i32.sub (local.get 0) (i32.const 1))
313           (i32.const 15)
314         )
315       )
316     )
317   )
318   (func $odd (export "odd") (param i32) (result i32)
319     (if (result i32) (i32.eqz (local.get 0))
320       (then (i32.const 99))
321       (else
322         (call_indirect (type $over-i32)
323           (i32.sub (local.get 0) (i32.const 1))
324           (i32.const 14)
325         )
326       )
327     )
328   )
329
330   ;; Stack exhaustion
331
332   ;; Implementations are required to have every call consume some abstract
333   ;; resource towards exhausting some abstract finite limit, such that
334   ;; infinitely recursive test cases reliably trap in finite time. This is
335   ;; because otherwise applications could come to depend on it on those
336   ;; implementations and be incompatible with implementations that don't do
337   ;; it (or don't do it under the same circumstances).
338
339   (func $runaway (export "runaway") (call_indirect (type $proc) (i32.const 16)))
340
341   (func $mutual-runaway1 (export "mutual-runaway") (call_indirect (type $proc) (i32.const 18)))
342   (func $mutual-runaway2 (call_indirect (type $proc) (i32.const 17)))
343
344   ;; As parameter of control constructs and instructions
345
346   (memory 1)
347
348   (func (export "as-select-first") (result i32)
349     (select (call_indirect (type $out-i32) (i32.const 0)) (i32.const 2) (i32.const 3))
350   )
351   (func (export "as-select-mid") (result i32)
352     (select (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (i32.const 3))
353   )
354   (func (export "as-select-last") (result i32)
355     (select (i32.const 2) (i32.const 3) (call_indirect (type $out-i32) (i32.const 0)))
356   )
357
358   (func (export "as-if-condition") (result i32)
359     (if (result i32) (call_indirect (type $out-i32) (i32.const 0)) (then (i32.const 1)) (else (i32.const 2)))
360   )
361
362   (func (export "as-br_if-first") (result i64)
363     (block (result i64) (br_if 0 (call_indirect (type $out-i64) (i32.const 1)) (i32.const 2)))
364   )
365   (func (export "as-br_if-last") (result i32)
366     (block (result i32) (br_if 0 (i32.const 2) (call_indirect (type $out-i32) (i32.const 0))))
367   )
368
369   (func (export "as-br_table-first") (result f32)
370     (block (result f32) (call_indirect (type $out-f32) (i32.const 2)) (i32.const 2) (br_table 0 0))
371   )
372   (func (export "as-br_table-last") (result i32)
373     (block (result i32) (i32.const 2) (call_indirect (type $out-i32) (i32.const 0)) (br_table 0 0))
374   )
375
376   (func (export "as-store-first")
377     (call_indirect (type $out-i32) (i32.const 0)) (i32.const 1) (i32.store)
378   )
379   (func (export "as-store-last")
380     (i32.const 10) (call_indirect (type $out-f64) (i32.const 3)) (f64.store)
381   )
382
383   (func (export "as-memory.grow-value") (result i32)
384     (memory.grow (call_indirect (type $out-i32) (i32.const 0)))
385   )
386   (func (export "as-return-value") (result i32)
387     (call_indirect (type $over-i32) (i32.const 1) (i32.const 4)) (return)
388   )
389   (func (export "as-drop-operand")
390     (call_indirect (type $over-i64) (i64.const 1) (i32.const 5)) (drop)
391   )
392   (func (export "as-br-value") (result f32)
393     (block (result f32) (br 0 (call_indirect (type $over-f32) (f32.const 1) (i32.const 6))))
394   )
395   (func (export "as-local.set-value") (result f64)
396     (local f64) (local.set 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7))) (local.get 0)
397   )
398   (func (export "as-local.tee-value") (result f64)
399     (local f64) (local.tee 0 (call_indirect (type $over-f64) (f64.const 1) (i32.const 7)))
400   )
401   (global $a (mut f64) (f64.const 10.0))
402   (func (export "as-global.set-value") (result f64)
403     (global.set $a (call_indirect (type $over-f64) (f64.const 1.0) (i32.const 7)))
404     (global.get $a)
405   )
406
407   (func (export "as-load-operand") (result i32)
408     (i32.load (call_indirect (type $out-i32) (i32.const 0)))
409   )
410
411   (func (export "as-unary-operand") (result f32)
412     (block (result f32)
413       (f32.sqrt
414         (call_indirect (type $over-f32) (f32.const 0x0p+0) (i32.const 6))
415       )
416     )
417   )
418
419   (func (export "as-binary-left") (result i32)
420     (block (result i32)
421       (i32.add
422         (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
423         (i32.const 10)
424       )
425     )
426   )
427   (func (export "as-binary-right") (result i32)
428     (block (result i32)
429       (i32.sub
430         (i32.const 10)
431         (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
432       )
433     )
434   )
435
436   (func (export "as-test-operand") (result i32)
437     (block (result i32)
438       (i32.eqz
439         (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
440       )
441     )
442   )
443
444   (func (export "as-compare-left") (result i32)
445     (block (result i32)
446       (i32.le_u
447         (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
448         (i32.const 10)
449       )
450     )
451   )
452   (func (export "as-compare-right") (result i32)
453     (block (result i32)
454       (i32.ne
455         (i32.const 10)
456         (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
457       )
458     )
459   )
460
461   (func (export "as-convert-operand") (result i64)
462     (block (result i64)
463       (i64.extend_i32_s
464         (call_indirect (type $over-i32) (i32.const 1) (i32.const 4))
465       )
466     )
467   )
468
469 )
470
471 (assert_return (invoke "type-i32") (i32.const 0x132))
472 (assert_return (invoke "type-i64") (i64.const 0x164))
473 (assert_return (invoke "type-f32") (f32.const 0xf32))
474 (assert_return (invoke "type-f64") (f64.const 0xf64))
475 (assert_return (invoke "type-f64-i32") (f64.const 0xf64) (i32.const 32))
476
477 (assert_return (invoke "type-index") (i64.const 100))
478
479 (assert_return (invoke "type-first-i32") (i32.const 32))
480 (assert_return (invoke "type-first-i64") (i64.const 64))
481 (assert_return (invoke "type-first-f32") (f32.const 1.32))
482 (assert_return (invoke "type-first-f64") (f64.const 1.64))
483
484 (assert_return (invoke "type-second-i32") (i32.const 32))
485 (assert_return (invoke "type-second-i64") (i64.const 64))
486 (assert_return (invoke "type-second-f32") (f32.const 32))
487 (assert_return (invoke "type-second-f64") (f64.const 64.1))
488
489 (assert_return (invoke "type-all-f64-i32") (f64.const 0xf64) (i32.const 32))
490 (assert_return (invoke "type-all-i32-f64") (i32.const 1) (f64.const 2))
491 (assert_return (invoke "type-all-i32-i64") (i64.const 2) (i32.const 1))
492
493 (assert_return (invoke "dispatch" (i32.const 5) (i64.const 2)) (i64.const 2))
494 (assert_return (invoke "dispatch" (i32.const 5) (i64.const 5)) (i64.const 5))
495 (assert_return (invoke "dispatch" (i32.const 12) (i64.const 5)) (i64.const 120))
496 (assert_return (invoke "dispatch" (i32.const 13) (i64.const 5)) (i64.const 8))
497 (assert_return (invoke "dispatch" (i32.const 20) (i64.const 2)) (i64.const 2))
498 (assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call type mismatch")
499 (assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call type mismatch")
500 (assert_trap (invoke "dispatch" (i32.const 32) (i64.const 2)) "undefined element")
501 (assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element")
502 (assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element")
503
504 (assert_return (invoke "dispatch-structural-i64" (i32.const 5)) (i64.const 9))
505 (assert_return (invoke "dispatch-structural-i64" (i32.const 12)) (i64.const 362880))
506 (assert_return (invoke "dispatch-structural-i64" (i32.const 13)) (i64.const 55))
507 (assert_return (invoke "dispatch-structural-i64" (i32.const 20)) (i64.const 9))
508 (assert_trap (invoke "dispatch-structural-i64" (i32.const 11)) "indirect call type mismatch")
509 (assert_trap (invoke "dispatch-structural-i64" (i32.const 22)) "indirect call type mismatch")
510
511 (assert_return (invoke "dispatch-structural-i32" (i32.const 4)) (i32.const 9))
512 (assert_return (invoke "dispatch-structural-i32" (i32.const 23)) (i32.const 362880))
513 (assert_return (invoke "dispatch-structural-i32" (i32.const 26)) (i32.const 55))
514 (assert_return (invoke "dispatch-structural-i32" (i32.const 19)) (i32.const 9))
515 (assert_trap (invoke "dispatch-structural-i32" (i32.const 9)) "indirect call type mismatch")
516 (assert_trap (invoke "dispatch-structural-i32" (i32.const 21)) "indirect call type mismatch")
517
518 (assert_return (invoke "dispatch-structural-f32" (i32.const 6)) (f32.const 9.0))
519 (assert_return (invoke "dispatch-structural-f32" (i32.const 24)) (f32.const 362880.0))
520 (assert_return (invoke "dispatch-structural-f32" (i32.const 27)) (f32.const 55.0))
521 (assert_return (invoke "dispatch-structural-f32" (i32.const 21)) (f32.const 9.0))
522 (assert_trap (invoke "dispatch-structural-f32" (i32.const 8)) "indirect call type mismatch")
523 (assert_trap (invoke "dispatch-structural-f32" (i32.const 19)) "indirect call type mismatch")
524
525 (assert_return (invoke "dispatch-structural-f64" (i32.const 7)) (f64.const 9.0))
526 (assert_return (invoke "dispatch-structural-f64" (i32.const 25)) (f64.const 362880.0))
527 (assert_return (invoke "dispatch-structural-f64" (i32.const 28)) (f64.const 55.0))
528 (assert_return (invoke "dispatch-structural-f64" (i32.const 22)) (f64.const 9.0))
529 (assert_trap (invoke "dispatch-structural-f64" (i32.const 10)) "indirect call type mismatch")
530 (assert_trap (invoke "dispatch-structural-f64" (i32.const 18)) "indirect call type mismatch")
531
532 (assert_return (invoke "fac-i64" (i64.const 0)) (i64.const 1))
533 (assert_return (invoke "fac-i64" (i64.const 1)) (i64.const 1))
534 (assert_return (invoke "fac-i64" (i64.const 5)) (i64.const 120))
535 (assert_return (invoke "fac-i64" (i64.const 25)) (i64.const 7034535277573963776))
536
537 (assert_return (invoke "fac-i32" (i32.const 0)) (i32.const 1))
538 (assert_return (invoke "fac-i32" (i32.const 1)) (i32.const 1))
539 (assert_return (invoke "fac-i32" (i32.const 5)) (i32.const 120))
540 (assert_return (invoke "fac-i32" (i32.const 10)) (i32.const 3628800))
541
542 (assert_return (invoke "fac-f32" (f32.const 0.0)) (f32.const 1.0))
543 (assert_return (invoke "fac-f32" (f32.const 1.0)) (f32.const 1.0))
544 (assert_return (invoke "fac-f32" (f32.const 5.0)) (f32.const 120.0))
545 (assert_return (invoke "fac-f32" (f32.const 10.0)) (f32.const 3628800.0))
546
547 (assert_return (invoke "fac-f64" (f64.const 0.0)) (f64.const 1.0))
548 (assert_return (invoke "fac-f64" (f64.const 1.0)) (f64.const 1.0))
549 (assert_return (invoke "fac-f64" (f64.const 5.0)) (f64.const 120.0))
550 (assert_return (invoke "fac-f64" (f64.const 10.0)) (f64.const 3628800.0))
551
552 (assert_return (invoke "fib-i64" (i64.const 0)) (i64.const 1))
553 (assert_return (invoke "fib-i64" (i64.const 1)) (i64.const 1))
554 (assert_return (invoke "fib-i64" (i64.const 2)) (i64.const 2))
555 (assert_return (invoke "fib-i64" (i64.const 5)) (i64.const 8))
556 (assert_return (invoke "fib-i64" (i64.const 20)) (i64.const 10946))
557
558 (assert_return (invoke "fib-i32" (i32.const 0)) (i32.const 1))
559 (assert_return (invoke "fib-i32" (i32.const 1)) (i32.const 1))
560 (assert_return (invoke "fib-i32" (i32.const 2)) (i32.const 2))
561 (assert_return (invoke "fib-i32" (i32.const 5)) (i32.const 8))
562 (assert_return (invoke "fib-i32" (i32.const 20)) (i32.const 10946))
563
564 (assert_return (invoke "fib-f32" (f32.const 0.0)) (f32.const 1.0))
565 (assert_return (invoke "fib-f32" (f32.const 1.0)) (f32.const 1.0))
566 (assert_return (invoke "fib-f32" (f32.const 2.0)) (f32.const 2.0))
567 (assert_return (invoke "fib-f32" (f32.const 5.0)) (f32.const 8.0))
568 (assert_return (invoke "fib-f32" (f32.const 20.0)) (f32.const 10946.0))
569
570 (assert_return (invoke "fib-f64" (f64.const 0.0)) (f64.const 1.0))
571 (assert_return (invoke "fib-f64" (f64.const 1.0)) (f64.const 1.0))
572 (assert_return (invoke "fib-f64" (f64.const 2.0)) (f64.const 2.0))
573 (assert_return (invoke "fib-f64" (f64.const 5.0)) (f64.const 8.0))
574 (assert_return (invoke "fib-f64" (f64.const 20.0)) (f64.const 10946.0))
575
576 (assert_return (invoke "even" (i32.const 0)) (i32.const 44))
577 (assert_return (invoke "even" (i32.const 1)) (i32.const 99))
578 (assert_return (invoke "even" (i32.const 100)) (i32.const 44))
579 (assert_return (invoke "even" (i32.const 77)) (i32.const 99))
580 (assert_return (invoke "odd" (i32.const 0)) (i32.const 99))
581 (assert_return (invoke "odd" (i32.const 1)) (i32.const 44))
582 (assert_return (invoke "odd" (i32.const 200)) (i32.const 99))
583 (assert_return (invoke "odd" (i32.const 77)) (i32.const 44))
584
585 (assert_exhaustion (invoke "runaway") "call stack exhausted")
586 (assert_exhaustion (invoke "mutual-runaway") "call stack exhausted")
587
588 (assert_return (invoke "as-select-first") (i32.const 0x132))
589 (assert_return (invoke "as-select-mid") (i32.const 2))
590 (assert_return (invoke "as-select-last") (i32.const 2))
591
592 (assert_return (invoke "as-if-condition") (i32.const 1))
593
594 (assert_return (invoke "as-br_if-first") (i64.const 0x164))
595 (assert_return (invoke "as-br_if-last") (i32.const 2))
596
597 (assert_return (invoke "as-br_table-first") (f32.const 0xf32))
598 (assert_return (invoke "as-br_table-last") (i32.const 2))
599
600 (assert_return (invoke "as-store-first"))
601 (assert_return (invoke "as-store-last"))
602
603 (assert_return (invoke "as-memory.grow-value") (i32.const 1))
604 (assert_return (invoke "as-return-value") (i32.const 1))
605 (assert_return (invoke "as-drop-operand"))
606 (assert_return (invoke "as-br-value") (f32.const 1))
607 (assert_return (invoke "as-local.set-value") (f64.const 1))
608 (assert_return (invoke "as-local.tee-value") (f64.const 1))
609 (assert_return (invoke "as-global.set-value") (f64.const 1.0))
610 (assert_return (invoke "as-load-operand") (i32.const 1))
611
612 (assert_return (invoke "as-unary-operand") (f32.const 0x0p+0))
613 (assert_return (invoke "as-binary-left") (i32.const 11))
614 (assert_return (invoke "as-binary-right") (i32.const 9))
615 (assert_return (invoke "as-test-operand") (i32.const 0))
616 (assert_return (invoke "as-compare-left") (i32.const 1))
617 (assert_return (invoke "as-compare-right") (i32.const 1))
618 (assert_return (invoke "as-convert-operand") (i64.const 1))
619
620
621 ;; Multiple tables
622
623 (module
624   (type $ii-i (func (param i32 i32) (result i32)))
625
626   (table $t1 funcref (elem $f $g))
627   (table $t2 funcref (elem $h $i $j))
628   (table $t3 4 funcref)
629   (elem (table $t3) (i32.const 0) func $g $h)
630   (elem (table $t3) (i32.const 3) func $z)
631
632   (func $f (type $ii-i) (i32.add (local.get 0) (local.get 1)))
633   (func $g (type $ii-i) (i32.sub (local.get 0) (local.get 1)))
634   (func $h (type $ii-i) (i32.mul (local.get 0) (local.get 1)))
635   (func $i (type $ii-i) (i32.div_u (local.get 0) (local.get 1)))
636   (func $j (type $ii-i) (i32.rem_u (local.get 0) (local.get 1)))
637   (func $z)
638
639   (func (export "call-1") (param i32 i32 i32) (result i32)
640     (call_indirect $t1 (type $ii-i) (local.get 0) (local.get 1) (local.get 2))
641   )
642   (func (export "call-2") (param i32 i32 i32) (result i32)
643     (call_indirect $t2 (type $ii-i) (local.get 0) (local.get 1) (local.get 2))
644   )
645   (func (export "call-3") (param i32 i32 i32) (result i32)
646     (call_indirect $t3 (type $ii-i) (local.get 0) (local.get 1) (local.get 2))
647   )
648 )
649
650 (assert_return (invoke "call-1" (i32.const 2) (i32.const 3) (i32.const 0)) (i32.const 5))
651 (assert_return (invoke "call-1" (i32.const 2) (i32.const 3) (i32.const 1)) (i32.const -1))
652 (assert_trap (invoke "call-1" (i32.const 2) (i32.const 3) (i32.const 2)) "undefined element")
653
654 (assert_return (invoke "call-2" (i32.const 2) (i32.const 3) (i32.const 0)) (i32.const 6))
655 (assert_return (invoke "call-2" (i32.const 2) (i32.const 3) (i32.const 1)) (i32.const 0))
656 (assert_return (invoke "call-2" (i32.const 2) (i32.const 3) (i32.const 2)) (i32.const 2))
657 (assert_trap (invoke "call-2" (i32.const 2) (i32.const 3) (i32.const 3)) "undefined element")
658
659 (assert_return (invoke "call-3" (i32.const 2) (i32.const 3) (i32.const 0)) (i32.const -1))
660 (assert_return (invoke "call-3" (i32.const 2) (i32.const 3) (i32.const 1)) (i32.const 6))
661 (assert_trap (invoke "call-3" (i32.const 2) (i32.const 3) (i32.const 2)) "uninitialized element")
662 (assert_trap (invoke "call-3" (i32.const 2) (i32.const 3) (i32.const 3)) "indirect call type mismatch")
663 (assert_trap (invoke "call-3" (i32.const 2) (i32.const 3) (i32.const 4)) "undefined element")
664
665
666 ;; Invalid syntax
667
668 (assert_malformed
669   (module quote
670     "(type $sig (func (param i32) (result i32)))"
671     "(table 0 funcref)"
672     "(func (result i32)"
673     "  (call_indirect (type $sig) (result i32) (param i32)"
674     "    (i32.const 0) (i32.const 0)"
675     "  )"
676     ")"
677   )
678   "unexpected token"
679 )
680 (assert_malformed
681   (module quote
682     "(type $sig (func (param i32) (result i32)))"
683     "(table 0 funcref)"
684     "(func (result i32)"
685     "  (call_indirect (param i32) (type $sig) (result i32)"
686     "    (i32.const 0) (i32.const 0)"
687     "  )"
688     ")"
689   )
690   "unexpected token"
691 )
692 (assert_malformed
693   (module quote
694     "(type $sig (func (param i32) (result i32)))"
695     "(table 0 funcref)"
696     "(func (result i32)"
697     "  (call_indirect (param i32) (result i32) (type $sig)"
698     "    (i32.const 0) (i32.const 0)"
699     "  )"
700     ")"
701   )
702   "unexpected token"
703 )
704 (assert_malformed
705   (module quote
706     "(type $sig (func (param i32) (result i32)))"
707     "(table 0 funcref)"
708     "(func (result i32)"
709     "  (call_indirect (result i32) (type $sig) (param i32)"
710     "    (i32.const 0) (i32.const 0)"
711     "  )"
712     ")"
713   )
714   "unexpected token"
715 )
716 (assert_malformed
717   (module quote
718     "(type $sig (func (param i32) (result i32)))"
719     "(table 0 funcref)"
720     "(func (result i32)"
721     "  (call_indirect (result i32) (param i32) (type $sig)"
722     "    (i32.const 0) (i32.const 0)"
723     "  )"
724     ")"
725   )
726   "unexpected token"
727 )
728 (assert_malformed
729   (module quote
730     "(table 0 funcref)"
731     "(func (result i32)"
732     "  (call_indirect (result i32) (param i32) (i32.const 0) (i32.const 0))"
733     ")"
734   )
735   "unexpected token"
736 )
737
738 (assert_malformed
739   (module quote
740     "(table 0 funcref)"
741     "(func (call_indirect (param $x i32) (i32.const 0) (i32.const 0)))"
742   )
743   "unexpected token"
744 )
745 (assert_malformed
746   (module quote
747     "(type $sig (func))"
748     "(table 0 funcref)"
749     "(func (result i32)"
750     "  (call_indirect (type $sig) (result i32) (i32.const 0))"
751     ")"
752   )
753   "inline function type"
754 )
755 (assert_malformed
756   (module quote
757     "(type $sig (func (param i32) (result i32)))"
758     "(table 0 funcref)"
759     "(func (result i32)"
760     "  (call_indirect (type $sig) (result i32) (i32.const 0))"
761     ")"
762   )
763   "inline function type"
764 )
765 (assert_malformed
766   (module quote
767     "(type $sig (func (param i32) (result i32)))"
768     "(table 0 funcref)"
769     "(func"
770     "  (call_indirect (type $sig) (param i32) (i32.const 0) (i32.const 0))"
771     ")"
772   )
773   "inline function type"
774 )
775 (assert_malformed
776   (module quote
777     "(type $sig (func (param i32 i32) (result i32)))"
778     "(table 0 funcref)"
779     "(func (result i32)"
780     "  (call_indirect (type $sig) (param i32) (result i32)"
781     "    (i32.const 0) (i32.const 0)"
782     "  )"
783     ")"
784   )
785   "inline function type"
786 )
787
788 ;; Invalid typing
789
790 (assert_invalid
791   (module
792     (type (func))
793     (func $no-table (call_indirect (type 0) (i32.const 0)))
794   )
795   "unknown table"
796 )
797
798 (assert_invalid
799   (module
800     (type (func))
801     (table 0 funcref)
802     (func $type-void-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0))))
803   )
804   "type mismatch"
805 )
806 (assert_invalid
807   (module
808     (type (func (result i64)))
809     (table 0 funcref)
810     (func $type-num-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0))))
811   )
812   "type mismatch"
813 )
814
815 (assert_invalid
816   (module
817     (type (func (param i32)))
818     (table 0 funcref)
819     (func $arity-0-vs-1 (call_indirect (type 0) (i32.const 0)))
820   )
821   "type mismatch"
822 )
823 (assert_invalid
824   (module
825     (type (func (param f64 i32)))
826     (table 0 funcref)
827     (func $arity-0-vs-2 (call_indirect (type 0) (i32.const 0)))
828   )
829   "type mismatch"
830 )
831 (assert_invalid
832   (module
833     (type (func))
834     (table 0 funcref)
835     (func $arity-1-vs-0 (call_indirect (type 0) (i32.const 1) (i32.const 0)))
836   )
837   "type mismatch"
838 )
839 (assert_invalid
840   (module
841     (type (func))
842     (table 0 funcref)
843     (func $arity-2-vs-0
844       (call_indirect (type 0) (f64.const 2) (i32.const 1) (i32.const 0))
845     )
846   )
847   "type mismatch"
848 )
849
850 (assert_invalid
851   (module
852     (type (func (param i32)))
853     (table 0 funcref)
854     (func $type-func-void-vs-i32 (call_indirect (type 0) (i32.const 1) (nop)))
855   )
856   "type mismatch"
857 )
858 (assert_invalid
859   (module
860     (type (func (param i32)))
861     (table 0 funcref)
862     (func $type-func-num-vs-i32 (call_indirect (type 0) (i32.const 0) (i64.const 1)))
863   )
864   "type mismatch"
865 )
866
867 (assert_invalid
868   (module
869     (type (func (param i32 i32)))
870     (table 0 funcref)
871     (func $type-first-void-vs-num
872       (call_indirect (type 0) (nop) (i32.const 1) (i32.const 0))
873     )
874   )
875   "type mismatch"
876 )
877 (assert_invalid
878   (module
879     (type (func (param i32 i32)))
880     (table 0 funcref)
881     (func $type-second-void-vs-num
882       (call_indirect (type 0) (i32.const 1) (nop) (i32.const 0))
883     )
884   )
885   "type mismatch"
886 )
887 (assert_invalid
888   (module
889     (type (func (param i32 f64)))
890     (table 0 funcref)
891     (func $type-first-num-vs-num
892       (call_indirect (type 0) (f64.const 1) (i32.const 1) (i32.const 0))
893     )
894   )
895   "type mismatch"
896 )
897 (assert_invalid
898   (module
899     (type (func (param f64 i32)))
900     (table 0 funcref)
901     (func $type-second-num-vs-num
902       (call_indirect (type 0) (i32.const 1) (f64.const 1) (i32.const 0))
903     )
904   )
905   "type mismatch"
906 )
907
908 (assert_invalid
909   (module
910     (func $f (param i32))
911     (type $sig (func (param i32)))
912     (table funcref (elem $f))
913     (func $type-first-empty-in-block
914       (block
915         (call_indirect (type $sig) (i32.const 0))
916       )
917     )
918   )
919   "type mismatch"
920 )
921 (assert_invalid
922   (module
923     (func $f (param i32 i32))
924     (type $sig (func (param i32 i32)))
925     (table funcref (elem $f))
926     (func $type-second-empty-in-block
927       (block
928         (call_indirect (type $sig) (i32.const 0) (i32.const 0))
929       )
930     )
931   )
932   "type mismatch"
933 )
934 (assert_invalid
935   (module
936     (func $f (param i32))
937     (type $sig (func (param i32)))
938     (table funcref (elem $f))
939     (func $type-first-empty-in-loop
940       (loop
941         (call_indirect (type $sig) (i32.const 0))
942       )
943     )
944   )
945   "type mismatch"
946 )
947 (assert_invalid
948   (module
949     (func $f (param i32 i32))
950     (type $sig (func (param i32 i32)))
951     (table funcref (elem $f))
952     (func $type-second-empty-in-loop
953       (loop
954         (call_indirect (type $sig) (i32.const 0) (i32.const 0))
955       )
956     )
957   )
958   "type mismatch"
959 )
960 (assert_invalid
961   (module
962     (func $f (param i32))
963     (type $sig (func (param i32)))
964     (table funcref (elem $f))
965     (func $type-first-empty-in-then
966       (i32.const 0) (i32.const 0)
967       (if
968         (then
969           (call_indirect (type $sig) (i32.const 0))
970         )
971       )
972     )
973   )
974   "type mismatch"
975 )
976 (assert_invalid
977   (module
978     (func $f (param i32 i32))
979     (type $sig (func (param i32 i32)))
980     (table funcref (elem $f))
981     (func $type-second-empty-in-then
982       (i32.const 0) (i32.const 0)
983       (if
984         (then
985           (call_indirect (type $sig) (i32.const 0) (i32.const 0))
986         )
987       )
988     )
989   )
990   "type mismatch"
991 )
992
993
994 ;; Unbound type
995
996 (assert_invalid
997   (module
998     (table 0 funcref)
999     (func $unbound-type (call_indirect (type 1) (i32.const 0)))
1000   )
1001   "unknown type"
1002 )
1003 (assert_invalid
1004   (module
1005     (table 0 funcref)
1006     (func $large-type (call_indirect (type 1012321300) (i32.const 0)))
1007   )
1008   "unknown type"
1009 )
1010
1011
1012 ;; Unbound function in table
1013
1014 (assert_invalid
1015   (module (table funcref (elem 0 0)))
1016   "unknown function"
1017 )