Commit 38f7f58
committed
Prototype support for async native functions
This experiments with enabling support for async NativeFunctions that
are only async from the pov of the host, and appear as synchronous from
within JavaScript.
Instead of running the async functions as a Promise via enqueue_job,
this works by allowing Operations to be executed over multiple VM
cycles, so an Operation may start some async work in one step and then
further steps can poll for completion of that work and finish the Operation.
In particular this works by allowing Call Operations to return an
`OpStatus::Pending`value that indicates that the same Call
operation needs to be executed repeatedly, until it returns an
`OpStatus::Finished` status.
In the case of a `Pending` status, the program counter is reset
and anything that was taken off the stack is pushed back so the same
Operation can be re-executed.
There is a new `NativeFunction::from_async_as_sync_with_captures()`
that lets the host provide a (sync) closure that itself returns / spawns
a boxed Future. This is tracked internally as an `Inner::AsyncFn`.
Whenever the function is `__call__`ed then (assuming the operation isn't
already in a pending / running state) a new Future is spawned via the
application's closure and the Operation enters a "pending" state.
When a NativeFunction is pending then each `__call__` will `poll()` the
spawned `Future` to see if the `async` function has a result.
This effectively stalls the VM at the same Opcode while still accounting
for any cycle budget and periodically yielding to the application's
async runtime while waiting for an async Call Operation to finish.
Limitations / Issues
====================
== Busy Loop Polling ==
Even though the implementation does yield back to the application's
async runtime when waiting for a NativeFunction to complete, the
implementation isn't ideal because it uses a noop task Context
+ Waker when polling NativeFunction Futures. The effectively relies on
the VM polling the future in a busy loop, wasting CPU time.
A better solution could be to implement a shim Waker that would flag
some state on the Boa engine Context, and then adapt the Future that's
used to yield the VM to the executor so that it only becomes Ready once
the async NativeFunction has signalled the waker. I.e. the Waker would
act like a bridge/proxy between a spawned async NativeFunction and the
the Future/Task associated with the VM's async `run_async_with_budget`.
This way I think the VM could remain async runtime agnostic but would
be able to actually sleep while waiting for async functions instead
of entering a busy yield loop.
== Requires PC rewind and reverting stack state ==
Ideally operations that may complete over multiple steps would maintain
a state machine via private registers, whereby it would not be necessary
to repeatedly rewind the program counter and re-push values to the stack
so that the operation can be decoded and executed repeatedly from the
beginning.
== Only adapts Call Operation ==
Currently only the Call Operation handles async NativeFunctions but
there are other Call[XYZ] Operations that could be adapted too.
== Not compatible with composite Operations that `call()` ==
The ability to track pending async functions is implemented in terms of
repeatedly executing an Opcode in the VM until it signals that it's not
Pending.
This currently relies on being able to reset and re-execute the
Operation (such as reverting program counter and stack changes).
There are lots of Operations that make use of JsObject::call()
internally and they would currently trigger a panic if they called an
async NativeFunction because they would not be able to "resolve()"
the "Pending" status that would be returned by the `call()`.
Ideally all Operations that use `__call__` or `__construct__` should
be fully resumable in the same way that the Call Operation is now.
This would presumably be easier to achieve with Rust Coroutines if they
were stable because it would otherwise be necessary to adapt composite
Operations into a state machine, similar to what the compiler does for
an async Future, so they can yield for async function calls and be
resumed by the VM.1 parent e954495 commit 38f7f58
File tree
12 files changed
+574
-112
lines changed- core/engine/src
- native_function
- object/internal_methods
- vm
- opcode
- await
- call
- control_flow
- generator
- examples/src/bin
12 files changed
+574
-112
lines changedLarge diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
406 | 406 | | |
407 | 407 | | |
408 | 408 | | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
409 | 416 | | |
410 | 417 | | |
411 | 418 | | |
412 | 419 | | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
413 | 426 | | |
414 | 427 | | |
415 | 428 | | |
| |||
425 | 438 | | |
426 | 439 | | |
427 | 440 | | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
428 | 458 | | |
| 459 | + | |
429 | 460 | | |
430 | 461 | | |
431 | 462 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
59 | | - | |
| 59 | + | |
| 60 | + | |
60 | 61 | | |
61 | 62 | | |
62 | 63 | | |
| |||
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
68 | | - | |
69 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| |||
76 | 78 | | |
77 | 79 | | |
78 | 80 | | |
79 | | - | |
| 81 | + | |
| 82 | + | |
80 | 83 | | |
81 | 84 | | |
82 | 85 | | |
| |||
87 | 90 | | |
88 | 91 | | |
89 | 92 | | |
90 | | - | |
| 93 | + | |
| 94 | + | |
91 | 95 | | |
92 | | - | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
93 | 116 | | |
94 | 117 | | |
95 | 118 | | |
| |||
101 | 124 | | |
102 | 125 | | |
103 | 126 | | |
104 | | - | |
105 | | - | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
106 | 152 | | |
107 | 153 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
| 139 | + | |
139 | 140 | | |
140 | 141 | | |
141 | 142 | | |
| |||
146 | 147 | | |
147 | 148 | | |
148 | 149 | | |
| 150 | + | |
149 | 151 | | |
150 | 152 | | |
151 | 153 | | |
| |||
244 | 246 | | |
245 | 247 | | |
246 | 248 | | |
| 249 | + | |
247 | 250 | | |
248 | 251 | | |
249 | 252 | | |
250 | 253 | | |
251 | 254 | | |
| 255 | + | |
252 | 256 | | |
253 | 257 | | |
254 | 258 | | |
| |||
298 | 302 | | |
299 | 303 | | |
300 | 304 | | |
301 | | - | |
| 305 | + | |
302 | 306 | | |
303 | | - | |
| 307 | + | |
304 | 308 | | |
305 | 309 | | |
306 | 310 | | |
| |||
375 | 379 | | |
376 | 380 | | |
377 | 381 | | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
378 | 388 | | |
379 | 389 | | |
380 | 390 | | |
381 | 391 | | |
382 | 392 | | |
383 | 393 | | |
384 | | - | |
| 394 | + | |
385 | 395 | | |
386 | | - | |
| 396 | + | |
387 | 397 | | |
388 | 398 | | |
389 | 399 | | |
| |||
393 | 403 | | |
394 | 404 | | |
395 | 405 | | |
396 | | - | |
| 406 | + | |
397 | 407 | | |
398 | | - | |
| 408 | + | |
399 | 409 | | |
400 | 410 | | |
401 | 411 | | |
| |||
422 | 432 | | |
423 | 433 | | |
424 | 434 | | |
425 | | - | |
| 435 | + | |
426 | 436 | | |
427 | 437 | | |
428 | 438 | | |
| |||
451 | 461 | | |
452 | 462 | | |
453 | 463 | | |
454 | | - | |
| 464 | + | |
455 | 465 | | |
456 | 466 | | |
457 | 467 | | |
| |||
461 | 471 | | |
462 | 472 | | |
463 | 473 | | |
464 | | - | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
465 | 478 | | |
466 | 479 | | |
467 | 480 | | |
| |||
475 | 488 | | |
476 | 489 | | |
477 | 490 | | |
478 | | - | |
| 491 | + | |
479 | 492 | | |
480 | 493 | | |
481 | | - | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
482 | 498 | | |
483 | 499 | | |
484 | 500 | | |
| |||
487 | 503 | | |
488 | 504 | | |
489 | 505 | | |
490 | | - | |
| 506 | + | |
491 | 507 | | |
492 | 508 | | |
493 | | - | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
494 | 513 | | |
495 | 514 | | |
496 | 515 | | |
| |||
515 | 534 | | |
516 | 535 | | |
517 | 536 | | |
518 | | - | |
| 537 | + | |
519 | 538 | | |
520 | 539 | | |
521 | 540 | | |
| |||
535 | 554 | | |
536 | 555 | | |
537 | 556 | | |
538 | | - | |
| 557 | + | |
539 | 558 | | |
540 | 559 | | |
541 | 560 | | |
| |||
576 | 595 | | |
577 | 596 | | |
578 | 597 | | |
579 | | - | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
580 | 602 | | |
581 | 603 | | |
582 | 604 | | |
583 | 605 | | |
584 | 606 | | |
| 607 | + | |
585 | 608 | | |
586 | 609 | | |
587 | 610 | | |
| |||
608 | 631 | | |
609 | 632 | | |
610 | 633 | | |
611 | | - | |
| 634 | + | |
612 | 635 | | |
613 | 636 | | |
614 | 637 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | | - | |
| 200 | + | |
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
206 | 206 | | |
207 | | - | |
| 207 | + | |
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
228 | | - | |
| 228 | + | |
229 | 229 | | |
230 | 230 | | |
231 | 231 | | |
| |||
0 commit comments