From e1d09ce920456ed1ea23e57176aba55105624c9a Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Sat, 17 Aug 2024 14:56:13 -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..6adfada2b2 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 the 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