2 (type $unop (func (param i32) (result i32)))
5 (func $add (param i32 i32) (result i32) (i32.add (local.get 0) (local.get 1)))
7 (func $mk-adder (param $i i32) (result (ref $unop))
8 (func.bind (type $unop) (local.get $i) (ref.func $add))
11 (global $f (mut (ref null $unop)) (ref.null $unop))
13 (func (export "make") (param $i i32)
14 (global.set $f (call $mk-adder (local.get $i)))
17 (func (export "call") (param $j i32) (result i32)
18 (call_ref (local.get $j) (global.get $f))
21 (func (export "call2") (param $i i32) (param $j i32) (param $k i32) (result i32)
22 (call $mk-adder (local.get $k))
23 (let (result i32) (local $f (ref $unop)) ;; binds $f to top of stack
25 (call_ref (local.get $i) (local.get $f))
26 (call_ref (local.get $j) (local.get $f))
31 (func (export "null") (result i32)
32 (func.bind (type $unop) (i32.const 1) (ref.null $unop))
37 (assert_trap (invoke "call" (i32.const 0)) "null function")
39 (assert_return (invoke "make" (i32.const 3)))
40 (assert_return (invoke "call" (i32.const 2)) (i32.const 5))
41 (assert_return (invoke "call" (i32.const 10)) (i32.const 13))
43 (assert_return (invoke "make" (i32.const 0)))
44 (assert_return (invoke "call" (i32.const 10)) (i32.const 10))
46 (assert_return (invoke "make" (i32.const -3)))
47 (assert_return (invoke "call" (i32.const 10)) (i32.const 7))
49 (assert_return (invoke "call2" (i32.const 2) (i32.const 3) (i32.const 0)) (i32.const 6))
50 (assert_return (invoke "call2" (i32.const 2) (i32.const 5) (i32.const 1)) (i32.const 18))
51 (assert_return (invoke "call2" (i32.const 2) (i32.const 5) (i32.const 7)) (i32.const 108))
53 (assert_trap (invoke "null") "null function")
56 (elem declare func $p $f)
57 (func $p (import "spectest" "print_f64_f64") (param f64 f64))
58 (func $f (param f64 f64 f64 f64) (result f64)
60 (f64.add (f64.mul (local.get 0) (f64.const 1000)))
61 (f64.add (f64.mul (local.get 1) (f64.const 100)))
62 (f64.add (f64.mul (local.get 2) (f64.const 10)))
63 (f64.add (f64.mul (local.get 3) (f64.const 1)))
66 (type $p0 (func (param)))
67 (type $p1 (func (param f64)))
68 (type $p2 (func (param f64 f64)))
69 (type $f0 (func (param) (result f64)))
70 (type $f1 (func (param f64) (result f64)))
71 (type $f2 (func (param f64 f64) (result f64)))
72 (type $f3 (func (param f64 f64 f64) (result f64)))
73 (type $f4 (func (param f64 f64 f64 f64) (result f64)))
75 (table $tp 30 funcref)
76 (table $tf 50 funcref)
78 (func (export "call-p0") (param $i i32)
79 (call_indirect $tp (type $p0) (local.get $i))
81 (func (export "call-p1") (param $i i32) (param f64)
82 (call_indirect $tp (type $p1) (local.get 1) (local.get $i))
84 (func (export "call-p2") (param $i i32) (param f64 f64)
85 (call_indirect $tp (type $p2) (local.get 1) (local.get 2) (local.get $i))
88 (func (export "call-f0") (param $i i32) (result f64)
89 (call_indirect $tf (type $f0) (local.get $i))
91 (func (export "call-f1") (param $i i32) (param f64) (result f64)
92 (call_indirect $tf (type $f1) (local.get 1) (local.get $i))
94 (func (export "call-f2") (param $i i32) (param f64 f64) (result f64)
95 (call_indirect $tf (type $f2) (local.get 1) (local.get 2) (local.get $i))
97 (func (export "call-f3") (param $i i32) (param f64 f64 f64) (result f64)
98 (call_indirect $tf (type $f3) (local.get 1) (local.get 2) (local.get 3) (local.get $i))
100 (func (export "call-f4") (param $i i32) (param f64 f64 f64 f64) (result f64)
101 (call_indirect $tf (type $f4) (local.get 1) (local.get 2) (local.get 3) (local.get 4) (local.get $i))
104 (func (export "init")
105 ;; Host closures with arity 2
106 (table.set $tp (i32.const 20)
109 (table.set $tp (i32.const 21)
110 (func.bind (type $p2)
114 ;; Host closures with arity 1
115 (table.set $tp (i32.const 10)
116 (func.bind (type $p1) (f64.const 1)
119 (table.set $tp (i32.const 11)
120 (func.bind (type $p1) (f64.const 1)
121 (func.bind (type $p2)
124 (table.set $tp (i32.const 12)
125 (func.bind (type $p1)
126 (func.bind (type $p1) (f64.const 1)
127 (func.bind (type $p2)
131 ;; Host closures with arity 0
132 (table.set $tp (i32.const 00)
133 (func.bind (type $p0) (f64.const 1) (f64.const 2)
136 (table.set $tp (i32.const 01)
137 (func.bind (type $p0) (f64.const 2)
138 (func.bind (type $p1) (f64.const 1)
141 (table.set $tp (i32.const 02)
142 (func.bind (type $p0)
143 (func.bind (type $p0) (f64.const 2)
144 (func.bind (type $p1)
145 (func.bind (type $p1) (f64.const 1)
146 (func.bind (type $p2)
147 (func.bind (type $p2)
151 ;; Wasm closures with arity 4
152 (table.set $tf (i32.const 40)
155 (table.set $tf (i32.const 41)
156 (func.bind (type $f4)
160 ;; Wasm closures with arity 3
161 (table.set $tf (i32.const 30)
162 (func.bind (type $f3) (f64.const 1)
165 (table.set $tf (i32.const 31)
166 (func.bind (type $f3) (f64.const 1)
167 (func.bind (type $f4)
170 (table.set $tf (i32.const 32)
171 (func.bind (type $f3)
172 (func.bind (type $f3) (f64.const 1)
173 (func.bind (type $f4)
177 ;; Wasm closures with arity 2
178 (table.set $tf (i32.const 20)
179 (func.bind (type $f2) (f64.const 1) (f64.const 2)
182 (table.set $tf (i32.const 21)
183 (func.bind (type $f2) (f64.const 2)
184 (func.bind (type $f3) (f64.const 1)
187 (table.set $tf (i32.const 22)
188 (func.bind (type $f2)
189 (func.bind (type $f2) (f64.const 2)
190 (func.bind (type $f3)
191 (func.bind (type $f3) (f64.const 1)
192 (func.bind (type $f4)
193 (func.bind (type $f4)
197 ;; Wasm closures with arity 1
198 (table.set $tf (i32.const 10)
199 (func.bind (type $f1) (f64.const 1) (f64.const 2) (f64.const 3)
202 (table.set $tf (i32.const 11)
203 (func.bind (type $f1) (f64.const 2) (f64.const 3)
204 (func.bind (type $f3) (f64.const 1)
207 (table.set $tf (i32.const 12)
208 (func.bind (type $f1) (f64.const 3)
209 (func.bind (type $f2) (f64.const 1) (f64.const 2)
212 (table.set $tf (i32.const 13)
213 (func.bind (type $f1) (f64.const 3)
214 (func.bind (type $f2) (f64.const 2)
215 (func.bind (type $f3) (f64.const 1)
218 (table.set $tf (i32.const 14)
219 (func.bind (type $f1)
220 (func.bind (type $f1)
221 (func.bind (type $f1) (f64.const 3)
222 (func.bind (type $f2)
223 (func.bind (type $f2)
224 (func.bind (type $f2) (f64.const 2)
225 (func.bind (type $f3)
226 (func.bind (type $f3)
227 (func.bind (type $f3) (f64.const 1)
228 (func.bind (type $f4)
229 (func.bind (type $f4)
230 (ref.func $f))))))))))))
233 ;; Wasm closures with arity 0
234 (table.set $tf (i32.const 00)
235 (func.bind (type $f0) (f64.const 1) (f64.const 2) (f64.const 3) (f64.const 4)
238 (table.set $tf (i32.const 01)
239 (func.bind (type $f0) (f64.const 2) (f64.const 3) (f64.const 4)
240 (func.bind (type $f3) (f64.const 1)
243 (table.set $tf (i32.const 02)
244 (func.bind (type $f0) (f64.const 3) (f64.const 4)
245 (func.bind (type $f2) (f64.const 1) (f64.const 2)
248 (table.set $tf (i32.const 03)
249 (func.bind (type $f0) (f64.const 4)
250 (func.bind (type $f1) (f64.const 1) (f64.const 2) (f64.const 3)
253 (table.set $tf (i32.const 04)
254 (func.bind (type $f0) (f64.const 3) (f64.const 4)
255 (func.bind (type $f2) (f64.const 2)
256 (func.bind (type $f3) (f64.const 1)
259 (table.set $tf (i32.const 05)
260 (func.bind (type $f0) (f64.const 4)
261 (func.bind (type $f1) (f64.const 2) (f64.const 3)
262 (func.bind (type $f3) (f64.const 1)
265 (table.set $tf (i32.const 06)
266 (func.bind (type $f0) (f64.const 4)
267 (func.bind (type $f1) (f64.const 3)
268 (func.bind (type $f2) (f64.const 1) (f64.const 2)
271 (table.set $tf (i32.const 07)
272 (func.bind (type $f0) (f64.const 4)
273 (func.bind (type $f1) (f64.const 3)
274 (func.bind (type $f2) (f64.const 2)
275 (func.bind (type $f3) (f64.const 1)
276 (func.bind (type $f4)
279 (table.set $tf (i32.const 08)
280 (func.bind (type $f0)
281 (func.bind (type $f0)
282 (func.bind (type $f0) (f64.const 4)
283 (func.bind (type $f1)
284 (func.bind (type $f1)
285 (func.bind (type $f1) (f64.const 2) (f64.const 3)
286 (func.bind (type $f3)
287 (func.bind (type $f3)
288 (func.bind (type $f3) (f64.const 1)
289 (func.bind (type $f4)
290 (func.bind (type $f4)
291 (ref.func $f))))))))))))
298 (assert_return (invoke "call-p0" (i32.const 00)))
299 (assert_return (invoke "call-p0" (i32.const 01)))
300 (assert_return (invoke "call-p0" (i32.const 02)))
301 (assert_return (invoke "call-p1" (i32.const 10) (f64.const 2)))
302 (assert_return (invoke "call-p1" (i32.const 11) (f64.const 2)))
303 (assert_return (invoke "call-p1" (i32.const 12) (f64.const 2)))
304 (assert_return (invoke "call-p2" (i32.const 20) (f64.const 1) (f64.const 2)))
305 (assert_return (invoke "call-p2" (i32.const 21) (f64.const 1) (f64.const 2)))
307 (assert_return (invoke "call-f0" (i32.const 00)) (f64.const 1234))
308 (assert_return (invoke "call-f0" (i32.const 01)) (f64.const 1234))
309 (assert_return (invoke "call-f0" (i32.const 02)) (f64.const 1234))
310 (assert_return (invoke "call-f0" (i32.const 03)) (f64.const 1234))
311 (assert_return (invoke "call-f0" (i32.const 04)) (f64.const 1234))
312 (assert_return (invoke "call-f0" (i32.const 05)) (f64.const 1234))
313 (assert_return (invoke "call-f0" (i32.const 06)) (f64.const 1234))
314 (assert_return (invoke "call-f0" (i32.const 07)) (f64.const 1234))
315 (assert_return (invoke "call-f0" (i32.const 08)) (f64.const 1234))
316 (assert_return (invoke "call-f1" (i32.const 10) (f64.const 4)) (f64.const 1234))
317 (assert_return (invoke "call-f1" (i32.const 11) (f64.const 4)) (f64.const 1234))
318 (assert_return (invoke "call-f1" (i32.const 12) (f64.const 4)) (f64.const 1234))
319 (assert_return (invoke "call-f1" (i32.const 13) (f64.const 4)) (f64.const 1234))
320 (assert_return (invoke "call-f1" (i32.const 14) (f64.const 4)) (f64.const 1234))
321 (assert_return (invoke "call-f2" (i32.const 20) (f64.const 3) (f64.const 4)) (f64.const 1234))
322 (assert_return (invoke "call-f2" (i32.const 21) (f64.const 3) (f64.const 4)) (f64.const 1234))
323 (assert_return (invoke "call-f2" (i32.const 22) (f64.const 3) (f64.const 4)) (f64.const 1234))
324 (assert_return (invoke "call-f3" (i32.const 30) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234))
325 (assert_return (invoke "call-f3" (i32.const 31) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234))
326 (assert_return (invoke "call-f3" (i32.const 32) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234))
327 (assert_return (invoke "call-f4" (i32.const 40) (f64.const 1) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234))
328 (assert_return (invoke "call-f4" (i32.const 41) (f64.const 1) (f64.const 2) (f64.const 3) (f64.const 4)) (f64.const 1234))
331 (; Once we allow subtyping on function types:
332 ;; The runtime type of a closure is its internal one,
333 ;; not the static bind annotation.
335 (type $ii (func (param i32) (result i32)))
336 (type $fl (func (param i32 anyref) (result (ref null $ii))))
337 (type $fu (func (param i32 (ref $ii)) (result anyref)))
338 (type $fl' (func (param anyref) (result (ref null $ii))))
339 (type $fu' (func (param (ref $ii)) (result anyref)))
341 (elem declare func $sqr $f)
342 (func $sqr (param i32) (result i32) (i32.mul (local.get 0) (local.get 0)))
343 (func $f (type $fl) (ref.func $sqr))
345 (table $t 10 funcref)
347 (func (export "run") (result i32)
348 (table.set $t (i32.const 0) (func.bind (type $fu) (ref.func $f)))
349 (table.set $t (i32.const 1) (func.bind (type $fu') (i32.const 0) (ref.func $f)))
352 (call_ref (i32.const 2)
353 (call_indirect $t (type $fl) (i32.const 0) (ref.null $fl) (i32.const 0))
355 (call_ref (i32.const 3)
356 (call_indirect $t (type $fl') (ref.null $fl') (i32.const 1))
362 (assert_return (invoke "run") (i32.const 13))
365 (; Instead, for now: ;)
368 (type $ii (func (param i32) (result i32)))
369 (type $fl (func (param i32 funcref) (result (ref null $ii))))
370 (type $fu (func (param i32 (ref $ii)) (result funcref)))
372 (elem declare func $sqr $f)
373 (func $sqr (param i32) (result i32) (i32.mul (local.get 0) (local.get 0)))
374 (func $f (type $fl) (ref.func $sqr))
376 (func (drop (func.bind (type $fu) (ref.func $f))))
383 (type $ii (func (param i32) (result i32)))
384 (type $fl (func (param i32 funcref) (result (ref null $ii))))
385 (type $fu' (func (param (ref $ii)) (result funcref)))
387 (elem declare func $sqr $f)
388 (func $sqr (param i32) (result i32) (i32.mul (local.get 0) (local.get 0)))
389 (func $f (type $fl) (ref.func $sqr))
391 (func (drop (func.bind (type $fu') (i32.const 0) (ref.func $f))))
397 ;; Null and unreachable typing.
401 (func (export "null") (result (ref $t))
406 (assert_trap (invoke "null") "null function")
409 (type $t (func (param f32)))
410 (func (export "null") (result (ref $t))
412 (func.bind (type $t))
415 (assert_trap (invoke "null") "null function")
419 (type $t1 (func (param i64)))
420 (func (export "null") (result (ref $t0))
426 (assert_trap (invoke "null") "null function")
430 (type $t1 (func (param i64)))
431 (func (export "null") (result (ref $t0))
434 (func.bind (type $t0))
437 (assert_trap (invoke "null") "null function")
441 (type $t (func (result f32)))
442 (func (export "null") (result i32)
452 (type $t (func (param f32)))
453 (func (export "unreachable") (result (ref $t))
455 (func.bind (type $t))
458 (assert_trap (invoke "unreachable") "unreachable")
461 (type $t (func (param f32) (result i32)))
462 (elem declare func $f)
463 (func $f (param i32 f32) (result i32) (local.get 0))
465 (func (export "unreachable") (result (ref $t))
468 (func.bind (type $t))
471 (assert_trap (invoke "unreachable") "unreachable")
475 (type $t (func (param f32)))
476 (elem declare func $f)
477 (func $f (param i32 f32) (result i32) (local.get 0))
479 (func (export "unreachable") (result (ref $t))
483 (func.bind (type $t))
492 (elem declare func $f)
493 (func $f (param i32) (result i32) (local.get 0))
495 (func (export "unreachable") (result (ref $t))
498 (func.bind (type $t))
508 (func (export "null") (result i32)
518 (type $t (func (param f32)))
519 (elem declare func $f)
520 (func $f (param i32 i32) (result i32) (local.get 0))
522 (func (export "unreachable") (result (ref $t))
525 (func.bind (type $t))