1;;! component_model_async = true
2;;! multi_memory = true
3;;! reference_types = true
4
5;; backpressure.inc
6(component
7  (core module $m
8    (import "" "backpressure.inc" (func $backpressure-inc))
9  )
10  (core func $backpressure-inc (canon backpressure.inc))
11  (core instance $i (instantiate $m (with "" (instance (export "backpressure.inc" (func $backpressure-inc))))))
12)
13
14;; backpressure.dec
15(component
16  (core module $m
17    (import "" "backpressure.dec" (func $backpressure-dec))
18  )
19  (core func $backpressure-dec (canon backpressure.dec))
20  (core instance $i (instantiate $m (with "" (instance (export "backpressure.dec" (func $backpressure-dec))))))
21)
22
23;; task.return
24(component
25  (core module $m
26    (import "" "task.return" (func $task-return (param i32)))
27  )
28  (core func $task-return (canon task.return (result u32)))
29  (core instance $i (instantiate $m (with "" (instance (export "task.return" (func $task-return))))))
30)
31
32;; waitable-set.wait
33(component
34  (core module $libc (memory (export "memory") 1))
35  (core instance $libc (instantiate $libc))
36  (core module $m
37    (import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i32) (result i32)))
38  )
39  (core func $waitable-set-wait (canon waitable-set.wait (memory $libc "memory")))
40  (core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait))))))
41)
42
43;; waitable-set.poll
44(component
45  (core module $libc (memory (export "memory") 1))
46  (core instance $libc (instantiate $libc))
47  (core module $m
48    (import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i32) (result i32)))
49  )
50  (core func $waitable-set-poll (canon waitable-set.poll (memory $libc "memory")))
51  (core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll))))))
52)
53
54;; thread.yield
55(component
56  (core module $m
57    (import "" "thread.yield" (func $thread-yield (result i32)))
58  )
59  (core func $thread-yield (canon thread.yield))
60  (core instance $i (instantiate $m (with "" (instance (export "thread.yield" (func $thread-yield))))))
61)
62
63;; subtask.drop
64(component
65  (core module $m
66    (import "" "subtask.drop" (func $subtask-drop (param i32)))
67  )
68  (core func $subtask-drop (canon subtask.drop))
69  (core instance $i (instantiate $m (with "" (instance (export "subtask.drop" (func $subtask-drop))))))
70)
71
72;; subtask.cancel
73(component
74  (core module $m
75    (import "" "subtask.cancel" (func $subtask-drop (param i32) (result i32)))
76  )
77  (core func $subtask-cancel (canon subtask.cancel))
78  (core instance $i (instantiate $m (with "" (instance (export "subtask.cancel" (func $subtask-cancel))))))
79)
80
81;; Test that some intrinsics are exempt from may-leave checks
82(component
83  (core func $backpressure.inc (canon backpressure.inc))
84  (core func $backpressure.dec (canon backpressure.dec))
85  (core func $context.get (canon context.get i32 0))
86  (core func $context.set (canon context.set i32 0))
87
88  (core module $DM
89    (import "" "backpressure.inc" (func $backpressure.inc))
90    (import "" "backpressure.dec" (func $backpressure.dec))
91    (import "" "context.get" (func $context.get (result i32)))
92    (import "" "context.set" (func $context.set (param i32)))
93
94    (global $g (mut i32) (i32.const 0))
95
96    (func (export "run")
97      (call $context.set (i32.const 100))
98    )
99    (func (export "post-return")
100      call $backpressure.inc
101      call $backpressure.dec
102
103      ;; context.get should be what was set in `run`
104      call $context.get
105      i32.const 100
106      i32.ne
107      if unreachable end
108
109      i32.const 32
110      call $context.set
111    )
112  )
113  (core instance $dm (instantiate $DM (with "" (instance
114    (export "backpressure.inc" (func $backpressure.inc))
115    (export "backpressure.dec" (func $backpressure.dec))
116    (export "context.get" (func $context.get))
117    (export "context.set" (func $context.set))
118  ))))
119  (func (export "run")
120    (canon lift (core func $dm "run") (post-return (func $dm "post-return"))))
121)
122
123(assert_return (invoke "run"))
124
125;; Test calling intrinsics during `realloc` and their values should be set for
126;; when main function is called
127(component
128  (core func $backpressure.inc (canon backpressure.inc))
129  (core func $backpressure.dec (canon backpressure.dec))
130  (core func $context.get (canon context.get i32 0))
131  (core func $context.set (canon context.set i32 0))
132
133  (core module $libc
134    (import "" "backpressure.inc" (func $backpressure.inc))
135    (import "" "backpressure.dec" (func $backpressure.dec))
136    (import "" "context.get" (func $context.get (result i32)))
137    (import "" "context.set" (func $context.set (param i32)))
138
139    (memory (export "memory") 1)
140    (func (export "realloc") (param i32 i32 i32 i32) (result i32)
141      (if (i32.ne (local.get 0) (i32.const 0)) (then (unreachable)))
142      (if (i32.ne (local.get 1) (i32.const 0)) (then (unreachable)))
143      (if (i32.ne (local.get 2) (i32.const 1)) (then (unreachable)))
144      (if (i32.ne (local.get 3) (i32.const 2)) (then (unreachable)))
145
146      call $context.get
147      i32.const 0
148      i32.ne
149      if unreachable end
150
151      i32.const 100
152      call $context.set
153
154      call $backpressure.inc
155      call $backpressure.dec
156
157      i32.const 200
158    )
159  )
160
161  (core instance $libc (instantiate $libc (with "" (instance
162    (export "backpressure.inc" (func $backpressure.inc))
163    (export "backpressure.dec" (func $backpressure.dec))
164    (export "context.get" (func $context.get))
165    (export "context.set" (func $context.set))
166  ))))
167
168  (core module $M
169    (import "" "backpressure.inc" (func $backpressure.inc))
170    (import "" "backpressure.dec" (func $backpressure.dec))
171    (import "" "context.get" (func $context.get (result i32)))
172    (import "" "context.set" (func $context.set (param i32)))
173
174    (func (export "run") (param i32 i32)
175      ;; ptr/len assertion
176      (if (i32.ne (local.get 0) (i32.const 200)) (then (unreachable)))
177      (if (i32.ne (local.get 1) (i32.const 2)) (then (unreachable)))
178
179      call $backpressure.inc
180      call $backpressure.dec
181
182      ;; context.get should be what was set in `realloc`
183      (if (i32.ne (call $context.get) (i32.const 100)) (then (unreachable)))
184    )
185  )
186  (core instance $m (instantiate $M (with "" (instance
187    (export "backpressure.inc" (func $backpressure.inc))
188    (export "backpressure.dec" (func $backpressure.dec))
189    (export "context.get" (func $context.get))
190    (export "context.set" (func $context.set))
191  ))))
192  (func (export "run") (param "x" string)
193    (canon lift (core func $m "run")
194      (realloc (func $libc "realloc"))
195      (memory $libc "memory")
196    )
197  )
198)
199
200(assert_return (invoke "run" (str.const "hi")))
201
202;; Test when realloc is called to communicate return values that various
203;; intrinsics work and have their expected values.
204(component
205  (component $A
206    (core module $libc (memory (export "memory") 1))
207    (core instance $libc (instantiate $libc))
208
209    (core func $task.return (canon task.return (result string) (memory $libc "memory")))
210
211    (core module $m
212      (import "" "task.return" (func $task.return (param i32 i32)))
213      (import "" "memory" (memory 1))
214      (func (export "run-sync") (result i32)
215        i32.const 40
216        i32.const 100
217        i32.store offset=0
218
219        i32.const 40
220        i32.const 2
221        i32.store offset=4
222
223        i32.const 40
224      )
225      (func (export "run-async") (result i32)
226        i32.const 100
227        i32.const 2
228        call $task.return
229        i32.const 0 ;; CALLBACK_CODE_EXIT
230      )
231
232      (func (export "run-async-cb") (param i32 i32 i32) (result i32) unreachable)
233      (data (i32.const 100) "hi")
234    )
235    (core instance $m (instantiate $m
236      (with "" (instance
237        (export "task.return" (func $task.return))
238        (export "memory" (memory $libc "memory"))
239      ))
240    ))
241    (func (export "run-sync") (result string)
242      (canon lift (core func $m "run-sync") (memory $libc "memory"))
243    )
244    (func (export "run-async") async (result string)
245      (canon lift (core func $m "run-async") (memory $libc "memory") async
246          (callback (func $m "run-async-cb")))
247    )
248  )
249
250  (component $B
251    (import "a" (instance $a
252      (export "run-sync" (func (result string)))
253      (export "run-async" (func async (result string)))
254    ))
255
256    (core func $backpressure.inc (canon backpressure.inc))
257    (core func $backpressure.dec (canon backpressure.dec))
258    (core func $context.get (canon context.get i32 0))
259    (core func $context.set (canon context.set i32 0))
260
261    (core module $libc
262      (import "" "backpressure.inc" (func $backpressure.inc))
263      (import "" "backpressure.dec" (func $backpressure.dec))
264      (import "" "context.get" (func $context.get (result i32)))
265      (import "" "context.set" (func $context.set (param i32)))
266
267      (memory (export "memory") 1)
268      (func (export "realloc") (param i32 i32 i32 i32) (result i32)
269        (if (i32.ne (local.get 0) (i32.const 0)) (then (unreachable)))
270        (if (i32.ne (local.get 1) (i32.const 0)) (then (unreachable)))
271        (if (i32.ne (local.get 2) (i32.const 1)) (then (unreachable)))
272        (if (i32.ne (local.get 3) (i32.const 2)) (then (unreachable)))
273
274        (if (i32.ne (call $context.get) (i32.const 400)) (then (unreachable)))
275        (call $context.set (i32.const 500))
276
277        call $backpressure.inc
278        call $backpressure.dec
279
280        i32.const 200
281      )
282    )
283
284    (core instance $libc (instantiate $libc (with "" (instance
285      (export "backpressure.inc" (func $backpressure.inc))
286      (export "backpressure.dec" (func $backpressure.dec))
287      (export "context.get" (func $context.get))
288      (export "context.set" (func $context.set))
289    ))))
290
291    (core func $sync-to-sync
292      (canon lower (func $a "run-sync")
293        (memory $libc "memory")
294        (realloc (func $libc "realloc"))
295      )
296    )
297    (core func $async-to-sync
298      (canon lower (func $a "run-sync")
299        async
300        (memory $libc "memory")
301        (realloc (func $libc "realloc"))
302      )
303    )
304    (core func $sync-to-async
305      (canon lower (func $a "run-async")
306        (memory $libc "memory")
307        (realloc (func $libc "realloc"))
308      )
309    )
310    (core func $async-to-async
311      (canon lower (func $a "run-async")
312        async
313        (memory $libc "memory")
314        (realloc (func $libc "realloc"))
315      )
316    )
317
318    (core module $M
319      (import "" "context.set" (func $context.set (param i32)))
320      (import "" "context.get" (func $context.get (result i32)))
321      (import "" "sync-to-sync" (func $sync-to-sync (param i32)))
322      (import "" "sync-to-async" (func $sync-to-async (param i32)))
323      (import "" "async-to-sync" (func $async-to-sync (param i32) (result i32)))
324      (import "" "async-to-async" (func $async-to-async (param i32) (result i32)))
325
326      ;; set this tasks's context before calling $run, in calling $run the
327      ;; runtime will then call `realloc` above for the string return value
328      ;; which should see our 400 value. That will then set 500 which we should
329      ;; then see after the return.
330
331      (func (export "sync-to-sync")
332        (call $context.set (i32.const 400))
333        (call $sync-to-sync (i32.const 20))
334        (if (i32.ne (call $context.get) (i32.const 500)) (then (unreachable)))
335      )
336
337      (func (export "sync-to-async")
338        (call $context.set (i32.const 400))
339        (call $sync-to-async (i32.const 20))
340        (if (i32.ne (call $context.get) (i32.const 500)) (then (unreachable)))
341      )
342
343      (func (export "async-to-sync")
344        (call $context.set (i32.const 400))
345        (if
346          (i32.ne
347            (call $async-to-sync (i32.const 20))
348            (i32.const 2) ;; RETURNED
349          )
350          (then (unreachable))
351        )
352        (if (i32.ne (call $context.get) (i32.const 500)) (then (unreachable)))
353      )
354
355      (func (export "async-to-async")
356        (call $context.set (i32.const 400))
357        (if
358          (i32.ne
359            (call $async-to-async (i32.const 20))
360            (i32.const 2) ;; RETURNED
361          )
362          (then (unreachable))
363        )
364        (if (i32.ne (call $context.get) (i32.const 500)) (then (unreachable)))
365      )
366    )
367    (core instance $m (instantiate $M (with "" (instance
368      (export "context.set" (func $context.set))
369      (export "context.get" (func $context.get))
370      (export "sync-to-sync" (func $sync-to-sync))
371      (export "sync-to-async" (func $sync-to-async))
372      (export "async-to-sync" (func $async-to-sync))
373      (export "async-to-async" (func $async-to-async))
374    ))))
375    (func (export "sync-to-sync") async (canon lift (core func $m "sync-to-sync")))
376    (func (export "sync-to-async") async (canon lift (core func $m "sync-to-async")))
377    (func (export "async-to-sync") async (canon lift (core func $m "async-to-sync")))
378    (func (export "async-to-async") async (canon lift (core func $m "async-to-async")))
379  )
380
381  (instance $a (instantiate $A))
382  (instance $b (instantiate $B (with "a" (instance $a))))
383  (export "sync-to-sync" (func $b "sync-to-sync"))
384  (export "sync-to-async" (func $b "sync-to-async"))
385  (export "async-to-sync" (func $b "async-to-sync"))
386  (export "async-to-async" (func $b "async-to-async"))
387)
388
389(assert_return (invoke "sync-to-sync"))
390(assert_return (invoke "sync-to-async"))
391(assert_return (invoke "async-to-sync"))
392(assert_return (invoke "async-to-async"))
393
394;; Same as above, but when calling the host.
395(component
396  (import "host" (instance $host
397    (export "return-hi" (func (result string)))
398  ))
399
400  (core func $backpressure.inc (canon backpressure.inc))
401  (core func $backpressure.dec (canon backpressure.dec))
402  (core func $context.get (canon context.get i32 0))
403  (core func $context.set (canon context.set i32 0))
404
405  (core module $libc
406    (import "" "backpressure.inc" (func $backpressure.inc))
407    (import "" "backpressure.dec" (func $backpressure.dec))
408    (import "" "context.get" (func $context.get (result i32)))
409    (import "" "context.set" (func $context.set (param i32)))
410
411    (memory (export "memory") 1)
412    (func (export "realloc") (param i32 i32 i32 i32) (result i32)
413      (if (i32.ne (local.get 0) (i32.const 0)) (then (unreachable)))
414      (if (i32.ne (local.get 1) (i32.const 0)) (then (unreachable)))
415      (if (i32.ne (local.get 2) (i32.const 1)) (then (unreachable)))
416      (if (i32.ne (local.get 3) (i32.const 2)) (then (unreachable)))
417
418      (if (i32.ne (call $context.get) (i32.const 400)) (then (unreachable)))
419      (call $context.set (i32.const 500))
420
421      call $backpressure.inc
422      call $backpressure.dec
423
424      i32.const 200
425    )
426  )
427
428  (core instance $libc (instantiate $libc (with "" (instance
429    (export "backpressure.inc" (func $backpressure.inc))
430    (export "backpressure.dec" (func $backpressure.dec))
431    (export "context.get" (func $context.get))
432    (export "context.set" (func $context.set))
433  ))))
434
435  (core func $run
436    (canon lower (func $host "return-hi")
437      (memory $libc "memory")
438      (realloc (func $libc "realloc"))
439    )
440  )
441
442  (core module $M
443    (import "" "context.set" (func $context.set (param i32)))
444    (import "" "context.get" (func $context.get (result i32)))
445    (import "" "run" (func $run (param i32)))
446
447    (func (export "run")
448      ;; set this tasks's context before calling $run, in calling $run the
449      ;; runtime will then call `realloc` above for the string return value
450      ;; which should see our 400 value. That will then set 500 which we
451      ;; should then see after the return.
452      (call $context.set (i32.const 400))
453      (call $run (i32.const 20))
454      (if (i32.ne (call $context.get) (i32.const 500)) (then (unreachable)))
455    )
456  )
457  (core instance $m (instantiate $M (with "" (instance
458    (export "context.set" (func $context.set))
459    (export "context.get" (func $context.get))
460    (export "run" (func $run))
461  ))))
462  (func (export "run") (canon lift (core func $m "run")))
463)
464
465(assert_return (invoke "run"))
466