...
1(module
2 ;; Recursive factorial
3 (func (export "fac-rec") (param i64) (result i64)
4 (if (result i64) (i64.eq (local.get 0) (i64.const 0))
5 (then (i64.const 1))
6 (else
7 (i64.mul (local.get 0) (call 0 (i64.sub (local.get 0) (i64.const 1))))
8 )
9 )
10 )
11
12 ;; Recursive factorial named
13 (func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64)
14 (if (result i64) (i64.eq (local.get $n) (i64.const 0))
15 (then (i64.const 1))
16 (else
17 (i64.mul
18 (local.get $n)
19 (call $fac-rec-named (i64.sub (local.get $n) (i64.const 1)))
20 )
21 )
22 )
23 )
24
25 ;; Iterative factorial
26 (func (export "fac-iter") (param i64) (result i64)
27 (local i64 i64)
28 (local.set 1 (local.get 0))
29 (local.set 2 (i64.const 1))
30 (block
31 (loop
32 (if
33 (i64.eq (local.get 1) (i64.const 0))
34 (then (br 2))
35 (else
36 (local.set 2 (i64.mul (local.get 1) (local.get 2)))
37 (local.set 1 (i64.sub (local.get 1) (i64.const 1)))
38 )
39 )
40 (br 0)
41 )
42 )
43 (local.get 2)
44 )
45
46 ;; Iterative factorial named
47 (func (export "fac-iter-named") (param $n i64) (result i64)
48 (local $i i64)
49 (local $res i64)
50 (local.set $i (local.get $n))
51 (local.set $res (i64.const 1))
52 (block $done
53 (loop $loop
54 (if
55 (i64.eq (local.get $i) (i64.const 0))
56 (then (br $done))
57 (else
58 (local.set $res (i64.mul (local.get $i) (local.get $res)))
59 (local.set $i (i64.sub (local.get $i) (i64.const 1)))
60 )
61 )
62 (br $loop)
63 )
64 )
65 (local.get $res)
66 )
67
68 ;; Optimized factorial.
69 (func (export "fac-opt") (param i64) (result i64)
70 (local i64)
71 (local.set 1 (i64.const 1))
72 (block
73 (br_if 0 (i64.lt_s (local.get 0) (i64.const 2)))
74 (loop
75 (local.set 1 (i64.mul (local.get 1) (local.get 0)))
76 (local.set 0 (i64.add (local.get 0) (i64.const -1)))
77 (br_if 0 (i64.gt_s (local.get 0) (i64.const 1)))
78 )
79 )
80 (local.get 1)
81 )
82
83 ;; Iterative factorial without locals.
84 (func $pick0 (param i64) (result i64 i64)
85 (local.get 0) (local.get 0)
86 )
87 (func $pick1 (param i64 i64) (result i64 i64 i64)
88 (local.get 0) (local.get 1) (local.get 0)
89 )
90 (func (export "fac-ssa") (param i64) (result i64)
91 (i64.const 1) (local.get 0)
92 (loop $l (param i64 i64) (result i64)
93 (call $pick1) (call $pick1) (i64.mul)
94 (call $pick1) (i64.const 1) (i64.sub)
95 (call $pick0) (i64.const 0) (i64.gt_u)
96 (br_if $l)
97 (drop) (return)
98 )
99 )
100)
101
102(assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776))
103(assert_return (invoke "fac-iter" (i64.const 25)) (i64.const 7034535277573963776))
104(assert_return (invoke "fac-rec-named" (i64.const 25)) (i64.const 7034535277573963776))
105(assert_return (invoke "fac-iter-named" (i64.const 25)) (i64.const 7034535277573963776))
106(assert_return (invoke "fac-opt" (i64.const 25)) (i64.const 7034535277573963776))
107(assert_return (invoke "fac-ssa" (i64.const 25)) (i64.const 7034535277573963776))
108
109(assert_exhaustion (invoke "fac-rec" (i64.const 1073741824)) "call stack exhausted")
View as plain text