1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5(function(global, utils) {
6
7"use strict";
8
9%CheckIsBootstrapping();
10
11// -------------------------------------------------------------------
12// Imports
13
14var GeneratorFunctionPrototype = utils.ImportNow("GeneratorFunctionPrototype");
15var GeneratorFunction = utils.ImportNow("GeneratorFunction");
16var GlobalFunction = global.Function;
17var MakeTypeError;
18var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
19
20utils.Import(function(from) {
21  MakeTypeError = from.MakeTypeError;
22});
23
24// ----------------------------------------------------------------------------
25
26// Generator functions and objects are specified by ES6, sections 15.19.3 and
27// 15.19.4.
28
29function GeneratorObjectNext(value) {
30  if (!IS_GENERATOR(this)) {
31    throw MakeTypeError(kIncompatibleMethodReceiver,
32                        '[Generator].prototype.next', this);
33  }
34
35  var continuation = %GeneratorGetContinuation(this);
36  if (continuation > 0) {
37    // Generator is suspended.
38    DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
39    try {
40      return %_GeneratorNext(this, value);
41    } catch (e) {
42      %GeneratorClose(this);
43      throw e;
44    }
45  } else if (continuation == 0) {
46    // Generator is already closed.
47    return { value: void 0, done: true };
48  } else {
49    // Generator is running.
50    throw MakeTypeError(kGeneratorRunning);
51  }
52}
53
54
55function GeneratorObjectThrow(exn) {
56  if (!IS_GENERATOR(this)) {
57    throw MakeTypeError(kIncompatibleMethodReceiver,
58                        '[Generator].prototype.throw', this);
59  }
60
61  var continuation = %GeneratorGetContinuation(this);
62  if (continuation > 0) {
63    // Generator is suspended.
64    try {
65      return %_GeneratorThrow(this, exn);
66    } catch (e) {
67      %GeneratorClose(this);
68      throw e;
69    }
70  } else if (continuation == 0) {
71    // Generator is already closed.
72    throw exn;
73  } else {
74    // Generator is running.
75    throw MakeTypeError(kGeneratorRunning);
76  }
77}
78
79// ----------------------------------------------------------------------------
80
81// Both Runtime_GeneratorNext and Runtime_GeneratorThrow are supported by
82// neither Crankshaft nor TurboFan, disable optimization of wrappers here.
83%NeverOptimizeFunction(GeneratorObjectNext);
84%NeverOptimizeFunction(GeneratorObjectThrow);
85
86// Set up non-enumerable functions on the generator prototype object.
87var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
88utils.InstallFunctions(GeneratorObjectPrototype,
89                       DONT_ENUM,
90                      ["next", GeneratorObjectNext,
91                       "throw", GeneratorObjectThrow]);
92
93%AddNamedProperty(GeneratorObjectPrototype, "constructor",
94    GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
95%AddNamedProperty(GeneratorObjectPrototype,
96    toStringTagSymbol, "Generator", DONT_ENUM | READ_ONLY);
97%InternalSetPrototype(GeneratorFunctionPrototype, GlobalFunction.prototype);
98%AddNamedProperty(GeneratorFunctionPrototype,
99    toStringTagSymbol, "GeneratorFunction", DONT_ENUM | READ_ONLY);
100%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
101    GeneratorFunction, DONT_ENUM | READ_ONLY);
102%InternalSetPrototype(GeneratorFunction, GlobalFunction);
103
104})
105