...
1;; Functions
2
3(module $Mf
4 (func (export "call") (result i32) (call $g))
5 (func $g (result i32) (i32.const 2))
6)
7(register "Mf" $Mf)
8
9(module $Nf
10 (func $f (import "Mf" "call") (result i32))
11 (export "Mf.call" (func $f))
12 (func (export "call Mf.call") (result i32) (call $f))
13 (func (export "call") (result i32) (call $g))
14 (func $g (result i32) (i32.const 3))
15)
16
17(assert_return (invoke $Mf "call") (i32.const 2))
18(assert_return (invoke $Nf "Mf.call") (i32.const 2))
19(assert_return (invoke $Nf "call") (i32.const 3))
20(assert_return (invoke $Nf "call Mf.call") (i32.const 2))
21
22(module
23 (import "spectest" "print_i32" (func $f (param i32)))
24 (export "print" (func $f))
25)
26(register "reexport_f")
27(assert_unlinkable
28 (module (import "reexport_f" "print" (func (param i64))))
29 "incompatible import type"
30)
31(assert_unlinkable
32 (module (import "reexport_f" "print" (func (param i32) (result i32))))
33 "incompatible import type"
34)
35
36
37;; Globals
38
39(module $Mg
40 (global $glob (export "glob") i32 (i32.const 42))
41 (func (export "get") (result i32) (global.get $glob))
42
43 ;; export mutable globals
44 (global $mut_glob (export "mut_glob") (mut i32) (i32.const 142))
45 (func (export "get_mut") (result i32) (global.get $mut_glob))
46 (func (export "set_mut") (param i32) (global.set $mut_glob (local.get 0)))
47)
48(register "Mg" $Mg)
49
50(module $Ng
51 (global $x (import "Mg" "glob") i32)
52 (global $mut_glob (import "Mg" "mut_glob") (mut i32))
53 (func $f (import "Mg" "get") (result i32))
54 (func $get_mut (import "Mg" "get_mut") (result i32))
55 (func $set_mut (import "Mg" "set_mut") (param i32))
56
57 (export "Mg.glob" (global $x))
58 (export "Mg.get" (func $f))
59 (global $glob (export "glob") i32 (i32.const 43))
60 (func (export "get") (result i32) (global.get $glob))
61
62 (export "Mg.mut_glob" (global $mut_glob))
63 (export "Mg.get_mut" (func $get_mut))
64 (export "Mg.set_mut" (func $set_mut))
65)
66
67(assert_return (get $Mg "glob") (i32.const 42))
68(assert_return (get $Ng "Mg.glob") (i32.const 42))
69(assert_return (get $Ng "glob") (i32.const 43))
70(assert_return (invoke $Mg "get") (i32.const 42))
71(assert_return (invoke $Ng "Mg.get") (i32.const 42))
72(assert_return (invoke $Ng "get") (i32.const 43))
73
74(assert_return (get $Mg "mut_glob") (i32.const 142))
75(assert_return (get $Ng "Mg.mut_glob") (i32.const 142))
76(assert_return (invoke $Mg "get_mut") (i32.const 142))
77(assert_return (invoke $Ng "Mg.get_mut") (i32.const 142))
78
79(assert_return (invoke $Mg "set_mut" (i32.const 241)))
80(assert_return (get $Mg "mut_glob") (i32.const 241))
81(assert_return (get $Ng "Mg.mut_glob") (i32.const 241))
82(assert_return (invoke $Mg "get_mut") (i32.const 241))
83(assert_return (invoke $Ng "Mg.get_mut") (i32.const 241))
84
85
86(assert_unlinkable
87 (module (import "Mg" "mut_glob" (global i32)))
88 "incompatible import type"
89)
90(assert_unlinkable
91 (module (import "Mg" "glob" (global (mut i32))))
92 "incompatible import type"
93)
94
95;; Tables
96
97(module $Mt
98 (type (func (result i32)))
99 (type (func))
100
101 (table (export "tab") 10 funcref)
102 (elem (i32.const 2) $g $g $g $g)
103 (func $g (result i32) (i32.const 4))
104 (func (export "h") (result i32) (i32.const -4))
105
106 (func (export "call") (param i32) (result i32)
107 (call_indirect (type 0) (local.get 0))
108 )
109)
110(register "Mt" $Mt)
111
112(module $Nt
113 (type (func))
114 (type (func (result i32)))
115
116 (func $f (import "Mt" "call") (param i32) (result i32))
117 (func $h (import "Mt" "h") (result i32))
118
119 (table funcref (elem $g $g $g $h $f))
120 (func $g (result i32) (i32.const 5))
121
122 (export "Mt.call" (func $f))
123 (func (export "call Mt.call") (param i32) (result i32)
124 (call $f (local.get 0))
125 )
126 (func (export "call") (param i32) (result i32)
127 (call_indirect (type 1) (local.get 0))
128 )
129)
130
131(assert_return (invoke $Mt "call" (i32.const 2)) (i32.const 4))
132(assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const 4))
133(assert_return (invoke $Nt "call" (i32.const 2)) (i32.const 5))
134(assert_return (invoke $Nt "call Mt.call" (i32.const 2)) (i32.const 4))
135
136(assert_trap (invoke $Mt "call" (i32.const 1)) "uninitialized")
137(assert_trap (invoke $Nt "Mt.call" (i32.const 1)) "uninitialized")
138(assert_return (invoke $Nt "call" (i32.const 1)) (i32.const 5))
139(assert_trap (invoke $Nt "call Mt.call" (i32.const 1)) "uninitialized")
140
141(assert_trap (invoke $Mt "call" (i32.const 0)) "uninitialized")
142(assert_trap (invoke $Nt "Mt.call" (i32.const 0)) "uninitialized")
143(assert_return (invoke $Nt "call" (i32.const 0)) (i32.const 5))
144(assert_trap (invoke $Nt "call Mt.call" (i32.const 0)) "uninitialized")
145
146(assert_trap (invoke $Mt "call" (i32.const 20)) "undefined")
147(assert_trap (invoke $Nt "Mt.call" (i32.const 20)) "undefined")
148(assert_trap (invoke $Nt "call" (i32.const 7)) "undefined")
149(assert_trap (invoke $Nt "call Mt.call" (i32.const 20)) "undefined")
150
151(assert_return (invoke $Nt "call" (i32.const 3)) (i32.const -4))
152(assert_trap (invoke $Nt "call" (i32.const 4)) "indirect call")
153
154(module $Ot
155 (type (func (result i32)))
156
157 (func $h (import "Mt" "h") (result i32))
158 (table (import "Mt" "tab") 5 funcref)
159 (elem (i32.const 1) $i $h)
160 (func $i (result i32) (i32.const 6))
161
162 (func (export "call") (param i32) (result i32)
163 (call_indirect (type 0) (local.get 0))
164 )
165)
166
167(assert_return (invoke $Mt "call" (i32.const 3)) (i32.const 4))
168(assert_return (invoke $Nt "Mt.call" (i32.const 3)) (i32.const 4))
169(assert_return (invoke $Nt "call Mt.call" (i32.const 3)) (i32.const 4))
170(assert_return (invoke $Ot "call" (i32.const 3)) (i32.const 4))
171
172(assert_return (invoke $Mt "call" (i32.const 2)) (i32.const -4))
173(assert_return (invoke $Nt "Mt.call" (i32.const 2)) (i32.const -4))
174(assert_return (invoke $Nt "call" (i32.const 2)) (i32.const 5))
175(assert_return (invoke $Nt "call Mt.call" (i32.const 2)) (i32.const -4))
176(assert_return (invoke $Ot "call" (i32.const 2)) (i32.const -4))
177
178(assert_return (invoke $Mt "call" (i32.const 1)) (i32.const 6))
179(assert_return (invoke $Nt "Mt.call" (i32.const 1)) (i32.const 6))
180(assert_return (invoke $Nt "call" (i32.const 1)) (i32.const 5))
181(assert_return (invoke $Nt "call Mt.call" (i32.const 1)) (i32.const 6))
182(assert_return (invoke $Ot "call" (i32.const 1)) (i32.const 6))
183
184(assert_trap (invoke $Mt "call" (i32.const 0)) "uninitialized")
185(assert_trap (invoke $Nt "Mt.call" (i32.const 0)) "uninitialized")
186(assert_return (invoke $Nt "call" (i32.const 0)) (i32.const 5))
187(assert_trap (invoke $Nt "call Mt.call" (i32.const 0)) "uninitialized")
188(assert_trap (invoke $Ot "call" (i32.const 0)) "uninitialized")
189
190(assert_trap (invoke $Ot "call" (i32.const 20)) "undefined")
191
192(module
193 (table (import "Mt" "tab") 0 funcref)
194 (elem (i32.const 9) $f)
195 (func $f)
196)
197
198(module $G1 (global (export "g") i32 (i32.const 5)))
199(register "G1" $G1)
200(module $G2
201 (global (import "G1" "g") i32)
202 (global (export "g") i32 (global.get 0))
203)
204(assert_return (get $G2 "g") (i32.const 5))
205
206(assert_unlinkable
207 (module
208 (table (import "Mt" "tab") 0 funcref)
209 (elem (i32.const 10) $f)
210 (func $f)
211 )
212 "elements segment does not fit"
213)
214
215(assert_unlinkable
216 (module
217 (table (import "Mt" "tab") 10 funcref)
218 (memory (import "Mt" "mem") 1) ;; does not exist
219 (func $f (result i32) (i32.const 0))
220 (elem (i32.const 7) $f)
221 (elem (i32.const 9) $f)
222 )
223 "unknown import"
224)
225(assert_trap (invoke $Mt "call" (i32.const 7)) "uninitialized")
226
227(assert_unlinkable
228 (module
229 (table (import "Mt" "tab") 10 funcref)
230 (func $f (result i32) (i32.const 0))
231 (elem (i32.const 7) $f)
232 (elem (i32.const 12) $f) ;; out of bounds
233 )
234 "elements segment does not fit"
235)
236(assert_trap (invoke $Mt "call" (i32.const 7)) "uninitialized")
237
238(assert_unlinkable
239 (module
240 (table (import "Mt" "tab") 10 funcref)
241 (func $f (result i32) (i32.const 0))
242 (elem (i32.const 7) $f)
243 (memory 1)
244 (data (i32.const 0x10000) "d") ;; out of bounds
245 )
246 "data segment does not fit"
247)
248(assert_trap (invoke $Mt "call" (i32.const 7)) "uninitialized")
249
250
251;; Memories
252
253(module $Mm
254 (memory (export "mem") 1 5)
255 (data (i32.const 10) "\00\01\02\03\04\05\06\07\08\09")
256
257 (func (export "load") (param $a i32) (result i32)
258 (i32.load8_u (local.get 0))
259 )
260)
261(register "Mm" $Mm)
262
263(module $Nm
264 (func $loadM (import "Mm" "load") (param i32) (result i32))
265
266 (memory 1)
267 (data (i32.const 10) "\f0\f1\f2\f3\f4\f5")
268
269 (export "Mm.load" (func $loadM))
270 (func (export "load") (param $a i32) (result i32)
271 (i32.load8_u (local.get 0))
272 )
273)
274
275(assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 2))
276(assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 2))
277(assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2))
278
279(module $Om
280 (memory (import "Mm" "mem") 1)
281 (data (i32.const 5) "\a0\a1\a2\a3\a4\a5\a6\a7")
282
283 (func (export "load") (param $a i32) (result i32)
284 (i32.load8_u (local.get 0))
285 )
286)
287
288(assert_return (invoke $Mm "load" (i32.const 12)) (i32.const 0xa7))
289(assert_return (invoke $Nm "Mm.load" (i32.const 12)) (i32.const 0xa7))
290(assert_return (invoke $Nm "load" (i32.const 12)) (i32.const 0xf2))
291(assert_return (invoke $Om "load" (i32.const 12)) (i32.const 0xa7))
292
293(module
294 (memory (import "Mm" "mem") 0)
295 (data (i32.const 0xffff) "a")
296)
297
298(assert_unlinkable
299 (module
300 (memory (import "Mm" "mem") 0)
301 (data (i32.const 0x10000) "a")
302 )
303 "data segment does not fit"
304)
305
306(module $Pm
307 (memory (import "Mm" "mem") 1 8)
308
309 (func (export "grow") (param $a i32) (result i32)
310 (memory.grow (local.get 0))
311 )
312)
313
314(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 1))
315(assert_return (invoke $Pm "grow" (i32.const 2)) (i32.const 1))
316(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 3))
317(assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const 3))
318(assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const 4))
319(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5))
320(assert_return (invoke $Pm "grow" (i32.const 1)) (i32.const -1))
321(assert_return (invoke $Pm "grow" (i32.const 0)) (i32.const 5))
322
323(assert_unlinkable
324 (module
325 (func $host (import "spectest" "print"))
326 (memory (import "Mm" "mem") 1)
327 (table (import "Mm" "tab") 0 funcref) ;; does not exist
328 (data (i32.const 0) "abc")
329 )
330 "unknown import"
331)
332(assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 0))
333
334(assert_unlinkable
335 (module
336 (memory (import "Mm" "mem") 1)
337 (data (i32.const 0) "abc")
338 (data (i32.const 0x50000) "d") ;; out of bounds
339 )
340 "data segment does not fit"
341)
342(assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 0))
343
344(assert_unlinkable
345 (module
346 (memory (import "Mm" "mem") 1)
347 (data (i32.const 0) "abc")
348 (table 0 funcref)
349 (func)
350 (elem (i32.const 0) 0) ;; out of bounds
351 )
352 "elements segment does not fit"
353)
354(assert_return (invoke $Mm "load" (i32.const 0)) (i32.const 0))
355
356;; Store is modified if the start function traps.
357(module $Ms
358 (type $t (func (result i32)))
359 (memory (export "memory") 1)
360 (table (export "table") 1 funcref)
361 (func (export "get memory[0]") (type $t)
362 (i32.load8_u (i32.const 0))
363 )
364 (func (export "get table[0]") (type $t)
365 (call_indirect (type $t) (i32.const 0))
366 )
367)
368(register "Ms" $Ms)
369
370(assert_trap
371 (module
372 (import "Ms" "memory" (memory 1))
373 (import "Ms" "table" (table 1 funcref))
374 (data (i32.const 0) "hello")
375 (elem (i32.const 0) $f)
376 (func $f (result i32)
377 (i32.const 0xdead)
378 )
379 (func $main
380 (unreachable)
381 )
382 (start $main)
383 )
384 "unreachable"
385)
386
387(assert_return (invoke $Ms "get memory[0]") (i32.const 104)) ;; 'h'
388(assert_return (invoke $Ms "get table[0]") (i32.const 0xdead))
View as plain text