Various edits for correctness - #3
Conversation
guybedford
left a comment
There was a problem hiding this comment.
I finally see what you mean about the sync completions not being attached. Well spotted on that, this looks like a great reworking.
The only issue remaining algorithmically is to fix up the sync state transitions in the completion handlers, which I've commented on.
It all works out really elegantly though otherwise, thanks.
| 1. <ins>If _module_.[[PendingAsyncDependencies]] is 0, then</ins> | ||
| 1. Perform ? _module_.ExecuteModule() | ||
| 1. Perform ! ExecuteCyclicModule(_module_). | ||
| 1. <ins>If _module_.[[EvaluationError]] is not *undefined*, return ThrowCompletion(_module_.[[EvaluationError]].</ins> |
There was a problem hiding this comment.
Missing closing bracket - return ThrowCompletion(_module_.[[EvaluationError]]).
| 1. Let _cycleRoot_ be ! GetCycleRoot(_m_). | ||
| 1. If _cycleRoot_.[[EvaluationError]] is not *undefined*, return *undefined*. | ||
| 1. Perform ! _module_.ExecuteModule(). | ||
| 1. Perform ? ExecuteCyclicModule(_module_). |
| 1. Set _module_.[[Status]] to `"evaluated"`. | ||
| 1. If _module_.[[Async]] is *true*, | ||
| 1. Assert: _module_.[[Status]] is `"evaluating-async"`. | ||
| 1. Set _module_.[[Status]] to `"evaluated"`. |
There was a problem hiding this comment.
A sync parent of an async module wouldn't be transitioned to "evaluated" with this guard.
I think this needs to be:
1. Assert _module_.[[EvaluationError]] is *undefined*.
1. If _module_.[[Status]] is `"instantiating"`, then
1. Assert: _module_.[[Async]] is *false*.
1. Assert: _module_.[[AsyncParentModules]] is an empty List.
1. If _module_.[[Status]] is `"evaluating-async"`, then
1. Set _module_.[[Status]] to `"evaluated"`.
| 1. Set _module_.[[Status]] to `"evaluated"`. | ||
| 1. If _module_.[[Async]] is *true*, | ||
| 1. Assert: _module_.[[Status]] is `"evaluating-async"`. | ||
| 1. Set _module_.[[Status]] to `"evaluated"`. |
There was a problem hiding this comment.
Same comment as with the CyclicModuleExecutionFulfilled case.
| 1. If _result_ is a normal completion, | ||
| 1. Perform ! CyclicModuleExecutionFulfilled(_module_). | ||
| 1. Otherwise, | ||
| 1. Perform ! CyclicModuleExecutionRejected(_module_, _result_.[[Value]]) |
This is important to allow other async module types, such as WebAssembly modules.
This patch ensures that async parent modules are evaluated, when ready, for both [[Async]] and non-[[Async]] modules. A sync module may have async parent modules when it depends on an async module. For example: a.mjs b.mjs c.mjs import "./b.mjs"; import "./c.mjs"; await undefined; In this case, b.mjs will have [[Async]] as false, but it will have a.mjs in its [[AsyncParentModules]]. When c.mjs is done executing, it will run b.mjs. But previously, a.mjs would never be executed. This patch also fixes up the resolution of the top level Promise, which would otherwise be missed in some cases (e.g., it was never resolved for synchronous modules).
|
Merged upstream. |
No description provided.