1;;! tail_call = true
2;;! reference_types = true
3
4;; Do the following loop: `A.f` indirect tail calls through the table, which is
5;; populated by `B.start` to contain `B.g`, which in turn tail calls `A.f` and
6;; the loop begins again.
7;;
8;; This is smoke testing that tail call chains across Wasm modules really do
9;; have O(1) stack usage.
10
11(module $A
12  (type (func (param i32) (result i32)))
13
14  (table (export "table") 1 1 funcref)
15
16  (func (export "f") (param i32) (result i32)
17    local.get 0
18    i32.eqz
19    if
20      (return (i32.const 42))
21    else
22      (i32.sub (local.get 0) (i32.const 1))
23      i32.const 0
24      return_call_indirect (type 0)
25    end
26    unreachable
27  )
28)
29
30(module $B
31  (import "A" "table" (table $table 1 1 funcref))
32  (import "A" "f" (func $f (param i32) (result i32)))
33
34  (func $g (export "g") (param i32) (result i32)
35    local.get 0
36    return_call $f
37  )
38
39  (func $start
40    (table.set $table (i32.const 0) (ref.func $g))
41  )
42  (start $start)
43)
44
45(assert_return (invoke $B "g" (i32.const 100000))
46               (i32.const 42))
47