1+ (module
2+ (import " env" " print_string" (func $print.string (param i32 i32 )))
3+ (import " env" " print_int" (func $print.int (param i32 )))
4+
5+ (memory $mem 1 )
6+ (export " memory" (memory $mem ))
7+
8+ (data (i32.const 0 ) " Test 1: Basic swap\n " )
9+ (data (i32.const 20 ) " Test 2: Triple return\n " )
10+ (data (i32.const 43 ) " Test 3: Nested calls\n " )
11+ (data (i32.const 65 ) " Test 4: Block multi-value\n " )
12+ (data (i32.const 92 ) " Test 5: Loop multi-value\n " )
13+ (data (i32.const 118 ) " Test 6: If multi-value\n " )
14+ (data (i32.const 142 ) " Test 7: Branch with values\n " )
15+ (data (i32.const 170 ) " Result: " )
16+ (data (i32.const 179 ) " Test 8: br_table multi-value\n " )
17+ (data (i32.const 208 ) " Test 9: Complex composition\n " )
18+
19+ ;; Test 1: two return values (swap)
20+ (func $swap (param i32 i32 ) (result i32 i32 )
21+ (local.get 1 )
22+ (local.get 0 )
23+ )
24+
25+ (func $test_swap (export " test_swap" )
26+ (call $print.string (i32.const 0 ) (i32.const 19 ))
27+
28+ (i32.const 5 )
29+ (i32.const 10 )
30+ (call $swap )
31+
32+ (call $print.string (i32.const 170 ) (i32.const 8 ))
33+ (call $print.int )
34+
35+ (call $print.string (i32.const 170 ) (i32.const 8 ))
36+ (call $print.int )
37+ )
38+
39+ ;; Test 2: three return values
40+ (func $triple (param i32 ) (result i32 i32 i32 )
41+ ;; returns (x, x+10, x+20)
42+ (local.get 0 )
43+ (local.get 0 )
44+ (i32.const 10 )
45+ (i32.add )
46+ (local.get 0 )
47+ (i32.const 20 )
48+ (i32.add )
49+ )
50+
51+ (func $test_triple (export " test_triple" )
52+ (call $print.string (i32.const 20 ) (i32.const 22 ))
53+
54+ (i32.const 5 )
55+ (call $triple )
56+
57+ (call $print.string (i32.const 170 ) (i32.const 8 ))
58+ (call $print.int )
59+ (call $print.string (i32.const 170 ) (i32.const 8 ))
60+ (call $print.int )
61+ (call $print.string (i32.const 170 ) (i32.const 8 ))
62+ (call $print.int )
63+ )
64+
65+ ;; Test 3: nested multi-value calls
66+ (func $add_pair (param i32 i32 ) (result i32 )
67+ (local.get 0 )
68+ (local.get 1 )
69+ (i32.add )
70+ )
71+
72+ (func $test_nested (export " test_nested" )
73+ (call $print.string (i32.const 43 ) (i32.const 21 ))
74+
75+ (i32.const 3 )
76+ (i32.const 7 )
77+ (call $swap )
78+ (call $add_pair )
79+
80+ (call $print.string (i32.const 170 ) (i32.const 8 ))
81+ (call $print.int )
82+ )
83+
84+ ;; Test 4: block with multi-value type
85+ (func $test_block (export " test_block" )
86+ (call $print.string (i32.const 65 ) (i32.const 26 ))
87+
88+ (block (result i32 i32 )
89+ (i32.const 42 )
90+ (i32.const 99 )
91+ )
92+
93+ (call $print.string (i32.const 170 ) (i32.const 8 ))
94+ (call $print.int )
95+ (call $print.string (i32.const 170 ) (i32.const 8 ))
96+ (call $print.int )
97+ )
98+
99+ ;; Test 5: loop with multi-value
100+ (func $test_loop (export " test_loop" )
101+ (local $counter i32 )
102+ (local $val1 i32 )
103+ (local $val2 i32 )
104+ (call $print.string (i32.const 92 ) (i32.const 25 ))
105+
106+ (i32.const 0 )
107+ (local.set $counter )
108+
109+ (i32.const 10 )
110+ (local.set $val1 )
111+ (i32.const 20 )
112+ (local.set $val2 )
113+
114+ ;; loop that accumulates
115+ (block $exit
116+ (loop $continue
117+
118+ (local.get $counter )
119+ (i32.const 3 )
120+ (i32.ge_u )
121+ (br_if $exit )
122+
123+ ;; incr both values
124+ (local.get $val1 )
125+ (i32.const 1 )
126+ (i32.add )
127+ (local.set $val1 )
128+
129+ (local.get $val2 )
130+ (i32.const 2 )
131+ (i32.add )
132+ (local.set $val2 )
133+
134+ ;; incr counter
135+ (local.get $counter )
136+ (i32.const 1 )
137+ (i32.add )
138+ (local.set $counter )
139+
140+ (br $continue )
141+ )
142+ )
143+
144+ ;; get results from loop
145+ (block (result i32 i32 )
146+ (local.get $val1 )
147+ (local.get $val2 )
148+ )
149+
150+ (call $print.string (i32.const 170 ) (i32.const 8 ))
151+ (call $print.int )
152+ (call $print.string (i32.const 170 ) (i32.const 8 ))
153+ (call $print.int )
154+ )
155+
156+ ;; Test 6: if/else with multi-value result
157+ (func $test_if (export " test_if" ) (param i32 )
158+ (call $print.string (i32.const 118 ) (i32.const 23 ))
159+
160+ (local.get 0 )
161+ (if (result i32 i32 )
162+ (then
163+ (i32.const 100 )
164+ (i32.const 200 )
165+ )
166+ (else
167+ (i32.const 300 )
168+ (i32.const 400 )
169+ )
170+ )
171+
172+ (call $print.string (i32.const 170 ) (i32.const 8 ))
173+ (call $print.int )
174+ (call $print.string (i32.const 170 ) (i32.const 8 ))
175+ (call $print.int )
176+ )
177+
178+ ;; Test 7: branch with multi-value preversation
179+ (func $test_branch (export " test_branch" ) (param i32 )
180+ (call $print.string (i32.const 142 ) (i32.const 27 ))
181+
182+ (block (result i32 i32 )
183+ (i32.const 10 )
184+ (i32.const 20 )
185+
186+ (local.get 0 )
187+ (br_if 0 )
188+
189+ ;; if we don't branch, we replace the values
190+ (drop )
191+ (drop )
192+ (i32.const 30 )
193+ (i32.const 40 )
194+ )
195+
196+ (call $print.string (i32.const 170 ) (i32.const 8 ))
197+ (call $print.int )
198+ (call $print.string (i32.const 170 ) (i32.const 8 ))
199+ (call $print.int )
200+ )
201+
202+ ;; Test 8: br_table with multi-value
203+ (func $test_br_table (export " test_br_table" ) (param i32 )
204+ (local $result1 i32 )
205+ (local $result2 i32 )
206+ (call $print.string (i32.const 179 ) (i32.const 29 ))
207+
208+ (block (result i32 i32 )
209+ (block (result i32 i32 )
210+ (block (result i32 i32 )
211+ (i32.const 1 )
212+ (i32.const 2 )
213+
214+ (local.get 0 )
215+ (br_table 0 1 2 2 ) ;; this will branch to case 0, 1, or 2 based on input (with default to 2)
216+ )
217+ ;; case 0
218+ (i32.const 10 )
219+ (i32.add )
220+ (i32.const 10 )
221+ (i32.add )
222+ (br 1 )
223+ )
224+ ;; case 1
225+ (i32.const 20 )
226+ (i32.add )
227+ (i32.const 20 )
228+ (i32.add )
229+ )
230+ ;; case 2 (and default)
231+ (local.set $result2 )
232+ (local.set $result1 )
233+
234+ (call $print.string (i32.const 170 ) (i32.const 8 ))
235+ (local.get $result1 )
236+ (call $print.int )
237+ (call $print.string (i32.const 170 ) (i32.const 8 ))
238+ (local.get $result2 )
239+ (call $print.int )
240+ )
241+
242+ ;; Test 9: complex composition
243+ (func $complex (param i32 i32 ) (result i32 i32 i32 )
244+ ;; returns (a+b, a-b, a*2)
245+ (local.get 0 )
246+ (local.get 1 )
247+ (i32.add )
248+
249+ (local.get 0 )
250+ (local.get 1 )
251+ (i32.sub )
252+
253+ (local.get 0 )
254+ (i32.const 2 )
255+ (i32.mul )
256+ )
257+
258+ (func $test_complex (export " test_complex" )
259+ (call $print.string (i32.const 208 ) (i32.const 28 ))
260+ (i32.const 10 )
261+ (i32.const 3 )
262+ (call $complex )
263+
264+ (i32.add ) ;; 20 + 7 = 27
265+ (i32.mul ) ;; 27 * 13 = 351
266+
267+ (call $print.string (i32.const 170 ) (i32.const 8 ))
268+ (call $print.int )
269+ )
270+
271+
272+ (func $main (export " main" )
273+ (call $test_swap )
274+ (call $test_triple )
275+ (call $test_nested )
276+ (call $test_block )
277+ (call $test_loop )
278+ (call $test_if (i32.const 1 ))
279+ (call $test_if (i32.const 0 ))
280+ (call $test_branch (i32.const 1 ))
281+ (call $test_branch (i32.const 0 ))
282+ (call $test_br_table (i32.const 0 ))
283+ (call $test_br_table (i32.const 1 ))
284+ (call $test_br_table (i32.const 2 ))
285+ (call $test_complex )
286+ )
287+ )
0 commit comments