|
24 | 24 | ;;
|
25 | 25 | ;; (Technically this is control0/prompt0 rather than
|
26 | 26 | ;; control/prompt.)
|
27 |
| - (tag $control (export "control") (param (ref $cont-func))) ;; control : ([cont ([] -> [])] -> []) -> [] |
| 27 | + (tag $control (export "control") (param (ref $cont-cont))) ;; control : ([cont ([] -> [])] -> []) -> [] |
28 | 28 | (func $prompt (export "prompt") (param $nextk (ref null $cont)) ;; prompt : cont ([] -> []) -> []
|
29 |
| - (block $on_control (result (ref $cont-func) (ref $cont)) |
30 |
| - (resume (tag $control $on_control) |
31 |
| - (local.get $nextk)) |
| 29 | + (local $h (ref $cont-cont)) |
| 30 | + (local $k (ref $cont)) |
| 31 | + (block $on_control (result (ref $cont-cont) (ref $cont)) |
| 32 | + (resume $cont (tag $control $on_control) |
| 33 | + (local.get $nextk)) |
32 | 34 | (return)
|
33 | 35 | ) ;; $on_control (param (ref $cont-func) (ref $cont))
|
34 |
| - (let (local $h (ref $cont-func)) (local $k (ref $cont)) |
35 |
| - (call_ref (local.get $k) (local.get $h)) |
36 |
| - ) |
| 36 | + (local.set $k) |
| 37 | + (local.set $h) |
| 38 | + (resume $cont-cont (local.get $k) (local.get $h)) |
37 | 39 | )
|
38 | 40 | )
|
39 | 41 | (register "control")
|
|
57 | 59 |
|
58 | 60 | (func $main (export "main") (param $yield (ref $func)) (param $fork (ref $cont-func))
|
59 | 61 | (call $log (i32.const 0))
|
60 |
| - (call_ref |
61 |
| - (cont.bind (type $cont) (local.get $yield) (local.get $fork) |
62 |
| - (cont.new (type $func-cont-func-cont) (ref.func $thread1))) |
| 62 | + (call_ref $cont-func |
| 63 | + (cont.bind $func-cont-func-cont $cont (local.get $yield) (local.get $fork) |
| 64 | + (cont.new $func-cont-func-cont (ref.func $thread1))) |
63 | 65 | (local.get $fork))
|
64 | 66 | (call $log (i32.const 1))
|
65 |
| - (call_ref |
66 |
| - (cont.bind (type $cont) (local.get $yield) (local.get $fork) |
67 |
| - (cont.new (type $func-cont-func-cont) (ref.func $thread2))) |
| 67 | + (call_ref $cont-func |
| 68 | + (cont.bind $func-cont-func-cont $cont (local.get $yield) (local.get $fork) |
| 69 | + (cont.new $func-cont-func-cont (ref.func $thread2))) |
68 | 70 | (local.get $fork))
|
69 | 71 | (call $log (i32.const 2))
|
70 |
| - (call_ref |
71 |
| - (cont.bind (type $cont) (local.get $yield) (local.get $fork) |
72 |
| - (cont.new (type $func-cont-func-cont) (ref.func $thread3))) |
| 72 | + (call_ref $cont-func |
| 73 | + (cont.bind $func-cont-func-cont $cont (local.get $yield) (local.get $fork) |
| 74 | + (cont.new $func-cont-func-cont (ref.func $thread3))) |
73 | 75 | (local.get $fork))
|
74 | 76 | (call $log (i32.const 3))
|
75 | 77 | )
|
76 | 78 |
|
77 | 79 | (func $thread1 (param $yield (ref $func)) (param $fork (ref $cont-func))
|
78 | 80 | (call $log (i32.const 10))
|
79 |
| - (call_ref (local.get $yield)) |
| 81 | + (call_ref $func (local.get $yield)) |
80 | 82 | (call $log (i32.const 11))
|
81 |
| - (call_ref (local.get $yield)) |
| 83 | + (call_ref $func (local.get $yield)) |
82 | 84 | (call $log (i32.const 12))
|
83 | 85 | )
|
84 | 86 |
|
85 | 87 | (func $thread2 (param $yield (ref $func)) (param $fork (ref $cont-func))
|
86 | 88 | (call $log (i32.const 20))
|
87 |
| - (call_ref (local.get $yield)) |
| 89 | + (call_ref $func (local.get $yield)) |
88 | 90 | (call $log (i32.const 21))
|
89 |
| - (call_ref (local.get $yield)) |
| 91 | + (call_ref $func (local.get $yield)) |
90 | 92 | (call $log (i32.const 22))
|
91 | 93 | )
|
92 | 94 |
|
93 | 95 | (func $thread3 (param $yield (ref $func)) (param $fork (ref $cont-func))
|
94 | 96 | (call $log (i32.const 30))
|
95 |
| - (call_ref (local.get $yield)) |
| 97 | + (call_ref $func (local.get $yield)) |
96 | 98 | (call $log (i32.const 31))
|
97 |
| - (call_ref (local.get $yield)) |
| 99 | + (call_ref $func (local.get $yield)) |
98 | 100 | (call $log (i32.const 32))
|
99 | 101 | )
|
100 | 102 | )
|
|
170 | 172 | (type $func-cont-func-func (func (param (ref $func)) (param (ref $cont-func)))) ;; ([] -> []) -> ([cont ([] -> [])] -> []) -> []
|
171 | 173 | (type $func-cont-func-cont (cont $func-cont-func-func)) ;; cont (([] -> []) -> ([cont ([] -> [])] -> []) -> [])
|
172 | 174 |
|
| 175 | + (type $func-cont-cont (func (param (ref $cont)) (param (ref $cont)))) |
| 176 | + (type $cont-cont-func (cont $func-cont-cont)) |
| 177 | + |
173 | 178 | (func $log (import "spectest" "print_i32") (param i32))
|
174 | 179 |
|
175 | 180 | ;; queue interface
|
|
184 | 189 | $fork-sync $fork-kt $fork-tk $fork-ykt $fork-ytk)
|
185 | 190 |
|
186 | 191 | ;; control/prompt interface
|
187 |
| - (tag $control (import "control" "control") (param (ref $cont-func))) ;; control : ([cont ([] -> [])] -> []) -> [] |
| 192 | + (tag $control (import "control" "control") (param (ref $cont-cont))) ;; control : ([cont ([] -> [])] -> []) -> [] |
188 | 193 | (func $prompt (import "control" "prompt") (param $nextk (ref null $cont))) ;; prompt : cont ([] -> []) -> []
|
189 | 194 |
|
190 | 195 | ;; generic boilerplate scheduler
|
|
215 | 220 | (call $scheduler (local.get $k))
|
216 | 221 | )
|
217 | 222 | (func $yield-sync
|
218 |
| - (suspend $control (ref.func $handle-yield)) |
| 223 | + (suspend $control (cont.new $cont-cont (ref.func $handle-yield))) |
219 | 224 | )
|
220 | 225 | (func $handle-fork-sync (param $t (ref $cont)) (param $k (ref $cont))
|
221 | 226 | (call $enqueue (local.get $t))
|
222 | 227 | (call $scheduler (local.get $k))
|
223 | 228 | )
|
224 | 229 | (func $fork-sync (param $t (ref $cont))
|
225 |
| - (suspend $control (func.bind (type $cont-func) (local.get $t) (ref.func $handle-fork-sync))) |
| 230 | + (suspend $control |
| 231 | + (cont.bind $cont-cont-func $cont-cont (local.get $t) |
| 232 | + (cont.new $cont-cont-func (ref.func $handle-fork-sync)))) |
226 | 233 | )
|
227 | 234 | (func $sync (export "sync") (param $k (ref $func-cont-func-cont))
|
228 | 235 | (call $scheduler
|
229 |
| - (cont.bind (type $cont) (ref.func $yield) (ref.func $fork-sync) (local.get $k))) |
| 236 | + (cont.bind $func-cont-func-cont $cont (ref.func $yield) (ref.func $fork-sync) (local.get $k))) |
230 | 237 | )
|
231 | 238 |
|
232 | 239 | ;; asynchronous yield (used by all asynchronous schedulers)
|
|
235 | 242 | (call $scheduler (call $dequeue))
|
236 | 243 | )
|
237 | 244 | (func $yield
|
238 |
| - (suspend $control (ref.func $handle-yield)) |
| 245 | + (suspend $control (cont.new $cont-cont (ref.func $handle-yield))) |
239 | 246 | )
|
240 | 247 | ;; four asynchronous implementations of fork:
|
241 | 248 | ;; * kt and tk don't yield on encountering a fork
|
|
251 | 258 | (call $scheduler (local.get $k))
|
252 | 259 | )
|
253 | 260 | (func $fork-kt (param $t (ref $cont))
|
254 |
| - (suspend $control (func.bind (type $cont-func) (local.get $t) (ref.func $handle-fork-kt))) |
| 261 | + (suspend $control |
| 262 | + (cont.bind $cont-cont-func $cont-cont (local.get $t) |
| 263 | + (cont.new $cont-cont-func (ref.func $handle-fork-kt)))) |
255 | 264 | )
|
256 | 265 | (func $kt (export "kt") (param $k (ref $func-cont-func-cont))
|
257 | 266 | (call $scheduler
|
258 |
| - (cont.bind (type $cont) (ref.func $yield) (ref.func $fork-kt) (local.get $k))) |
| 267 | + (cont.bind $func-cont-func-cont $cont (ref.func $yield) (ref.func $fork-kt) (local.get $k))) |
259 | 268 | )
|
260 | 269 |
|
261 | 270 | ;; no yield on fork, new thread first
|
|
264 | 273 | (call $scheduler (local.get $t))
|
265 | 274 | )
|
266 | 275 | (func $fork-tk (param $t (ref $cont))
|
267 |
| - (suspend $control (func.bind (type $cont-func) (local.get $t) (ref.func $handle-fork-tk))) |
| 276 | + (suspend $control |
| 277 | + (cont.bind $cont-cont-func $cont-cont (local.get $t) |
| 278 | + (cont.new $cont-cont-func (ref.func $handle-fork-tk)))) |
268 | 279 | )
|
269 | 280 | (func $tk (export "tk") (param $k (ref $func-cont-func-cont))
|
270 | 281 | (call $scheduler
|
271 |
| - (cont.bind (type $cont) (ref.func $yield) (ref.func $fork-tk) (local.get $k))) |
| 282 | + (cont.bind $func-cont-func-cont $cont (ref.func $yield) (ref.func $fork-tk) (local.get $k))) |
272 | 283 | )
|
273 | 284 |
|
274 | 285 | ;; yield on fork, continuation first
|
|
278 | 289 | (call $scheduler (call $dequeue))
|
279 | 290 | )
|
280 | 291 | (func $fork-ykt (param $t (ref $cont))
|
281 |
| - (suspend $control (func.bind (type $cont-func) (local.get $t) (ref.func $handle-fork-ykt))) |
| 292 | + (suspend $control |
| 293 | + (cont.bind $cont-cont-func $cont-cont (local.get $t) |
| 294 | + (cont.new $cont-cont-func (ref.func $handle-fork-ykt)))) |
282 | 295 | )
|
283 | 296 | (func $ykt (export "ykt") (param $k (ref $func-cont-func-cont))
|
284 | 297 | (call $scheduler
|
285 |
| - (cont.bind (type $cont) (ref.func $yield) (ref.func $fork-ykt) (local.get $k))) |
| 298 | + (cont.bind $func-cont-func-cont $cont (ref.func $yield) (ref.func $fork-ykt) (local.get $k))) |
286 | 299 | )
|
287 | 300 |
|
288 | 301 | ;; yield on fork, new thread first
|
|
292 | 305 | (call $scheduler (call $dequeue))
|
293 | 306 | )
|
294 | 307 | (func $fork-ytk (param $t (ref $cont))
|
295 |
| - (suspend $control (func.bind (type $cont-func) (local.get $t) (ref.func $handle-fork-ytk))) |
| 308 | + (suspend $control |
| 309 | + (cont.bind $cont-cont-func $cont-cont (local.get $t) |
| 310 | + (cont.new $cont-cont-func (ref.func $handle-fork-ytk)))) |
296 | 311 | )
|
297 | 312 | (func $ytk (export "ytk") (param $k (ref $func-cont-func-cont))
|
298 | 313 | (call $scheduler
|
299 |
| - (cont.bind (type $cont) (ref.func $yield) (ref.func $fork-ytk) (local.get $k))) |
| 314 | + (cont.bind $func-cont-func-cont $cont (ref.func $yield) (ref.func $fork-ytk) (local.get $k))) |
300 | 315 | )
|
301 | 316 | )
|
302 | 317 | (register "scheduler")
|
|
325 | 340 |
|
326 | 341 | (func $run (export "run")
|
327 | 342 | (call $log (i32.const -1))
|
328 |
| - (call $scheduler-sync (cont.new (type $func-cont-func-cont) (ref.func $main))) |
| 343 | + (call $scheduler-sync (cont.new $func-cont-func-cont (ref.func $main))) |
329 | 344 | (call $log (i32.const -2))
|
330 |
| - (call $scheduler-kt (cont.new (type $func-cont-func-cont) (ref.func $main))) |
| 345 | + (call $scheduler-kt (cont.new $func-cont-func-cont (ref.func $main))) |
331 | 346 | (call $log (i32.const -3))
|
332 |
| - (call $scheduler-tk (cont.new (type $func-cont-func-cont) (ref.func $main))) |
| 347 | + (call $scheduler-tk (cont.new $func-cont-func-cont (ref.func $main))) |
333 | 348 | (call $log (i32.const -4))
|
334 |
| - (call $scheduler-ykt (cont.new (type $func-cont-func-cont) (ref.func $main))) |
| 349 | + (call $scheduler-ykt (cont.new $func-cont-func-cont (ref.func $main))) |
335 | 350 | (call $log (i32.const -5))
|
336 |
| - (call $scheduler-ytk (cont.new (type $func-cont-func-cont) (ref.func $main))) |
| 351 | + (call $scheduler-ytk (cont.new $func-cont-func-cont (ref.func $main))) |
337 | 352 | (call $log (i32.const -6))
|
338 | 353 | )
|
339 | 354 | )
|
|
0 commit comments