...
1;; Test the element section
2
3;; Syntax
4(module
5 (table $t 10 funcref)
6 (func $f)
7 (func $g)
8
9 ;; Passive
10 (elem funcref)
11 (elem funcref (ref.func $f) (item ref.func $f) (item (ref.null func)) (ref.func $g))
12 (elem func)
13 (elem func $f $f $g $g)
14
15 (elem $p1 funcref)
16 (elem $p2 funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g))
17 (elem $p3 func)
18 (elem $p4 func $f $f $g $g)
19
20 ;; Active
21 (elem (table $t) (i32.const 0) funcref)
22 (elem (table $t) (i32.const 0) funcref (ref.func $f) (ref.null func))
23 (elem (table $t) (i32.const 0) func)
24 (elem (table $t) (i32.const 0) func $f $g)
25 (elem (table $t) (offset (i32.const 0)) funcref)
26 (elem (table $t) (offset (i32.const 0)) func $f $g)
27 (elem (table 0) (i32.const 0) func)
28 (elem (table 0x0) (i32.const 0) func $f $f)
29 (elem (table 0x000) (offset (i32.const 0)) func)
30 (elem (table 0) (offset (i32.const 0)) func $f $f)
31 (elem (table $t) (i32.const 0) func)
32 (elem (table $t) (i32.const 0) func $f $f)
33 (elem (table $t) (offset (i32.const 0)) func)
34 (elem (table $t) (offset (i32.const 0)) func $f $f)
35 (elem (offset (i32.const 0)))
36 (elem (offset (i32.const 0)) funcref (ref.func $f) (ref.null func))
37 (elem (offset (i32.const 0)) func $f $f)
38 (elem (offset (i32.const 0)) $f $f)
39 (elem (i32.const 0))
40 (elem (i32.const 0) funcref (ref.func $f) (ref.null func))
41 (elem (i32.const 0) func $f $f)
42 (elem (i32.const 0) $f $f)
43 (elem (i32.const 0) funcref (item (ref.func $f)) (item (ref.null func)))
44
45 (elem $a1 (table $t) (i32.const 0) funcref)
46 (elem $a2 (table $t) (i32.const 0) funcref (ref.func $f) (ref.null func))
47 (elem $a3 (table $t) (i32.const 0) func)
48 (elem $a4 (table $t) (i32.const 0) func $f $g)
49 (elem $a9 (table $t) (offset (i32.const 0)) funcref)
50 (elem $a10 (table $t) (offset (i32.const 0)) func $f $g)
51 (elem $a11 (table 0) (i32.const 0) func)
52 (elem $a12 (table 0x0) (i32.const 0) func $f $f)
53 (elem $a13 (table 0x000) (offset (i32.const 0)) func)
54 (elem $a14 (table 0) (offset (i32.const 0)) func $f $f)
55 (elem $a15 (table $t) (i32.const 0) func)
56 (elem $a16 (table $t) (i32.const 0) func $f $f)
57 (elem $a17 (table $t) (offset (i32.const 0)) func)
58 (elem $a18 (table $t) (offset (i32.const 0)) func $f $f)
59 (elem $a19 (offset (i32.const 0)))
60 (elem $a20 (offset (i32.const 0)) funcref (ref.func $f) (ref.null func))
61 (elem $a21 (offset (i32.const 0)) func $f $f)
62 (elem $a22 (offset (i32.const 0)) $f $f)
63 (elem $a23 (i32.const 0))
64 (elem $a24 (i32.const 0) funcref (ref.func $f) (ref.null func))
65 (elem $a25 (i32.const 0) func $f $f)
66 (elem $a26 (i32.const 0) $f $f)
67
68 ;; Declarative
69 (elem declare funcref)
70 (elem declare funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g))
71 (elem declare func)
72 (elem declare func $f $f $g $g)
73
74 (elem $d1 declare funcref)
75 (elem $d2 declare funcref (ref.func $f) (ref.func $f) (ref.null func) (ref.func $g))
76 (elem $d3 declare func)
77 (elem $d4 declare func $f $f $g $g)
78)
79
80(module
81 (func $f)
82 (func $g)
83
84 (table $t funcref (elem (ref.func $f) (ref.null func) (ref.func $g)))
85)
86
87
88;; Basic use
89
90(module
91 (table 10 funcref)
92 (func $f)
93 (elem (i32.const 0) $f)
94)
95(module
96 (import "spectest" "table" (table 10 funcref))
97 (func $f)
98 (elem (i32.const 0) $f)
99)
100
101(module
102 (table 10 funcref)
103 (func $f)
104 (elem (i32.const 0) $f)
105 (elem (i32.const 3) $f)
106 (elem (i32.const 7) $f)
107 (elem (i32.const 5) $f)
108 (elem (i32.const 3) $f)
109)
110(module
111 (import "spectest" "table" (table 10 funcref))
112 (func $f)
113 (elem (i32.const 9) $f)
114 (elem (i32.const 3) $f)
115 (elem (i32.const 7) $f)
116 (elem (i32.const 3) $f)
117 (elem (i32.const 5) $f)
118)
119
120(module
121 (global (import "spectest" "global_i32") i32)
122 (table 1000 funcref)
123 (func $f)
124 (elem (global.get 0) $f)
125)
126
127(module
128 (global $g (import "spectest" "global_i32") i32)
129 (table 1000 funcref)
130 (func $f)
131 (elem (global.get $g) $f)
132)
133
134(module
135 (type $out-i32 (func (result i32)))
136 (table 10 funcref)
137 (elem (i32.const 7) $const-i32-a)
138 (elem (i32.const 9) $const-i32-b)
139 (func $const-i32-a (type $out-i32) (i32.const 65))
140 (func $const-i32-b (type $out-i32) (i32.const 66))
141 (func (export "call-7") (type $out-i32)
142 (call_indirect (type $out-i32) (i32.const 7))
143 )
144 (func (export "call-9") (type $out-i32)
145 (call_indirect (type $out-i32) (i32.const 9))
146 )
147)
148(assert_return (invoke "call-7") (i32.const 65))
149(assert_return (invoke "call-9") (i32.const 66))
150
151;; Same as the above, but use ref.null to ensure the elements use exprs.
152;; Note: some tools like wast2json avoid using exprs when possible.
153(module
154 (type $out-i32 (func (result i32)))
155 (table 11 funcref)
156 (elem (i32.const 6) funcref (ref.null func) (ref.func $const-i32-a))
157 (elem (i32.const 9) funcref (ref.func $const-i32-b) (ref.null func))
158 (func $const-i32-a (type $out-i32) (i32.const 65))
159 (func $const-i32-b (type $out-i32) (i32.const 66))
160 (func (export "call-7") (type $out-i32)
161 (call_indirect (type $out-i32) (i32.const 7))
162 )
163 (func (export "call-9") (type $out-i32)
164 (call_indirect (type $out-i32) (i32.const 9))
165 )
166)
167(assert_return (invoke "call-7") (i32.const 65))
168(assert_return (invoke "call-9") (i32.const 66))
169
170(assert_invalid
171 (module (table 1 funcref) (global i32 (i32.const 0)) (elem (global.get 0) $f) (func $f))
172 "unknown global"
173)
174(assert_invalid
175 (module (table 1 funcref) (global $g i32 (i32.const 0)) (elem (global.get $g) $f) (func $f))
176 "unknown global"
177)
178
179
180;; Corner cases
181
182(module
183 (table 10 funcref)
184 (func $f)
185 (elem (i32.const 9) $f)
186)
187(module
188 (import "spectest" "table" (table 10 funcref))
189 (func $f)
190 (elem (i32.const 9) $f)
191)
192
193(module
194 (table 0 funcref)
195 (elem (i32.const 0))
196)
197(module
198 (import "spectest" "table" (table 0 funcref))
199 (elem (i32.const 0))
200)
201
202(module
203 (table 0 0 funcref)
204 (elem (i32.const 0))
205)
206
207(module
208 (table 20 funcref)
209 (elem (i32.const 20))
210)
211
212(module
213 (import "spectest" "table" (table 0 funcref))
214 (func $f)
215 (elem (i32.const 0) $f)
216)
217
218(module
219 (import "spectest" "table" (table 0 100 funcref))
220 (func $f)
221 (elem (i32.const 0) $f)
222)
223
224(module
225 (import "spectest" "table" (table 0 funcref))
226 (func $f)
227 (elem (i32.const 1) $f)
228)
229
230(module
231 (import "spectest" "table" (table 0 30 funcref))
232 (func $f)
233 (elem (i32.const 1) $f)
234)
235
236;; Invalid bounds for elements
237
238(assert_trap
239 (module
240 (table 0 funcref)
241 (func $f)
242 (elem (i32.const 0) $f)
243 )
244 "out of bounds table access"
245)
246
247(assert_trap
248 (module
249 (table 0 0 funcref)
250 (func $f)
251 (elem (i32.const 0) $f)
252 )
253 "out of bounds table access"
254)
255
256(assert_trap
257 (module
258 (table 0 1 funcref)
259 (func $f)
260 (elem (i32.const 0) $f)
261 )
262 "out of bounds table access"
263)
264
265(assert_trap
266 (module
267 (table 0 funcref)
268 (elem (i32.const 1))
269 )
270 "out of bounds table access"
271)
272(assert_trap
273 (module
274 (table 10 funcref)
275 (func $f)
276 (elem (i32.const 10) $f)
277 )
278 "out of bounds table access"
279)
280(assert_trap
281 (module
282 (import "spectest" "table" (table 10 funcref))
283 (func $f)
284 (elem (i32.const 10) $f)
285 )
286 "out of bounds table access"
287)
288
289(assert_trap
290 (module
291 (table 10 20 funcref)
292 (func $f)
293 (elem (i32.const 10) $f)
294 )
295 "out of bounds table access"
296)
297(assert_trap
298 (module
299 (import "spectest" "table" (table 10 funcref))
300 (func $f)
301 (elem (i32.const 10) $f)
302 )
303 "out of bounds table access"
304)
305
306(assert_trap
307 (module
308 (table 10 funcref)
309 (func $f)
310 (elem (i32.const -1) $f)
311 )
312 "out of bounds table access"
313)
314(assert_trap
315 (module
316 (import "spectest" "table" (table 10 funcref))
317 (func $f)
318 (elem (i32.const -1) $f)
319 )
320 "out of bounds table access"
321)
322
323(assert_trap
324 (module
325 (table 10 funcref)
326 (func $f)
327 (elem (i32.const -10) $f)
328 )
329 "out of bounds table access"
330)
331(assert_trap
332 (module
333 (import "spectest" "table" (table 10 funcref))
334 (func $f)
335 (elem (i32.const -10) $f)
336 )
337 "out of bounds table access"
338)
339
340;; Implicitly dropped elements
341
342(module
343 (table 10 funcref)
344 (elem $e (i32.const 0) func $f)
345 (func $f)
346 (func (export "init")
347 (table.init $e (i32.const 0) (i32.const 0) (i32.const 1))
348 )
349)
350(assert_trap (invoke "init") "out of bounds table access")
351
352(module
353 (table 10 funcref)
354 (elem $e declare func $f)
355 (func $f)
356 (func (export "init")
357 (table.init $e (i32.const 0) (i32.const 0) (i32.const 1))
358 )
359)
360(assert_trap (invoke "init") "out of bounds table access")
361
362;; Element without table
363
364(assert_invalid
365 (module
366 (func $f)
367 (elem (i32.const 0) $f)
368 )
369 "unknown table"
370)
371
372;; Invalid offsets
373
374(assert_invalid
375 (module
376 (table 1 funcref)
377 (elem (i64.const 0))
378 )
379 "type mismatch"
380)
381
382(assert_invalid
383 (module
384 (table 1 funcref)
385 (elem (ref.null func))
386 )
387 "type mismatch"
388)
389
390(assert_invalid
391 (module
392 (table 1 funcref)
393 (elem (offset (;empty instruction sequence;)))
394 )
395 "type mismatch"
396)
397
398(assert_invalid
399 (module
400 (table 1 funcref)
401 (elem (offset (i32.const 0) (i32.const 0)))
402 )
403 "type mismatch"
404)
405
406(assert_invalid
407 (module
408 (global (import "test" "global-i32") i32)
409 (table 1 funcref)
410 (elem (offset (global.get 0) (global.get 0)))
411 )
412 "type mismatch"
413)
414
415(assert_invalid
416 (module
417 (global (import "test" "global-i32") i32)
418 (table 1 funcref)
419 (elem (offset (global.get 0) (i32.const 0)))
420 )
421 "type mismatch"
422)
423
424
425(assert_invalid
426 (module
427 (table 1 funcref)
428 (elem (i32.ctz (i32.const 0)))
429 )
430 "constant expression required"
431)
432
433(assert_invalid
434 (module
435 (table 1 funcref)
436 (elem (nop))
437 )
438 "constant expression required"
439)
440
441(assert_invalid
442 (module
443 (table 1 funcref)
444 (elem (offset (nop) (i32.const 0)))
445 )
446 "constant expression required"
447)
448
449(assert_invalid
450 (module
451 (table 1 funcref)
452 (elem (offset (i32.const 0) (nop)))
453 )
454 "constant expression required"
455)
456
457(assert_invalid
458 (module
459 (global $g (import "test" "g") (mut i32))
460 (table 1 funcref)
461 (elem (global.get $g))
462 )
463 "constant expression required"
464)
465
466(assert_invalid
467 (module
468 (table 1 funcref)
469 (elem (global.get 0))
470 )
471 "unknown global 0"
472)
473
474(assert_invalid
475 (module
476 (global (import "test" "global-i32") i32)
477 (table 1 funcref)
478 (elem (global.get 1))
479 )
480 "unknown global 1"
481)
482
483(assert_invalid
484 (module
485 (global (import "test" "global-mut-i32") (mut i32))
486 (table 1 funcref)
487 (elem (global.get 0))
488 )
489 "constant expression required"
490)
491
492;; Invalid elements
493
494(assert_invalid
495 (module
496 (table 1 funcref)
497 (elem (i32.const 0) funcref (ref.null extern))
498 )
499 "type mismatch"
500)
501
502(assert_invalid
503 (module
504 (table 1 funcref)
505 (elem (i32.const 0) funcref (item (ref.null func) (ref.null func)))
506 )
507 "type mismatch"
508)
509
510(assert_invalid
511 (module
512 (table 1 funcref)
513 (elem (i32.const 0) funcref (i32.const 0))
514 )
515 "type mismatch"
516)
517
518(assert_invalid
519 (module
520 (table 1 funcref)
521 (elem (i32.const 0) funcref (item (i32.const 0)))
522 )
523 "type mismatch"
524)
525
526(assert_invalid
527 (module
528 (table 1 funcref)
529 (elem (i32.const 0) funcref (item (call $f)))
530 (func $f (result funcref) (ref.null func))
531 )
532 "constant expression required"
533)
534
535(assert_invalid
536 (module
537 (table 1 funcref)
538 (elem (i32.const 0) funcref (item (i32.add (i32.const 0) (i32.const 1))))
539 )
540 "constant expression required"
541)
542
543;; Two elements target the same slot
544
545(module
546 (type $out-i32 (func (result i32)))
547 (table 10 funcref)
548 (elem (i32.const 9) $const-i32-a)
549 (elem (i32.const 9) $const-i32-b)
550 (func $const-i32-a (type $out-i32) (i32.const 65))
551 (func $const-i32-b (type $out-i32) (i32.const 66))
552 (func (export "call-overwritten") (type $out-i32)
553 (call_indirect (type $out-i32) (i32.const 9))
554 )
555)
556(assert_return (invoke "call-overwritten") (i32.const 66))
557
558(module
559 (type $out-i32 (func (result i32)))
560 (import "spectest" "table" (table 10 funcref))
561 (elem (i32.const 9) $const-i32-a)
562 (elem (i32.const 9) $const-i32-b)
563 (func $const-i32-a (type $out-i32) (i32.const 65))
564 (func $const-i32-b (type $out-i32) (i32.const 66))
565 (func (export "call-overwritten-element") (type $out-i32)
566 (call_indirect (type $out-i32) (i32.const 9))
567 )
568)
569(assert_return (invoke "call-overwritten-element") (i32.const 66))
570
571;; Element sections across multiple modules change the same table
572
573(module $module1
574 (type $out-i32 (func (result i32)))
575 (table (export "shared-table") 10 funcref)
576 (elem (i32.const 8) $const-i32-a)
577 (elem (i32.const 9) $const-i32-b)
578 (func $const-i32-a (type $out-i32) (i32.const 65))
579 (func $const-i32-b (type $out-i32) (i32.const 66))
580 (func (export "call-7") (type $out-i32)
581 (call_indirect (type $out-i32) (i32.const 7))
582 )
583 (func (export "call-8") (type $out-i32)
584 (call_indirect (type $out-i32) (i32.const 8))
585 )
586 (func (export "call-9") (type $out-i32)
587 (call_indirect (type $out-i32) (i32.const 9))
588 )
589)
590
591(register "module1" $module1)
592
593(assert_trap (invoke $module1 "call-7") "uninitialized element")
594(assert_return (invoke $module1 "call-8") (i32.const 65))
595(assert_return (invoke $module1 "call-9") (i32.const 66))
596
597(module $module2
598 (type $out-i32 (func (result i32)))
599 (import "module1" "shared-table" (table 10 funcref))
600 (elem (i32.const 7) $const-i32-c)
601 (elem (i32.const 8) $const-i32-d)
602 (func $const-i32-c (type $out-i32) (i32.const 67))
603 (func $const-i32-d (type $out-i32) (i32.const 68))
604)
605
606(assert_return (invoke $module1 "call-7") (i32.const 67))
607(assert_return (invoke $module1 "call-8") (i32.const 68))
608(assert_return (invoke $module1 "call-9") (i32.const 66))
609
610(module $module3
611 (type $out-i32 (func (result i32)))
612 (import "module1" "shared-table" (table 10 funcref))
613 (elem (i32.const 8) $const-i32-e)
614 (elem (i32.const 9) $const-i32-f)
615 (func $const-i32-e (type $out-i32) (i32.const 69))
616 (func $const-i32-f (type $out-i32) (i32.const 70))
617)
618
619(assert_return (invoke $module1 "call-7") (i32.const 67))
620(assert_return (invoke $module1 "call-8") (i32.const 69))
621(assert_return (invoke $module1 "call-9") (i32.const 70))
622
623;; Element segments must match element type of table
624
625(assert_invalid
626 (module (func $f) (table 1 externref) (elem (i32.const 0) $f))
627 "type mismatch"
628)
629
630(assert_invalid
631 (module (table 1 funcref) (elem (i32.const 0) externref (ref.null extern)))
632 "type mismatch"
633)
634
635(assert_invalid
636 (module
637 (func $f)
638 (table $t 1 externref)
639 (elem $e funcref (ref.func $f))
640 (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1))))
641 "type mismatch"
642)
643
644(assert_invalid
645 (module
646 (table $t 1 funcref)
647 (elem $e externref (ref.null extern))
648 (func (table.init $t $e (i32.const 0) (i32.const 0) (i32.const 1))))
649 "type mismatch"
650)
651
652;; Initializing a table with an externref-type element segment
653
654(module $m
655 (table $t (export "table") 2 externref)
656 (func (export "get") (param $i i32) (result externref)
657 (table.get $t (local.get $i)))
658 (func (export "set") (param $i i32) (param $x externref)
659 (table.set $t (local.get $i) (local.get $x))))
660
661(register "exporter" $m)
662
663(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern))
664(assert_return (invoke $m "get" (i32.const 1)) (ref.null extern))
665
666(assert_return (invoke $m "set" (i32.const 0) (ref.extern 42)))
667(assert_return (invoke $m "set" (i32.const 1) (ref.extern 137)))
668
669(assert_return (invoke $m "get" (i32.const 0)) (ref.extern 42))
670(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137))
671
672(module
673 (import "exporter" "table" (table $t 2 externref))
674 (elem (i32.const 0) externref (ref.null extern)))
675
676(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern))
677(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137))
678
679;; Initializing a table with imported funcref global
680
681(module $module4
682 (func (result i32)
683 i32.const 42
684 )
685 (global (export "f") funcref (ref.func 0))
686)
687
688(register "module4" $module4)
689
690(module
691 (import "module4" "f" (global funcref))
692 (type $out-i32 (func (result i32)))
693 (table 10 funcref)
694 (elem (offset (i32.const 0)) funcref (global.get 0))
695 (func (export "call_imported_elem") (type $out-i32)
696 (call_indirect (type $out-i32) (i32.const 0))
697 )
698)
699
700(assert_return (invoke "call_imported_elem") (i32.const 42))
View as plain text