From ac21460fedf4b926520b06c9820bdbebad596a8b Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Sat, 17 Aug 2024 15:09:03 -0700 Subject: [PATCH] Normative: Fix hangs with top-level await (#3357) Closes #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 --- spec.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec.html b/spec.html index 0940af6a76..3f95b6d214 100644 --- a/spec.html +++ b/spec.html @@ -26922,6 +26922,7 @@

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. @@ -26948,6 +26949,8 @@

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