Bug 1874684 - Part 21: Rename SecondsAndNanoseconds::toTotalNanoseconds. r=dminor
[gecko.git] / js / src / builtin / Generator.js
blobada80e3006bb40e8b7c496a744da38e59fa6cf02
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)) {
12       return callFunction(
13         CallGeneratorMethodIfWrapped,
14         this,
15         val,
16         "GeneratorNext"
17       );
18     }
20     if (GeneratorObjectIsClosed(this)) {
21       return { value: undefined, done: true };
22     }
24     if (GeneratorIsRunning(this)) {
25       ThrowTypeError(JSMSG_NESTING_GENERATOR);
26     }
27   }
29   try {
30     return resumeGenerator(this, val, "next");
31   } catch (e) {
32     if (!GeneratorObjectIsClosed(this)) {
33       GeneratorSetClosed(this);
34     }
35     throw e;
36   }
39 function GeneratorThrow(val) {
40   if (!IsSuspendedGenerator(this)) {
41     if (!IsObject(this) || !IsGeneratorObject(this)) {
42       return callFunction(
43         CallGeneratorMethodIfWrapped,
44         this,
45         val,
46         "GeneratorThrow"
47       );
48     }
50     if (GeneratorObjectIsClosed(this)) {
51       throw val;
52     }
54     if (GeneratorIsRunning(this)) {
55       ThrowTypeError(JSMSG_NESTING_GENERATOR);
56     }
57   }
59   try {
60     return resumeGenerator(this, val, "throw");
61   } catch (e) {
62     if (!GeneratorObjectIsClosed(this)) {
63       GeneratorSetClosed(this);
64     }
65     throw e;
66   }
69 function GeneratorReturn(val) {
70   if (!IsSuspendedGenerator(this)) {
71     if (!IsObject(this) || !IsGeneratorObject(this)) {
72       return callFunction(
73         CallGeneratorMethodIfWrapped,
74         this,
75         val,
76         "GeneratorReturn"
77       );
78     }
80     if (GeneratorObjectIsClosed(this)) {
81       return { value: val, done: true };
82     }
84     if (GeneratorIsRunning(this)) {
85       ThrowTypeError(JSMSG_NESTING_GENERATOR);
86     }
87   }
89   try {
90     var rval = { value: val, done: true };
91     return resumeGenerator(this, rval, "return");
92   } catch (e) {
93     if (!GeneratorObjectIsClosed(this)) {
94       GeneratorSetClosed(this);
95     }
96     throw e;
97   }
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.
105   forceInterpreter();
106   if (kind === "next") {
107     return resumeGenerator(gen, val, "next");
108   }
109   if (kind === "throw") {
110     return resumeGenerator(gen, val, "throw");
111   }
112   assert(kind === "return", "Invalid resume kind");
113   return resumeGenerator(gen, val, "return");