Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Normative: Synchronous based on a syntax and module graph
This patch is a variant on tc39#49 which determines which module subgraphs are to be executed synchronously based on syntax (whether the module contains a top-level await syntactically) and the dependency graph (whether it imports a module which contains a top-level await, recursively). This fixed check is designed to be more predictable and analyzable. Abstract module record changes: - The [[Async]] field stores whether this module or dependencies are async. It is expected to be initialized by the Linking phase. - The [[ExecutionPromise]] field stores the Promise related to the evaluation of a module whose [[Async]] field is *true*. - Evaluate() returns a Promise for [[Async]] modules, a completion record for sync modules which throw, or undefined otherwise. Cyclic Module Record changes: - A new [[ModuleAsync]] field stores whether this particular module is asynchronous (dependencies aside). - The ExecuteModule method on Cyclic Module Records takes an argument for the Promise capability, but only if that particular module is [[ModuleAsync]]. - The Link/Instantiate phase is used to propagate the [[Async]] field up the module graph to dependencies. - When there's a cycle, with some modules sync and some async, the whole cycle is considered async, with the Promise of each module set to the entrypoint of the cycle, although the cycle-closing edge will not actually be awaited (since this would be a deadlock). Source Text Module Record changes: - The check for whether a module contains a top-level await locally is in a ContainsAwait algorithm (TBD writing this out, but it should be static since await may not appear in a direct eval) - Module execution works as before if ContainsAwait is false, and works like an async function if ContainsAwait is true. Closes tc39#47, tc39#48, tc39#43
- Loading branch information