1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 function GeneratorNext(val) {
6 // The IsSuspendedGenerator call below is not necessary for correctness.
7 // It's a performance optimization to check for the common case with a
8 // single call. It's also inlined in Baseline.
10 if (!IsSuspendedGenerator(this)) {
11 if (!IsObject(this) || !IsGeneratorObject(this)) {
13 CallGeneratorMethodIfWrapped,
20 if (GeneratorObjectIsClosed(this)) {
21 return { value: undefined, done: true };
24 if (GeneratorIsRunning(this)) {
25 ThrowTypeError(JSMSG_NESTING_GENERATOR);
30 return resumeGenerator(this, val, "next");
32 if (!GeneratorObjectIsClosed(this)) {
33 GeneratorSetClosed(this);
39 function GeneratorThrow(val) {
40 if (!IsSuspendedGenerator(this)) {
41 if (!IsObject(this) || !IsGeneratorObject(this)) {
43 CallGeneratorMethodIfWrapped,
50 if (GeneratorObjectIsClosed(this)) {
54 if (GeneratorIsRunning(this)) {
55 ThrowTypeError(JSMSG_NESTING_GENERATOR);
60 return resumeGenerator(this, val, "throw");
62 if (!GeneratorObjectIsClosed(this)) {
63 GeneratorSetClosed(this);
69 function GeneratorReturn(val) {
70 if (!IsSuspendedGenerator(this)) {
71 if (!IsObject(this) || !IsGeneratorObject(this)) {
73 CallGeneratorMethodIfWrapped,
80 if (GeneratorObjectIsClosed(this)) {
81 return { value: val, done: true };
84 if (GeneratorIsRunning(this)) {
85 ThrowTypeError(JSMSG_NESTING_GENERATOR);
90 var rval = { value: val, done: true };
91 return resumeGenerator(this, rval, "return");
93 if (!GeneratorObjectIsClosed(this)) {
94 GeneratorSetClosed(this);
100 function InterpretGeneratorResume(gen, val, kind) {
101 // If we want to resume a generator in the interpreter, the script containing
102 // the resumeGenerator/JSOp::Resume also has to run in the interpreter. The
103 // forceInterpreter() call below compiles to a bytecode op that prevents us
104 // from JITing this script.
106 if (kind === "next") {
107 return resumeGenerator(gen, val, "next");
109 if (kind === "throw") {
110 return resumeGenerator(gen, val, "throw");
112 assert(kind === "return", "Invalid resume kind");
113 return resumeGenerator(gen, val, "return");