generator.js 3.67 KB
Newer Older
1
// Copyright 2013 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
"use strict";

7 8 9 10 11 12 13
// This file relies on the fact that the following declarations have been made
// in runtime.js:
// var $Function = global.Function;

// ----------------------------------------------------------------------------


14 15
// Generator functions and objects are specified by ES6, sections 15.19.3 and
// 15.19.4.
16

17
function GeneratorObjectNext(value) {
18 19 20 21 22
  if (!IS_GENERATOR(this)) {
    throw MakeTypeError('incompatible_method_receiver',
                        ['[Generator].prototype.next', this]);
  }

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
  var continuation = %GeneratorGetContinuation(this);
  if (continuation > 0) {
    // Generator is suspended.
    if (DEBUG_IS_ACTIVE) %DebugPrepareStepInIfStepping(this);
    try {
      return %_GeneratorNext(this, value);
    } catch (e) {
      %GeneratorClose(this);
      throw e;
    }
  } else if (continuation == 0) {
    // Generator is already closed.
    return { value: void 0, done: true };
  } else {
    // Generator is running.
    throw MakeTypeError('generator_running', []);
  }
40 41 42
}

function GeneratorObjectThrow(exn) {
43 44 45 46 47
  if (!IS_GENERATOR(this)) {
    throw MakeTypeError('incompatible_method_receiver',
                        ['[Generator].prototype.throw', this]);
  }

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
  var continuation = %GeneratorGetContinuation(this);
  if (continuation > 0) {
    // Generator is suspended.
    try {
      return %_GeneratorThrow(this, exn);
    } catch (e) {
      %GeneratorClose(this);
      throw e;
    }
  } else if (continuation == 0) {
    // Generator is already closed.
    throw exn;
  } else {
    // Generator is running.
    throw MakeTypeError('generator_running', []);
  }
64 65
}

66 67 68 69
function GeneratorObjectIterator() {
  return this;
}

70 71 72 73 74 75 76
function GeneratorFunctionPrototypeConstructor(x) {
  if (%_IsConstructCall()) {
    throw MakeTypeError('not_constructor', ['GeneratorFunctionPrototype']);
  }
}

function GeneratorFunctionConstructor(arg1) {  // length == 1
77
  return NewFunctionFromString(arguments, 'function*');
78 79 80
}


81 82
function SetUpGenerators() {
  %CheckIsBootstrapping();
83 84 85 86 87 88 89

  // Both Runtime_GeneratorNext and Runtime_GeneratorThrow are supported by
  // neither Crankshaft nor TurboFan, disable optimization of wrappers here.
  %NeverOptimizeFunction(GeneratorObjectNext);
  %NeverOptimizeFunction(GeneratorObjectThrow);

  // Set up non-enumerable functions on the generator prototype object.
90 91 92 93
  var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
  InstallFunctions(GeneratorObjectPrototype,
                   DONT_ENUM | DONT_DELETE | READ_ONLY,
                   ["next", GeneratorObjectNext,
94
                    "throw", GeneratorObjectThrow]);
95

96
  %FunctionSetName(GeneratorObjectIterator, '[Symbol.iterator]');
97
  %AddNamedProperty(GeneratorObjectPrototype, symbolIterator,
98
      GeneratorObjectIterator, DONT_ENUM | DONT_DELETE | READ_ONLY);
99
  %AddNamedProperty(GeneratorObjectPrototype, "constructor",
100
      GeneratorFunctionPrototype, DONT_ENUM | DONT_DELETE | READ_ONLY);
101 102
  %AddNamedProperty(GeneratorObjectPrototype,
      symbolToStringTag, "Generator", DONT_ENUM | READ_ONLY);
103
  %InternalSetPrototype(GeneratorFunctionPrototype, $Function.prototype);
104 105
  %AddNamedProperty(GeneratorFunctionPrototype,
      symbolToStringTag, "GeneratorFunction", DONT_ENUM | READ_ONLY);
106
  %SetCode(GeneratorFunctionPrototype, GeneratorFunctionPrototypeConstructor);
107
  %AddNamedProperty(GeneratorFunctionPrototype, "constructor",
108
      GeneratorFunction, DONT_ENUM | DONT_DELETE | READ_ONLY);
109
  %InternalSetPrototype(GeneratorFunction, $Function);
110
  %SetCode(GeneratorFunction, GeneratorFunctionConstructor);
111 112 113
}

SetUpGenerators();