27.5 Generator Objects

A Generator object 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 "prototype" property of the Generator function that created the instance. Generator instances indirectly inherit properties from the Generator Prototype intrinsic, %GeneratorFunction.prototype.prototype%.

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 %GeneratorFunction.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.5.1.2 Generator.prototype.next ( value )

The next method performs the following steps:

  1. Let g be the this value.
  2. Return ? GeneratorResume(g, value, empty).

27.5.1.3 Generator.prototype.return ( value )

The return method performs the following steps:

  1. Let g be the this value.
  2. Let C be Completion { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
  3. Return ? GeneratorResumeAbrupt(g, C, empty).

27.5.1.4 Generator.prototype.throw ( exception )

The throw method performs the following steps:

  1. Let g be the this value.
  2. Let C be ThrowCompletion(exception).
  3. Return ? GeneratorResumeAbrupt(g, C, empty).

27.5.1.5 Generator.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Generator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.5.2 Properties of Generator Instances

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

Table 73: Internal Slots of Generator Instances
Internal Slot Description
[[GeneratorState]] The current execution state of the generator. The possible values are: undefined, suspendedStart, suspendedYield, executing, and completed.
[[GeneratorContext]] The execution context that is used when executing the code of this generator.
[[GeneratorBrand]] A brand used to distinguish different kinds of generators. The [[GeneratorBrand]] of generators declared by ECMAScript source text is always empty.

27.5.3 Generator Abstract Operations

27.5.3.1 GeneratorStart ( generator, generatorBody )

The abstract operation GeneratorStart takes arguments generator and generatorBody (a Parse Node or an Abstract Closure with no parameters). It performs the following steps when called:

  1. Assert: The value of generator.[[GeneratorState]] is undefined.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context the following steps will be performed:
    1. If generatorBody is a Parse Node, then
      1. Let result be the result of evaluating generatorBody.
    2. Else,
      1. Assert: generatorBody is an Abstract Closure with no parameters.
      2. Let result be generatorBody().
    3. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return.
    4. Remove genContext 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.
    5. Set generator.[[GeneratorState]] to completed.
    6. 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.
    7. If result.[[Type]] is normal, let resultValue be undefined.
    8. Else if result.[[Type]] is return, let resultValue be result.[[Value]].
    9. Else,
      1. Assert: result.[[Type]] is throw.
      2. Return Completion(result).
    10. Return CreateIterResultObject(resultValue, true).
  5. Set generator.[[GeneratorContext]] to genContext.
  6. Set generator.[[GeneratorState]] to suspendedStart.
  7. Return NormalCompletion(undefined).

27.5.3.2 GeneratorValidate ( generator, generatorBrand )

The abstract operation GeneratorValidate takes arguments generator and generatorBrand. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(generator, [[GeneratorState]]).
  2. Perform ? RequireInternalSlot(generator, [[GeneratorBrand]]).
  3. If generator.[[GeneratorBrand]] is not the same value as generatorBrand, throw a TypeError exception.
  4. Assert: generator also has a [[GeneratorContext]] internal slot.
  5. Let state be generator.[[GeneratorState]].
  6. If state is executing, throw a TypeError exception.
  7. Return state.

27.5.3.3 GeneratorResume ( generator, value, generatorBrand )

The abstract operation GeneratorResume takes arguments generator, value, and generatorBrand. It performs the following steps when called:

  1. Let state be ? GeneratorValidate(generator, generatorBrand).
  2. If state is completed, return CreateIterResultObject(undefined, true).
  3. Assert: state is either suspendedStart or suspendedYield.
  4. Let genContext be generator.[[GeneratorContext]].
  5. Let methodContext be the running execution context.
  6. Suspend methodContext.
  7. Set generator.[[GeneratorState]] to executing.
  8. Push genContext onto the execution context stack; genContext is now the running execution context.
  9. 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.
  10. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  11. Return Completion(result).

27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )

The abstract operation GeneratorResumeAbrupt takes arguments generator, abruptCompletion (a Completion Record whose [[Type]] is return or throw), and generatorBrand. It performs the following steps when called:

  1. Let state be ? GeneratorValidate(generator, generatorBrand).
  2. If state is suspendedStart, then
    1. Set generator.[[GeneratorState]] to completed.
    2. 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.
    3. Set state to completed.
  3. If state is completed, then
    1. If abruptCompletion.[[Type]] is return, then
      1. Return CreateIterResultObject(abruptCompletion.[[Value]], true).
    2. Return Completion(abruptCompletion).
  4. Assert: state is suspendedYield.
  5. Let genContext be generator.[[GeneratorContext]].
  6. Let methodContext be the running execution context.
  7. Suspend methodContext.
  8. Set generator.[[GeneratorState]] to executing.
  9. Push genContext onto the execution context stack; genContext is now the running execution context.
  10. 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.
  11. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  12. Return Completion(result).

27.5.3.5 GetGeneratorKind ( )

The abstract operation GetGeneratorKind takes no arguments. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. If genContext does not have a Generator component, return non-generator.
  3. Let generator be the Generator component of genContext.
  4. If generator has an [[AsyncGeneratorState]] internal slot, return async.
  5. Else, return sync.

27.5.3.6 GeneratorYield ( iterNextObj )

The abstract operation GeneratorYield takes argument iterNextObj. It performs the following steps when called:

  1. Assert: iterNextObj is an Object that implements the IteratorResult interface.
  2. Let genContext be the running execution context.
  3. Assert: genContext is the execution context of a generator.
  4. Let generator be the value of the Generator component of genContext.
  5. Assert: GetGeneratorKind() is sync.
  6. Set generator.[[GeneratorState]] to suspendedYield.
  7. Remove genContext 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.
  8. Set the code evaluation state of genContext such that when evaluation is resumed with a Completion resumptionValue the following steps will be performed:
    1. Return resumptionValue.
    2. NOTE: This returns to the evaluation of the YieldExpression that originally called this abstract operation.
  9. Return NormalCompletion(iterNextObj).
  10. NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of genContext.

27.5.3.7 Yield ( value )

The abstract operation Yield takes argument value (an ECMAScript language value). It performs the following steps when called:

  1. Let generatorKind be ! GetGeneratorKind().
  2. If generatorKind is async, return ? AsyncGeneratorYield(value).
  3. Otherwise, return ? GeneratorYield(! CreateIterResultObject(value, false)).

27.5.3.8 CreateIteratorFromClosure ( closure, generatorBrand, generatorPrototype )

The abstract operation CreateIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand, and generatorPrototype (an Object). It performs the following steps when called:

  1. NOTE: closure can contain uses of the Yield shorthand to yield an IteratorResult object.
  2. Let internalSlotsList be « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] ».
  3. Let generator be ! OrdinaryObjectCreate(generatorPrototype, internalSlotsList).
  4. Set generator.[[GeneratorBrand]] to generatorBrand.
  5. Set generator.[[GeneratorState]] to undefined.
  6. Perform ! GeneratorStart(generator, closure).
  7. Return generator.