diff --git a/spec.html b/spec.html index 77be680..5ca6e68 100644 --- a/spec.html +++ b/spec.html @@ -243,8 +243,446 @@

+ +

ECMAScript Language: Functions and Classes

+ + +

Generator Function Definitions

+ + +

+ Runtime Semantics: EvaluateGeneratorBody ( + _functionObject_: a function object, + _argumentsList_: a List of ECMAScript language values, + ): a throw completion or a return completion +

+
+
+ GeneratorBody : FunctionBody + + 1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). + 1. Let _G_ be ? OrdinaryCreateFromConstructor(_functionObject_, *"%GeneratorFunction.prototype.prototype%"*, « [[GeneratorState]], [[GeneratorContext]], [[GeneratorAsyncContextMapping]], [[GeneratorBrand]] »). + 1. Set _G_.[[GeneratorBrand]] to ~empty~. + 1. Perform GeneratorStart(_G_, |FunctionBody|). + 1. Return Completion Record { [[Type]]: ~return~, [[Value]]: _G_, [[Target]]: ~empty~ }. + +
+
+ + +

Async Generator Function Definitions

+ + +

+ Runtime Semantics: EvaluateAsyncGeneratorBody ( + _functionObject_: a function object, + _argumentsList_: a List of ECMAScript language values, + ): a throw completion or a return completion +

+
+
+ + AsyncGeneratorBody : FunctionBody + + + 1. Perform ? FunctionDeclarationInstantiation(_functionObject_, _argumentsList_). + 1. Let _generator_ be ? OrdinaryCreateFromConstructor(_functionObject_, *"%AsyncGeneratorFunction.prototype.prototype%"*, « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[AsyncGeneratorAsyncContextMapping]], [[GeneratorBrand]] »). + 1. Set _generator_.[[GeneratorBrand]] to ~empty~. + 1. Perform AsyncGeneratorStart(_generator_, |FunctionBody|). + 1. Return Completion Record { [[Type]]: ~return~, [[Value]]: _generator_, [[Target]]: ~empty~ }. + +
+
+
+

Control Abstraction Objects

+ + +

Generator Objects

+ + +

Properties of Generator Instances

+

Generator instances are initially created with the internal slots described in .

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Internal Slot + + Type + + Description +
+ [[GeneratorState]] + + *undefined*, ~suspendedStart~, ~suspendedYield~, ~executing~, or ~completed~ + + The current execution state of the generator. +
+ [[GeneratorContext]] + + an execution context + + The execution context that is used when executing the code of this generator. +
+ [[GeneratorAsyncContextMapping]] + + a List of Async Context Mapping Records + + The value of the agent's [[AsyncContextMapping]] to use the next time this generator is resumed. +
+ [[GeneratorBrand]] + + a String or ~empty~ + + A brand used to distinguish different kinds of generators. The [[GeneratorBrand]] of generators declared by ECMAScript source text is always ~empty~. +
+
+
+ + +

Generator Abstract Operations

+ + +

+ GeneratorStart ( + _generator_: a Generator, + _generatorBody_: a |FunctionBody| Parse Node or an Abstract Closure with no parameters, + ): ~unused~ +

+
+
+ + 1. Assert: The value of _generator_.[[GeneratorState]] is *undefined*. + 1. Let _genContext_ be the running execution context. + 1. Set the Generator component of _genContext_ to _generator_. + 1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ and performs the following steps when called: + 1. Let _acGenContext_ be the running execution context. + 1. Let _acGenerator_ be the Generator component of _acGenContext_. + 1. If _generatorBody_ is a Parse Node, then + 1. Let _result_ be Completion(Evaluation of _generatorBody_). + 1. Else, + 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. + 1. Let _result_ be _generatorBody_(). + 1. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return. + 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. + 1. Set _acGenerator_.[[GeneratorState]] to ~completed~. + 1. NOTE: Once a generator enters the ~completed~ state it never leaves it and its associated execution context is never resumed. Any execution state associated with _acGenerator_ can be discarded at this point. + 1. If _result_.[[Type]] is ~normal~, then + 1. Let _resultValue_ be *undefined*. + 1. Else if _result_.[[Type]] is ~return~, then + 1. Let _resultValue_ be _result_.[[Value]]. + 1. Else, + 1. Assert: _result_.[[Type]] is ~throw~. + 1. Return ? _result_. + 1. Return CreateIterResultObject(_resultValue_, *true*). + 1. Set the code evaluation state of _genContext_ such that when evaluation is resumed for that execution context, _closure_ will be called with no arguments. + 1. Set _generator_.[[GeneratorContext]] to _genContext_. + 1. Set _generator_.[[GeneratorAsyncContextMapping]] to AsyncContextSnapshot(). + 1. Set _generator_.[[GeneratorState]] to ~suspendedStart~. + 1. Return ~unused~. + +
+ + +

+ GeneratorValidate ( + _generator_: an ECMAScript language value, + _generatorBrand_: a String or ~empty~, + ): either a normal completion containing one of ~suspendedStart~, ~suspendedYield~, or ~completed~, or a throw completion +

+
+
+ + 1. Perform ? RequireInternalSlot(_generator_, [[GeneratorState]]). + 1. Perform ? RequireInternalSlot(_generator_, [[GeneratorBrand]]). + 1. If _generator_.[[GeneratorBrand]] is not _generatorBrand_, throw a *TypeError* exception. + 1. Assert: _generator_ also has a [[GeneratorContext]] internal slot. + 1. Assert: _generator_ also has [[GeneratorContext]] and [[GeneratorAsyncContextMapping]] internal slots. + 1. Let _state_ be _generator_.[[GeneratorState]]. + 1. If _state_ is ~executing~, throw a *TypeError* exception. + 1. Return _state_. + +
+ + +

+ GeneratorResume ( + _generator_: an ECMAScript language value, + _value_: an ECMAScript language value or ~empty~, + _generatorBrand_: a String or ~empty~, + ): either a normal completion containing an ECMAScript language value or a throw completion +

+
+
+ + 1. Let _state_ be ? GeneratorValidate(_generator_, _generatorBrand_). + 1. If _state_ is ~completed~, return CreateIterResultObject(*undefined*, *true*). + 1. Assert: _state_ is either ~suspendedStart~ or ~suspendedYield~. + 1. Let _genContext_ be _generator_.[[GeneratorContext]]. + 1. Let _methodContext_ be the running execution context. + 1. Suspend _methodContext_. + 1. Set _generator_.[[GeneratorState]] to ~executing~. + 1. Let _asyncContextMapping_ be AsyncContextSwap(_generator_.[[GeneratorAsyncContextMapping]]). + 1. Push _genContext_ onto the execution context stack; _genContext_ is now the running execution context. + 1. Resume the suspended evaluation of _genContext_ using NormalCompletion(_value_) as the result of the operation that suspended it. Let _result_ be the value returned by the resumed computation. + 1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _methodContext_ is the currently running execution context. + 1. Assert: The result of AsyncContextSnapshot() is _generator_.[[GeneratorAsyncContextMapping]]. + 1. AsyncContextSwap(_asyncContextMapping_). + 1. Return ? _result_. + +
+ + +

+ GeneratorResumeAbrupt ( + _generator_: an ECMAScript language value, + _abruptCompletion_: a return completion or a throw completion, + _generatorBrand_: a String or ~empty~, + ): either a normal completion containing an ECMAScript language value or a throw completion +

+
+
+ + 1. Let _state_ be ? GeneratorValidate(_generator_, _generatorBrand_). + 1. If _state_ is ~suspendedStart~, then + 1. Set _generator_.[[GeneratorState]] to ~completed~. + 1. NOTE: Once a generator enters the ~completed~ state it never leaves it and its associated execution context is never resumed. Any execution state associated with _generator_ can be discarded at this point. + 1. Set _state_ to ~completed~. + 1. If _state_ is ~completed~, then + 1. If _abruptCompletion_.[[Type]] is ~return~, then + 1. Return CreateIterResultObject(_abruptCompletion_.[[Value]], *true*). + 1. Return ? _abruptCompletion_. + 1. Assert: _state_ is ~suspendedYield~. + 1. Let _genContext_ be _generator_.[[GeneratorContext]]. + 1. Let _methodContext_ be the running execution context. + 1. Suspend _methodContext_. + 1. Set _generator_.[[GeneratorState]] to ~executing~. + 1. Let _asyncContextMapping_ be AsyncContextSwap(_generator_.[[GeneratorAsyncContextMapping]]). + 1. Push _genContext_ onto the execution context stack; _genContext_ is now the running execution context. + 1. Resume the suspended evaluation of _genContext_ using _abruptCompletion_ as the result of the operation that suspended it. Let _result_ be the Completion Record returned by the resumed computation. + 1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _methodContext_ is the currently running execution context. + 1. Assert: The result of AsyncContextSnapshot() is _generator_.[[GeneratorAsyncContextMapping]]. + 1. AsyncContextSwap(_asyncContextMapping_). + 1. Return ? _result_. + +
+ + +

+ CreateIteratorFromClosure ( + _closure_: an Abstract Closure with no parameters, + _generatorBrand_: a String or ~empty~, + _generatorPrototype_: an Object, + ): a Generator +

+
+
+ + 1. NOTE: _closure_ can contain uses of the Yield operation to yield an IteratorResult object. + 1. Let _internalSlotsList_ be « [[GeneratorState]], [[GeneratorContext]], [[GeneratorAsyncContextMapping]], [[GeneratorBrand]] ». + 1. Let _generator_ be OrdinaryObjectCreate(_generatorPrototype_, _internalSlotsList_). + 1. Set _generator_.[[GeneratorBrand]] to _generatorBrand_. + 1. Set _generator_.[[GeneratorState]] to *undefined*. + 1. Let _callerContext_ be the running execution context. + 1. Let _calleeContext_ be a new execution context. + 1. Set the Function of _calleeContext_ to *null*. + 1. Set the Realm of _calleeContext_ to the current Realm Record. + 1. Set the ScriptOrModule of _calleeContext_ to _callerContext_'s ScriptOrModule. + 1. If _callerContext_ is not already suspended, suspend _callerContext_. + 1. Push _calleeContext_ onto the execution context stack; _calleeContext_ is now the running execution context. + 1. Perform GeneratorStart(_generator_, _closure_). + 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context. + 1. Return _generator_. + +
+
+
+ + +

AsyncGenerator Objects

+ + +

Properties of AsyncGenerator Instances

+

AsyncGenerator instances are initially created with the internal slots described below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Internal SlotTypeDescription
[[AsyncGeneratorState]]*undefined*, ~suspendedStart~, ~suspendedYield~, ~executing~, ~awaiting-return~, or ~completed~The current execution state of the async generator.
[[AsyncGeneratorContext]]an execution contextThe execution context that is used when executing the code of this async generator.
[[AsyncGeneratorQueue]]a List of AsyncGeneratorRequest RecordsRecords which represent requests to resume the async generator. Except during state transitions, it is non-empty if and only if [[AsyncGeneratorState]] is either ~executing~ or ~awaiting-return~.
[[AsyncGeneratorAsyncContextMapping]]a List of Async Context Mapping RecordsThe value of the agent's [[AsyncContextMapping]] to use the next time this generator is resumed.
[[GeneratorBrand]]a String or ~empty~A brand used to distinguish different kinds of async generators. The [[GeneratorBrand]] of async generators declared by ECMAScript source text is always ~empty~.
+
+
+ + +

AsyncGenerator Abstract Operations

+ + +

+ AsyncGeneratorStart ( + _generator_: an AsyncGenerator, + _generatorBody_: a |FunctionBody| Parse Node or an Abstract Closure with no parameters, + ): ~unused~ +

+
+
+ + 1. Assert: _generator_.[[AsyncGeneratorState]] is *undefined*. + 1. Let _genContext_ be the running execution context. + 1. Set the Generator component of _genContext_ to _generator_. + 1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ and performs the following steps when called: + 1. Let _acGenContext_ be the running execution context. + 1. Let _acGenerator_ be the Generator component of _acGenContext_. + 1. If _generatorBody_ is a Parse Node, then + 1. Let _result_ be Completion(Evaluation of _generatorBody_). + 1. Else, + 1. Assert: _generatorBody_ is an Abstract Closure with no parameters. + 1. Let _result_ be Completion(_generatorBody_()). + 1. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return. + 1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context. + 1. Set _acGenerator_.[[AsyncGeneratorState]] to ~completed~. + 1. If _result_.[[Type]] is ~normal~, set _result_ to NormalCompletion(*undefined*). + 1. If _result_.[[Type]] is ~return~, set _result_ to NormalCompletion(_result_.[[Value]]). + 1. Perform AsyncGeneratorCompleteStep(_acGenerator_, _result_, *true*). + 1. Perform AsyncGeneratorDrainQueue(_acGenerator_). + 1. Return *undefined*. + 1. Set the code evaluation state of _genContext_ such that when evaluation is resumed for that execution context, _closure_ will be called with no arguments. + 1. Set _generator_.[[AsyncGeneratorContext]] to _genContext_. + 1. Set _generator_.[[AsyncGeneratorState]] to ~suspendedStart~. + 1. Set _generator_.[[AsyncGeneratorQueue]] to a new empty List. + 1. Set _generator_.[[AsyncGeneratorAsyncContextMapping]] to AsyncContextSnapshot(). + 1. Return ~unused~. + +
+ + +

+ AsyncGeneratorValidate ( + _generator_: an ECMAScript language value, + _generatorBrand_: a String or ~empty~, + ): either a normal completion containing ~unused~ or a throw completion +

+
+
+ + 1. Perform ? RequireInternalSlot(_generator_, [[AsyncGeneratorContext]]). + 1. Perform ? RequireInternalSlot(_generator_, [[AsyncGeneratorState]]). + 1. Perform ? RequireInternalSlot(_generator_, [[AsyncGeneratorQueue]]). + 1. Perform ? RequireInternalSlot(_generator_, [[AsyncGeneratorAsyncContextMapping]]). + 1. If _generator_.[[GeneratorBrand]] is not _generatorBrand_, throw a *TypeError* exception. + 1. Return ~unused~. + +
+ + +

+ AsyncGeneratorResume ( + _generator_: an AsyncGenerator, + _completion_: a Completion Record, + ): ~unused~ +

+
+
+ + 1. Assert: _generator_.[[AsyncGeneratorState]] is either ~suspendedStart~ or ~suspendedYield~. + 1. Let _genContext_ be _generator_.[[AsyncGeneratorContext]]. + 1. Let _callerContext_ be the running execution context. + 1. Suspend _callerContext_. + 1. Set _generator_.[[AsyncGeneratorState]] to ~executing~. + 1. Let _asyncContextMapping_ be AsyncContextSwap(_generator_.[[AsyncGeneratorAsyncContextMapping]]). + 1. Push _genContext_ onto the execution context stack; _genContext_ is now the running execution context. + 1. Resume the suspended evaluation of _genContext_ using _completion_ as the result of the operation that suspended it. Let _result_ be the Completion Record returned by the resumed computation. + 1. Assert: _result_ is never an abrupt completion. + 1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _callerContext_ is the currently running execution context. + 1. Assert: The result of AsyncContextSnapshot() is _generator_.[[AsyncGeneratorAsyncContextMapping]]. + 1. AsyncContextSwap(_asyncContextMapping_). + 1. Return ~unused~. + +
+ + +

+ CreateAsyncIteratorFromClosure ( + _closure_: an Abstract Closure with no parameters, + _generatorBrand_: a String or ~empty~, + _generatorPrototype_: an Object, + ): an AsyncGenerator +

+
+
+ + 1. NOTE: _closure_ can contain uses of the Await operation and uses of the Yield operation to yield an IteratorResult object. + 1. Let _internalSlotsList_ be « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[AsyncGeneratorAsyncContextMapping]], [[GeneratorBrand]] ». + 1. Let _generator_ be OrdinaryObjectCreate(_generatorPrototype_, _internalSlotsList_). + 1. Set _generator_.[[GeneratorBrand]] to _generatorBrand_. + 1. Set _generator_.[[AsyncGeneratorState]] to *undefined*. + 1. Let _callerContext_ be the running execution context. + 1. Let _calleeContext_ be a new execution context. + 1. Set the Function of _calleeContext_ to *null*. + 1. Set the Realm of _calleeContext_ to the current Realm Record. + 1. Set the ScriptOrModule of _calleeContext_ to _callerContext_'s ScriptOrModule. + 1. If _callerContext_ is not already suspended, suspend _callerContext_. + 1. Push _calleeContext_ onto the execution context stack; _calleeContext_ is now the running execution context. + 1. Perform AsyncGeneratorStart(_generator_, _closure_). + 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context. + 1. Return _generator_. + +
+
+
+