Skip to content

Commit

Permalink
Normative: Fix hangs with top-level await (tc39#3357)
Browse files Browse the repository at this point in the history
Closes tc39#3356.

Modules that depend on modules with top-level await but do not
themselves have a top-level await may currently hang. When a module with
TLA finishes evaluating, it triggers evaluation of ancestors modules
that depend on it.

Currently, ancestors that do not have TLA themselves are evaluated and
have their [[Status]] set to ~evaluated~ but incorrectly leaves their
[[AsyncEvaluation]] field unchanged as true. This means subsequent
importers of those ancestors consider them as in the middle of async
evaluation and will wait on them in InnerModuleEvaluation. But since
they are already evaluated, those waits cause a hang.

This PR sets [[AsyncEvaluation]] to false for those ancestors when their
[[Status]] transition to ~evaluated~.

Note that the ancestors that error out during evaluation do not need
this fix because there is a bail-out path for errored out modules in
InnerModuleEvaluation.

 - Set [[AsyncEvaluation]] to false in rejection closure for symmetry
  • Loading branch information
syg authored and ljharb committed Aug 17, 2024
1 parent 14676db commit ac21460
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -26922,6 +26922,7 @@ <h1>
1. If _result_ is an abrupt completion, then
1. Perform AsyncModuleExecutionRejected(_m_, _result_.[[Value]]).
1. Else,
1. Set _m_.[[AsyncEvaluation]] to *false*.
1. Set _m_.[[Status]] to ~evaluated~.
1. If _m_.[[TopLevelCapability]] is not ~empty~, then
1. Assert: _m_.[[CycleRoot]] and _m_ are the same Module Record.
Expand All @@ -26948,6 +26949,8 @@ <h1>
1. Assert: _module_.[[EvaluationError]] is ~empty~.
1. Set _module_.[[EvaluationError]] to ThrowCompletion(_error_).
1. Set _module_.[[Status]] to ~evaluated~.
1. Set _module_.[[AsyncEvaluation]] to *false*.
1. NOTE: _module_.[[AsyncEvaluation]] is set to *false* for symmetry with AsyncModuleExecutionFulfilled. In InnerModuleEvaluation, the value of a module's [[AsyncEvaluation]] internal slot is unused when its [[EvaluationError]] internal slot is not ~empty~.
1. For each Cyclic Module Record _m_ of _module_.[[AsyncParentModules]], do
1. Perform AsyncModuleExecutionRejected(_m_, _error_).
1. If _module_.[[TopLevelCapability]] is not ~empty~, then
Expand Down

0 comments on commit ac21460

Please sign in to comment.