diff --git a/spec.html b/spec.html index 4c2111e..338d690 100644 --- a/spec.html +++ b/spec.html @@ -40,77 +40,126 @@

AsyncBlockStart ( _promiseCapability_, _asyncBody_, _asyncContext_ ) - -

InnerModuleEvaluation( _module_, _stack_, _index_ )

+ +

Evaluate( ) Concrete Method

-

The InnerModuleEvaluation abstract operation is used by Evaluate to perform the actual evaluation process for the Source Text Module Record _module_, as well as recursively on all other modules in the dependency graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used the same way as in InnerModuleInstantiation.

+

The Evaluate concrete method of a Source Text Module Record implements the corresponding Module Record abstract method.

+

By the time the promise returned by Evaluate settles, Evaluate transitions this module's [[Status]] from `"instantiated"` to `"evaluated"`.

-

This abstract operation performs the following steps:

+

If execution results in an exception, that exception is recorded in the [[EvaluationError]] field and rethrown by future invocations of Evaluate.

+ +

If execution results in a rejected promise, the promise's rejection reason is recorded in the [[EvaluationError]] field. Future invocations of Evaluate will then return a new promise rejected with that same rejection reason.

+ +

This abstract method performs the following steps (most of the work is done by the auxiliary function InnerModuleEvaluation):

- 1. If _module_ is not a Source Text Module Record, then - 1. Perform ? _module_.Evaluate(). - 1. Return _index_. - 1. If _module_.[[Status]] is `"evaluated"`, then - 1. If _module_.[[EvaluationError]] is *undefined*, return _index_. - 1. Otherwise return _module_.[[EvaluationError]]. - 1. If _module_.[[Status]] is `"evaluating"`, return _index_. - 1. Assert: _module_.[[Status]] is `"instantiated"`. - 1. Set _module_.[[Status]] to `"evaluating"`. - 1. Set _module_.[[DFSIndex]] to _index_. - 1. Set _module_.[[DFSAncestorIndex]] to _index_. - 1. Set _index_ to _index_ + 1. - 1. Append _module_ to _stack_. - 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do - 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). - 1. NOTE: Instantiate must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. - 1. Set _index_ to ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_). - 1. Assert: _requiredModule_.[[Status]] is either `"evaluating"` or `"evaluated"`. - 1. Assert: _requiredModule_.[[Status]] is `"evaluating"` if and only if _requiredModule_ is in _stack_. - 1. If _requiredModule_.[[Status]] is `"evaluating"`, then - 1. Assert: _requiredModule_ is a Source Text Module Record. - 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). - 1. Perform ? ModuleExecution(_module_). - 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 _done_ be *false*. - 1. Repeat, while _done_ is *false*, - 1. Let _requiredModule_ be the last element in _stack_. - 1. Remove the last element of _stack_. - 1. Set _requiredModule_.[[Status]] to `"evaluated"`. - 1. If _requiredModule_ and _module_ are the same Module Record, set _done_ to *true*. - 1. Return _index_. + 1. Let _module_ be this Source Text Module Record. + 1. Assert: _module_.[[Status]] is `"instantiated"` or `"evaluated"`. + 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%). + 1. Let _stack_ be a new empty List. + 1. Let _result_ be Await(InnerModuleEvaluation(_module_, _stack_, 0)). + 1. If _result_ is an abrupt completion, then + 1. For each module _m_ in _stack_, do + 1. Assert: _m_.[[Status]] is `"evaluating"`. + 1. Set _m_.[[Status]] to `"evaluated"`. + 1. Set _m_.[[EvaluationError]] to _result_. + 1. Assert: _module_.[[Status]] is `"evaluated"` and _module_.[[EvaluationError]] is _result_. + 1. Return _result_. + 1. Perform ! Call(_promiseCapability_.[[Reject]], *undefined*, «_result_.[[Value]]»). + 1. Return _promiseCapability_.[[Promise]]. + 1. Assert: _module_.[[Status]] is `"evaluated"` and _module_.[[EvaluationError]] is *undefined*. + 1. Assert: _stack_ is empty. + 1. Return *undefined*. + 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, «*undefined*»). + 1. Return _promiseCapability_.[[Promise]]. -
- -

ModuleExecution( _module_ )

+ +

InnerModuleEvaluation( _module_, _stack_, _index_ )

-

The ModuleExecution abstract operation is used by InnerModuleEvaluation to initialize the execution context of the module and evaluate the module's code within it.

+

The InnerModuleEvaluation abstract operation is used by Evaluate to perform the actual evaluation process for the Source Text Module Record _module_, as well as recursively on all other modules in the dependency graph. The _stack_ and _index_ parameters, as well as _module_'s [[DFSIndex]] and [[DFSAncestoreIndex]] fields, are used the same way as in InnerModuleInstantiation.

-

This abstract operation performs the following steps:

+

This abstract operation performs the following steps:

- - 1. Let _moduleCxt_ be a new ECMAScript code execution context. - 1. Set the Function of _moduleCxt_ to *null*. - 1. Assert: _module_.[[Realm]] is not *undefined*. - 1. Set the Realm of _moduleCxt_ to _module_.[[Realm]]. - 1. Set the ScriptOrModule of _moduleCxt_ to _module_. - 1. Assert: _module_ has been linked and declarations in its module environment have been instantiated. - 1. Set the VariableEnvironment of _moduleCxt_ to _module_.[[Environment]]. - 1. Set the LexicalEnvironment of _moduleCxt_ to _module_.[[Environment]]. - 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%). - 1. Suspend the currently running execution context. - 1. Perform ! AsyncBlockStart(_promiseCapability_, _module_.[[ECMAScriptCode]], _moduleCxt_). - 1. Push _moduleCxt_ on to the execution context stack; _moduleCxt_ is now the running execution context. - 1. Let _result_ be the result of evaluating _module_.[[ECMAScriptCode]]. - 1. Suspend _moduleCxt_ and remove it from the execution context stack. - 1. Resume the context that is now on the top of the execution context stack as the running execution context. - 1. Return Completion(_result__promiseCapability_.[[Promise]]). - -
+ + 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%). + 1. If _module_ is not a Source Text Module Record, then + 1. Perform _module_.Evaluate(). + 1. Return _index_. + 1. Let _evaluateResult_ be Await(! _module_.Evaluate()) + 1. If _evaluateResult_ is an abrupt completion, perform ! Call(_promiseCapability_.[[Reject]], *undefined*, «_evaluateResult_.[[Value]]»). + 1. Otherwise, perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, «_index_»). + 1. Return _promiseCapability_.[[Promise]]. + 1. If _module_.[[Status]] is `"evaluated"`, then + 1. If _module_.[[EvaluationError]] is *undefined*, return _index_. + 1. Otherwise return _module_.[[EvaluationError]]. + 1. If _module_.[[EvaluationError]] is an abrupt completion, perform ! Call(_promiseCapability_.[[Reject]], *undefined*, «_module_.[[EvaluationError]].[[Value]]»). + 1. Otherwise, perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, «_index_»). + 1. Return _promiseCapability_.[[Promise]] + 1. If _module_.[[Status]] is `"evaluating"`, return _index_. + 1. Assert: _module_.[[Status]] is `"instantiated"`. + 1. Set _module_.[[Status]] to `"evaluating"`. + 1. Set _module_.[[DFSIndex]] to _index_. + 1. Set _module_.[[DFSAncestorIndex]] to _index_. + 1. Set _index_ to _index_ + 1. + 1. Append _module_ to _stack_. + 1. For each String _required_ that is an element of _module_.[[RequestedModules]], do + 1. Let _requiredModule_ be ! HostResolveImportedModule(_module_, _required_). + 1. NOTE: Instantiate must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully. + 1. Set _index_ to ? InnerModuleEvaluation(_requiredModule_, _stack_, _index_). + 1. Let _childResult_ be Await(! InnerModuleEvaluation(_requiredModule_, _stack_, _index_). + 1. IfAbruptRejectPromise(_childResult_, _promiseCapability_). + 1. Assert: _requiredModule_.[[Status]] is either `"evaluating"` or `"evaluated"`. + 1. Assert: _requiredModule_.[[Status]] is `"evaluating"` if and only if _requiredModule_ is in _stack_. + 1. If _requiredModule_.[[Status]] is `"evaluating"`, then + 1. Assert: _requiredModule_ is a Source Text Module Record. + 1. Set _module_.[[DFSAncestorIndex]] to min(_module_.[[DFSAncestorIndex]], _requiredModule_.[[DFSAncestorIndex]]). + 1. Perform ? ModuleExecution(_module_). + 1. Let _executionResult_ be Await(! ModuleExecution(_module_)). + 1. IfAbruptRejectPromise(_executionResult_, _promiseCapability_). + 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 _done_ be *false*. + 1. Repeat, while _done_ is *false*, + 1. Let _requiredModule_ be the last element in _stack_. + 1. Remove the last element of _stack_. + 1. Set _requiredModule_.[[Status]] to `"evaluated"`. + 1. If _requiredModule_ and _module_ are the same Module Record, set _done_ to *true*. + 1. Return _index_. + 1. Perform ! Call(_promiseCapability_.[[Resolve]], *undefined*, «_index_»). + 1. Return _promiseCapability_.[[Promise]] + +
+ + +

ModuleExecution( _module_ )

+

The ModuleExecution abstract operation is used by InnerModuleEvaluation to initialize the execution context of the module and evaluate the module's code within it.

+ +

This abstract operation performs the following steps:

+ + + 1. Let _moduleCxt_ be a new ECMAScript code execution context. + 1. Set the Function of _moduleCxt_ to *null*. + 1. Assert: _module_.[[Realm]] is not *undefined*. + 1. Set the Realm of _moduleCxt_ to _module_.[[Realm]]. + 1. Set the ScriptOrModule of _moduleCxt_ to _module_. + 1. Assert: _module_ has been linked and declarations in its module environment have been instantiated. + 1. Set the VariableEnvironment of _moduleCxt_ to _module_.[[Environment]]. + 1. Set the LexicalEnvironment of _moduleCxt_ to _module_.[[Environment]]. + 1. Let _promiseCapability_ be ! NewPromiseCapability(%Promise%). + 1. Suspend the currently running execution context. + 1. Perform ! AsyncBlockStart(_promiseCapability_, _module_.[[ECMAScriptCode]], _moduleCxt_). + 1. Push _moduleCxt_ on to the execution context stack; _moduleCxt_ is now the running execution context. + 1. Let _result_ be the result of evaluating _module_.[[ECMAScriptCode]]. + 1. Suspend _moduleCxt_ and remove it from the execution context stack. + 1. Resume the context that is now on the top of the execution context stack as the running execution context. + 1. Return Completion(_result_). + 1. Return _promiseCapability_.[[Promise]]. + +
+

AsyncFunctionStart ( _promiseCapability_, _asyncFunctionBody_ )