Skip to content

Conversation

nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Jul 3, 2025

This PR separates the logic to perform a depth-first traversal on module graph out of InnerModuleLinking/InnerModuleEvaluation. It has two advantages:

  • it makes it obvious that traversal for linking and evaluation work the same way, since it's not copy&pasted code that needs to be kept in sync
  • especially for evaluation, it disentangles the traversal logic from the "keeping track of top-level await consequences" logic.

Whether this is an improvement or not is subjective (it adds a layer of indirection), so I'm
curious to read the editors opinion about it.

From an editorial/formatting point of view, ModuleGraphDFS is an AO that takes a bunch of callbacks. I've declared them inline in the Link()/Evaluate() concrete methods as abstract closures, even though they don't actually close over anything. I think having them inline rather than as separate AOs makes the reading flow simpler. Ideally, my preferred approach would be something that lets us write

1. Perform ModuleGraphDFS(_module_, _initialStatus_, _pendingStatus_) with
     Action(_m_):
       1. ...
     SCCCompletion(_m_, _sccRoot_):
       1. ...
     PostErrorCleanup(_m_, _errorCompletion_):
       1. ...

I suggest reading this commit-by-commit. The first two commits just move logic around so that what would go in the same AC of the third commit is already all in the same place.

This PR preserves the bugs that would be fixed by #3613 and #3583, but by implementing this PR + those two in engine262 all the tests I have still pass.

The import defer proposal would add a new callback to ModuleGraphDFS, _getModuleDescendants_, that for linking just returns the RequestedModules while for Evaluation it uses import defer's step 11 of https://tc39.es/proposal-defer-import-eval/#sec-innermoduleevaluation (with GatherAsynchronousTransitiveDependencies).

@nicolo-ribaudo nicolo-ribaudo marked this pull request as ready for review July 3, 2025 12:19
@nicolo-ribaudo nicolo-ribaudo force-pushed the extract-dfs-logic-2 branch 2 times, most recently from a4fc0b9 to e2975da Compare July 3, 2025 13:57
@nicolo-ribaudo
Copy link
Member Author

nicolo-ribaudo commented Aug 7, 2025

Marking as draft as:

@nicolo-ribaudo nicolo-ribaudo marked this pull request as draft August 7, 2025 20:53
@bakkot bakkot added the editor call to be discussed in the next editor call label Sep 22, 2025
…loop

Rather than doing it in the DFS recursion loop.

This changes the order in which modules are pushed in [[PendingAsyncDependencies]]:
now they automatically are sorted by their [[AsyncEvaluationOrder]]. It does not
actually matter though, because GatherAvailableAncestors will merge various
[[PendingAsyncDependencies]] lists in a non-order-preserving way so
AsyncModuleExecutionFulfilled still needs to explicitly re-sort the resulting list.
@nicolo-ribaudo nicolo-ribaudo force-pushed the extract-dfs-logic-2 branch 2 times, most recently from 64f28a0 to aa7eab7 Compare September 26, 2025 14:33
Copy link

The rendered spec for this PR is available at https://tc39.es/ecma262/pr/3635.

@nicolo-ribaudo nicolo-ribaudo marked this pull request as ready for review September 26, 2025 14:41
@nicolo-ribaudo nicolo-ribaudo force-pushed the extract-dfs-logic-2 branch 3 times, most recently from 67a4e47 to f945022 Compare September 26, 2025 14:45
This commit deduplicates the logic that is currently both in InnerModuleLinking
and InnerModuleEvaluation, clearly splitting what logic is relative to traversing
the graph and what is relative to actually linking/evaluating modules.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editor call to be discussed in the next editor call
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants