27.5 Generator Objects
A Generator is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.
Generator instances directly inherit properties from the object that is the initial value of the
27.5.1 Properties of the Generator Prototype Object
The Generator prototype object:
- is %GeneratorFunction.prototype.prototype%.
- is an
ordinary object . - is not a Generator instance and does not have a [[GeneratorState]] internal slot.
- has a [[Prototype]] internal slot whose value is
%IteratorPrototype% . - has properties that are indirectly inherited by all Generator instances.
27.5.1.1 Generator.prototype.constructor
The initial value of Generator.prototype.constructor
is
This property has the attributes { [[Writable]]:
27.5.1.2 Generator.prototype.next ( value )
- Return ?
GeneratorResume (this value, value,empty ).
27.5.1.3 Generator.prototype.return ( value )
This method performs the following steps when called:
- Let g be the
this value. - Let C be
Completion Record { [[Type]]:return , [[Value]]: value, [[Target]]:empty }. - Return ?
GeneratorResumeAbrupt (g, C,empty ).
27.5.1.4 Generator.prototype.throw ( exception )
This method performs the following steps when called:
- Let g be the
this value. - Let C be
ThrowCompletion (exception). - Return ?
GeneratorResumeAbrupt (g, C,empty ).
27.5.1.5 Generator.prototype [ @@toStringTag ]
The initial value of the
This property has the attributes { [[Writable]]:
27.5.2 Properties of Generator Instances
Generator instances are initially created with the internal slots described in
Internal Slot | Type | Description |
---|---|---|
[[GeneratorState]] |
|
The current execution state of the generator. |
[[GeneratorContext]] |
an |
The |
[[GeneratorBrand]] |
a String or |
A brand used to distinguish different kinds of generators. The [[GeneratorBrand]] of generators declared by |
27.5.3 Generator Abstract Operations
27.5.3.1 GeneratorStart ( generator, generatorBody )
The abstract operation GeneratorStart takes arguments generator (a Generator) and generatorBody (a
Assert : The value of generator.[[GeneratorState]] isundefined .- Let genContext be the
running execution context . - Set the Generator component of genContext to generator.
- Let closure be a new
Abstract Closure with no parameters that captures generatorBody and performs the following steps when called:- Let acGenContext be the
running execution context . - Let acGenerator be the Generator component of acGenContext.
- If generatorBody is a
Parse Node , then- Let result be
Completion (Evaluation of generatorBody).
- Let result be
- Else,
Assert : generatorBody is anAbstract Closure with no parameters.- Let result be generatorBody().
Assert : If we return here, the generator either threw an exception or performed either an implicit or explicit return.- Remove acGenContext from the
execution context stack and restore theexecution context that is at the top of theexecution context stack as therunning execution context . - Set acGenerator.[[GeneratorState]] to
completed . - NOTE: Once a generator enters the
completed state it never leaves it and its associatedexecution context is never resumed. Any execution state associated with acGenerator can be discarded at this point. - If result is a
normal completion , then- Let resultValue be
undefined .
- Let resultValue be
- Else if result is a
return completion , then- Let resultValue be result.[[Value]].
- Else,
Assert : result is athrow completion .- Return ? result.
- Return
CreateIterResultObject (resultValue,true ).
- Let acGenContext be the
- Set the code evaluation state of genContext such that when evaluation is resumed for that
execution context , closure will be called with no arguments. - Set generator.[[GeneratorContext]] to genContext.
- Set generator.[[GeneratorState]] to
suspended-start . - Return
unused .
27.5.3.2 GeneratorValidate ( generator, generatorBrand )
The abstract operation GeneratorValidate takes arguments generator (an
- Perform ?
RequireInternalSlot (generator, [[GeneratorState]]). - Perform ?
RequireInternalSlot (generator, [[GeneratorBrand]]). - If generator.[[GeneratorBrand]] is not generatorBrand, throw a
TypeError exception. Assert : generator also has a [[GeneratorContext]] internal slot.- Let state be generator.[[GeneratorState]].
- If state is
executing , throw aTypeError exception. - Return state.
27.5.3.3 GeneratorResume ( generator, value, generatorBrand )
The abstract operation GeneratorResume takes arguments generator (an
- Let state be ?
GeneratorValidate (generator, generatorBrand). - If state is
completed , returnCreateIterResultObject (undefined ,true ). Assert : state is eithersuspended-start orsuspended-yield .- Let genContext be generator.[[GeneratorContext]].
- Let methodContext be the
running execution context . - Suspend methodContext.
- Set generator.[[GeneratorState]] to
executing . - Push genContext onto the
execution context stack ; genContext is now therunning execution context . - 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. Assert : When we return here, genContext has already been removed from theexecution context stack and methodContext is the currentlyrunning execution context .- Return ? result.
27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )
The abstract operation GeneratorResumeAbrupt takes arguments generator (an
- Let state be ?
GeneratorValidate (generator, generatorBrand). - If state is
suspended-start , then- Set generator.[[GeneratorState]] to
completed . - NOTE: Once a generator enters the
completed state it never leaves it and its associatedexecution context is never resumed. Any execution state associated with generator can be discarded at this point. - Set state to
completed .
- Set generator.[[GeneratorState]] to
- If state is
completed , then- If abruptCompletion is a
return completion , then- Return
CreateIterResultObject (abruptCompletion.[[Value]],true ).
- Return
- Return ? abruptCompletion.
- If abruptCompletion is a
Assert : state issuspended-yield .- Let genContext be generator.[[GeneratorContext]].
- Let methodContext be the
running execution context . - Suspend methodContext.
- Set generator.[[GeneratorState]] to
executing . - Push genContext onto the
execution context stack ; genContext is now therunning execution context . - 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. Assert : When we return here, genContext has already been removed from theexecution context stack and methodContext is the currentlyrunning execution context .- Return ? result.
27.5.3.5 GetGeneratorKind ( )
The abstract operation GetGeneratorKind takes no arguments and returns
- Let genContext be the
running execution context . - If genContext does not have a Generator component, return
non-generator . - Let generator be the Generator component of genContext.
- If generator has an [[AsyncGeneratorState]] internal slot, return
async . - Else, return
sync .
27.5.3.6 GeneratorYield ( iterNextObj )
The abstract operation GeneratorYield takes argument iterNextObj (an Object that conforms to the IteratorResult interface) and returns either a
- Let genContext be the
running execution context . Assert : genContext is theexecution context of a generator.- Let generator be the value of the Generator component of genContext.
Assert :GetGeneratorKind () issync .- Set generator.[[GeneratorState]] to
suspended-yield . - Remove genContext from the
execution context stack and restore theexecution context that is at the top of theexecution context stack as therunning execution context . - Let callerContext be the
running execution context . - Resume callerContext passing
NormalCompletion (iterNextObj). If genContext is ever resumed again, let resumptionValue be theCompletion Record with which it is resumed. Assert : If control reaches here, then genContext is therunning execution context again.- Return resumptionValue.
27.5.3.7 Yield ( value )
The abstract operation Yield takes argument value (an
- Let generatorKind be
GetGeneratorKind (). - If generatorKind is
async , return ?AsyncGeneratorYield (?Await (value)). - Otherwise, return ?
GeneratorYield (CreateIterResultObject (value,false )).
27.5.3.8 CreateIteratorFromClosure ( closure, generatorBrand, generatorPrototype )
The abstract operation CreateIteratorFromClosure takes arguments closure (an
- NOTE: closure can contain uses of the
Yield operation to yield an IteratorResult object. - Let internalSlotsList be « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] ».
- Let generator be
OrdinaryObjectCreate (generatorPrototype, internalSlotsList). - Set generator.[[GeneratorBrand]] to generatorBrand.
- Set generator.[[GeneratorState]] to
undefined . - Let callerContext be the
running execution context . - Let calleeContext be a new
execution context . - Set the Function of calleeContext to
null . - Set the
Realm of calleeContext tothe current Realm Record . - Set the ScriptOrModule of calleeContext to callerContext's ScriptOrModule.
- If callerContext is not already suspended, suspend callerContext.
- Push calleeContext onto the
execution context stack ; calleeContext is now therunning execution context . - Perform
GeneratorStart (generator, closure). - Remove calleeContext from the
execution context stack and restore callerContext as therunning execution context . - Return generator.