From a966577e62c7c2e9bbbe336036c9954ef6124508 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 2 Feb 2021 13:05:08 +0200 Subject: [PATCH 1/2] replace GetCycleRoot with [[CycleRoot]] field --- spec.html | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/spec.html b/spec.html index f6e1ab8..4011f7a 100644 --- a/spec.html +++ b/spec.html @@ -339,6 +339,17 @@

Cyclic Module Records

A List of all the |ModuleSpecifier| strings used by the module represented by this record to request the importation of a module. The List is source code occurrence ordered. + + + [[CycleRoot]] + + + Cyclic Module Record | *undefined* + + + The first visited module of the cycle, the root DFS ancestor of the strongly connected component. For a module not in a cycle this would be the module itself. + + [[Async]] @@ -517,7 +528,7 @@

Evaluate ( ) Concrete Method

1. Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent. 1. Let _module_ be this Cyclic Module Record. 1. Assert: _module_.[[Status]] is ~linked~ or ~evaluated~. - 1. If _module_.[[Status]] is ~evaluated~, set _module_ to GetAsyncCycleRoot(_module_). + 1. If _module_.[[Status]] is ~evaluated~, set _module_ to _module_.[[CycleRoot]]. 1. If _module_.[[TopLevelCapability]] is not *undefined*, then 1. Return _module_.[[TopLevelCapability]].[[Promise]]. 1. Let _stack_ be a new empty List. @@ -574,7 +585,7 @@

InnerModuleEvaluation ( _module_, _stack_, _index_ )

1. If _requiredModule_.[[Status]] is ~evaluating~, then 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). 1. Otherwise, - 1. Set _requiredModule_ to GetAsyncCycleRoot(_requiredModule_). + 1. Set _requiredModule_ to _requiredModule_.[[CycleRoot]]. 1. Assert: _requiredModule_.[[Status]] is ~evaluated~. 1. If _requiredModule_.[[EvaluationError]] is not *undefined*, return _requiredModule_.[[EvaluationError]]. 1. If _requiredModule_.[[AsyncEvaluating]] is *true*, then @@ -587,6 +598,7 @@

InnerModuleEvaluation ( _module_, _stack_, _index_ )

1. Assert: _module_ occurs exactly once in _stack_. 1. Assert: _module_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSIndex]]. 1. If _module_.[[DFSAncestorIndex]] equals _module_.[[DFSIndex]], then + 1. Let _cycleRoot_ be _module_. 1. Let _done_ be *false*. 1. Repeat, while _done_ is *false*, 1. Let _requiredModule_ be the last element in _stack_. @@ -594,13 +606,14 @@

InnerModuleEvaluation ( _module_, _stack_, _index_ )

1. Assert: _requiredModule_ is a Cyclic Module Record. 1. Set _requiredModule_.[[Status]] to ~evaluated~. 1. If _requiredModule_ and _module_ are the same Module Record, set _done_ to *true*. + 1. Set _requiredModule_.[[CycleRoot]] to _cycleRoot_. 1. Return _index_.

A module is ~evaluating~ while it is being traversed by InnerModuleEvaluation. A module is ~evaluated~ on execution completion and during execution if it is an asynchronous module.

-

Any modules depending on a module of an async cycle when that cycle is not ~evaluating~ will instead depend on the execution of the root of the cycle via GetAsyncCycleRoot. This ensures that the cycle state can be treated as a single strongly connected component through its root module state.

+

Any modules depending on a module of an async cycle when that cycle is not ~evaluating~ will instead depend on the execution of the root of the cycle via [[CycleRoot]]. This ensures that the cycle state can be treated as a single strongly connected component through its root module state.

@@ -639,23 +652,8 @@

ExecuteAsyncModule ( _module_ )

- -

GetAsyncCycleRoot ( _module_ )

- - 1. Assert: _module_.[[Status]] is ~evaluated~. - 1. If _module_.[[AsyncParentModules]] is an empty List, return _module_. - 1. Repeat, while _module_.[[DFSIndex]] is greater than _module_.[[DFSAncestorIndex]], - 1. Assert: _module_.[[AsyncParentModules]] is a non-empty List. - 1. Let _nextCycleModule_ be the first element of _module_.[[AsyncParentModules]]. - 1. Assert: _nextCycleModule_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSAncestorIndex]]. - 1. Set _module_ to _nextCycleModule_. - 1. Assert: _module_.[[DFSIndex]] is equal to _module_.[[DFSAncestorIndex]]. - 1. Return _module_. - -
- - -

AsyncModuleExecutionFulfilled ( _module_ )

+ +

CyclicModuleExecutionFulfilled ( _module_ )

1. Assert: _module_.[[Status]] is ~evaluated~. 1. If _module_.[[AsyncEvaluating]] is *false*, @@ -664,13 +662,10 @@

AsyncModuleExecutionFulfilled ( _module_ )

1. Assert: _module_.[[EvaluationError]] is *undefined*. 1. Set _module_.[[AsyncEvaluating]] to *false*. 1. For each Module _m_ of _module_.[[AsyncParentModules]], do - 1. If _module_.[[DFSIndex]] is not equal to _module_.[[DFSAncestorIndex]], then - 1. Assert: _m_.[[DFSAncestorIndex]] is less than or equal to _module_.[[DFSAncestorIndex]]. 1. Decrement _m_.[[PendingAsyncDependencies]] by 1. 1. If _m_.[[PendingAsyncDependencies]] is 0 and _m_.[[EvaluationError]] is *undefined*, then 1. Assert: _m_.[[AsyncEvaluating]] is *true*. - 1. Let _cycleRoot_ be ! GetAsyncCycleRoot(_m_). - 1. If _cycleRoot_.[[EvaluationError]] is not *undefined*, return *undefined*. + 1. If _m_.[[CycleRoot]].[[EvaluationError]] is not *undefined*, return *undefined*. 1. If _m_.[[Async]] is *true*, then 1. Perform ! ExecuteAsyncModule(_m_). 1. Otherwise, @@ -680,7 +675,7 @@

AsyncModuleExecutionFulfilled ( _module_ )

1. Otherwise, 1. Perform ! AsyncModuleExecutionRejected(_m_, _result_.[[Value]]). 1. If _module_.[[TopLevelCapability]] is not *undefined*, then - 1. Assert: _module_.[[DFSIndex]] is equal to _module_.[[DFSAncestorIndex]]. + 1. Assert: _module_.[[CycleRoot]] is equal to _module_. 1. Perform ! Call(_module_.[[TopLevelCapability]].[[Resolve]], *undefined*, «*undefined*»). 1. Return *undefined*.
@@ -697,11 +692,9 @@

AsyncModuleExecutionRejected ( _module_, _error_ )

1. Set _module_.[[EvaluationError]] to ThrowCompletion(_error_). 1. Set _module_.[[AsyncEvaluating]] to *false*. 1. For each Module _m_ of _module_.[[AsyncParentModules]], do - 1. If _module_.[[DFSIndex]] is not equal to _module_.[[DFSAncestorIndex]], then - 1. Assert: _m_.[[DFSAncestorIndex]] is equal to _module_.[[DFSAncestorIndex]]. 1. Perform ! AsyncModuleExecutionRejected(_m_, _error_). 1. If _module_.[[TopLevelCapability]] is not *undefined*, then - 1. Assert: _module_.[[DFSIndex]] is equal to _module_.[[DFSAncestorIndex]]. + 1. Assert: _module_.[[CycleRoot]] is equal to _module_. 1. Perform ! Call(_module_.[[TopLevelCapability]].[[Reject]], *undefined*, «_error_»). 1. Return *undefined*. @@ -1058,7 +1051,7 @@

ParseModule ( _sourceText_, _realm_, _hostDefined_ )

1. Else, 1. Append _ee_ to _indirectExportEntries_. 1. Let _async_ be _body_ Contains `await`. - 1. Return Source Text Module Record { [[Realm]]: _realm_, [[Environment]]: *undefined*, [[Namespace]]: *undefined*, [[Async]]: _async_, [[AsyncEvaluating]]: *false*, [[TopLevelCapability]]: *undefined*, [[AsyncParentModules]]: *undefined*, [[PendingAsyncDependencies]]: *undefined*, [[Status]]: ~unlinked~, [[EvaluationError]]: *undefined*, [[HostDefined]]: _hostDefined_, [[ECMAScriptCode]]: _body_, [[Context]]: ~empty~, [[ImportMeta]]: ~empty~, [[RequestedModules]]: _requestedModules_, [[ImportEntries]]: _importEntries_, [[LocalExportEntries]]: _localExportEntries_, [[IndirectExportEntries]]: _indirectExportEntries_, [[StarExportEntries]]: _starExportEntries_, [[DFSIndex]]: *undefined*, [[DFSAncestorIndex]]: *undefined* }. + 1. Return Source Text Module Record { [[Realm]]: _realm_, [[Environment]]: *undefined*, [[Namespace]]: *undefined*, [[CycleRoot]]: *undefined*, [[Async]]: _async_, [[AsyncEvaluating]]: *false*, [[TopLevelCapability]]: *undefined*, [[AsyncParentModules]]: *undefined*, [[PendingAsyncDependencies]]: *undefined*, [[Status]]: ~unlinked~, [[EvaluationError]]: *undefined*, [[HostDefined]]: _hostDefined_, [[ECMAScriptCode]]: _body_, [[Context]]: ~empty~, [[ImportMeta]]: ~empty~, [[RequestedModules]]: _requestedModules_, [[ImportEntries]]: _importEntries_, [[LocalExportEntries]]: _localExportEntries_, [[IndirectExportEntries]]: _indirectExportEntries_, [[StarExportEntries]]: _starExportEntries_, [[DFSIndex]]: *undefined*, [[DFSAncestorIndex]]: *undefined* }.

An implementation may parse module source text and analyse it for Early Error conditions prior to the evaluation of ParseModule for that module source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseModule upon that source text.

From efbbe70d6d18295519d0394dfca3516f04e510f0 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 3 Feb 2021 18:03:13 +0200 Subject: [PATCH 2/2] fixup naming issue --- spec.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec.html b/spec.html index 4011f7a..750fdda 100644 --- a/spec.html +++ b/spec.html @@ -652,8 +652,8 @@

ExecuteAsyncModule ( _module_ )

- -

CyclicModuleExecutionFulfilled ( _module_ )

+ +

AsyncModuleExecutionFulfilled ( _module_ )

1. Assert: _module_.[[Status]] is ~evaluated~. 1. If _module_.[[AsyncEvaluating]] is *false*, @@ -681,7 +681,7 @@

CyclicModuleExecutionFulfilled ( _module_ )

- +

AsyncModuleExecutionRejected ( _module_, _error_ )

1. Assert: _module_.[[Status]] is ~evaluated~.