OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, utils) { | 5 (function(global, utils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
11 // ------------------------------------------------------------------- | 11 // ------------------------------------------------------------------- |
12 // Imports | 12 // Imports |
13 | 13 |
14 var GeneratorFunctionPrototype = utils.ImportNow("GeneratorFunctionPrototype"); | 14 var GeneratorFunctionPrototype = utils.ImportNow("GeneratorFunctionPrototype"); |
15 var GeneratorFunction = utils.ImportNow("GeneratorFunction"); | 15 var GeneratorFunction = utils.ImportNow("GeneratorFunction"); |
16 var GlobalFunction = global.Function; | 16 var GlobalFunction = global.Function; |
17 var MakeTypeError; | 17 var MakeTypeError; |
18 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 18 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
19 | 19 |
20 utils.Import(function(from) { | 20 utils.Import(function(from) { |
21 MakeTypeError = from.MakeTypeError; | 21 MakeTypeError = from.MakeTypeError; |
22 }); | 22 }); |
23 | 23 |
24 // ---------------------------------------------------------------------------- | 24 // ---------------------------------------------------------------------------- |
25 | 25 |
26 // Generator functions and objects are specified by ES6, sections 15.19.3 and | 26 // Generator functions and objects are specified by ES6, sections 15.19.3 and |
27 // 15.19.4. | 27 // 15.19.4. |
28 | 28 |
29 // Explanation of the use of %GeneratorClose: | |
30 // | |
31 // There are two situations in which resuming a generator must result in | |
32 // closing it (in ES6 terms: setting [[GeneratorState]] to "completed"). | |
33 // - When the generator throws. We close it by calling %GeneratorClose in the | |
34 // catch blocks below. | |
35 // - When the generator returns a "done" iterator result. | |
36 // * For GeneratorObjectNext and GeneratorObjectThrow this can only happen | |
37 // when the generator hits a "final" yield (as introduced by the | |
38 // parser). A final yield already takes care of closing the generator | |
39 // itself, so we don't need to do it here. | |
40 // * For GeneratorObjectReturn this can also happen if the triggered return is | |
41 // not "caught" and terminates the generator. We handle this here by just | |
42 // always calling %GeneratorClose when the received result is "done". This | |
43 // may include cases where the generator has already been closed but doing | |
44 // it twice is harmless. | |
45 | |
29 function GeneratorObjectNext(value) { | 46 function GeneratorObjectNext(value) { |
30 if (!IS_GENERATOR(this)) { | 47 if (!IS_GENERATOR(this)) { |
31 throw MakeTypeError(kIncompatibleMethodReceiver, | 48 throw MakeTypeError(kIncompatibleMethodReceiver, |
32 '[Generator].prototype.next', this); | 49 '[Generator].prototype.next', this); |
33 } | 50 } |
34 | 51 |
35 var continuation = %GeneratorGetContinuation(this); | 52 var continuation = %GeneratorGetContinuation(this); |
36 if (continuation > 0) { | 53 if (continuation > 0) { |
37 // Generator is suspended. | 54 // Generator is suspended. |
38 DEBUG_PREPARE_STEP_IN_IF_STEPPING(this); | 55 DEBUG_PREPARE_STEP_IN_IF_STEPPING(this); |
39 try { | 56 try { |
40 return %_GeneratorNext(this, value); | 57 return %_GeneratorNext(this, value); |
41 } catch (e) { | 58 } catch (e) { |
42 %GeneratorClose(this); | 59 %GeneratorClose(this); |
43 throw e; | 60 throw e; |
44 } | 61 } |
45 } else if (continuation == 0) { | 62 } else if (continuation == 0) { |
46 // Generator is already closed. | 63 // Generator is already closed. |
47 return { value: void 0, done: true }; | 64 return { value: UNDEFINED, done: true }; |
Dan Ehrenberg
2016/01/20 23:48:21
Not that this should be done in this patch, but sh
Benedikt Meurer
2016/01/21 05:09:02
Nice catch! Yes that should use %_CreateIterResult
| |
48 } else { | 65 } else { |
49 // Generator is running. | 66 // Generator is running. |
50 throw MakeTypeError(kGeneratorRunning); | 67 throw MakeTypeError(kGeneratorRunning); |
68 } | |
69 } | |
70 | |
71 | |
72 function GeneratorObjectReturn(value) { | |
73 if (!IS_GENERATOR(this)) { | |
74 throw MakeTypeError(kIncompatibleMethodReceiver, | |
75 '[Generator].prototype.return', this); | |
76 } | |
77 | |
78 var continuation = %GeneratorGetContinuation(this); | |
79 if (continuation > 0) { | |
80 // Generator is suspended. | |
81 DEBUG_PREPARE_STEP_IN_IF_STEPPING(this); | |
82 try { | |
83 let result = %_GeneratorReturn(this, value); | |
84 if (result.done) %GeneratorClose(this); | |
85 return result; | |
86 } catch (e) { | |
87 %GeneratorClose(this); | |
88 throw e; | |
89 } | |
90 } else if (continuation == 0) { | |
91 // Generator is already closed. | |
92 return { value: value, done: true }; | |
Benedikt Meurer
2016/01/21 05:09:02
Use %_CreateIterResultObject, as explained above.
| |
93 } else { | |
94 // Generator is running. | |
95 throw MakeTypeError(kGeneratorRunning); | |
51 } | 96 } |
52 } | 97 } |
53 | 98 |
54 | 99 |
55 function GeneratorObjectThrow(exn) { | 100 function GeneratorObjectThrow(exn) { |
56 if (!IS_GENERATOR(this)) { | 101 if (!IS_GENERATOR(this)) { |
57 throw MakeTypeError(kIncompatibleMethodReceiver, | 102 throw MakeTypeError(kIncompatibleMethodReceiver, |
58 '[Generator].prototype.throw', this); | 103 '[Generator].prototype.throw', this); |
59 } | 104 } |
60 | 105 |
(...skipping 10 matching lines...) Expand all Loading... | |
71 // Generator is already closed. | 116 // Generator is already closed. |
72 throw exn; | 117 throw exn; |
73 } else { | 118 } else { |
74 // Generator is running. | 119 // Generator is running. |
75 throw MakeTypeError(kGeneratorRunning); | 120 throw MakeTypeError(kGeneratorRunning); |
76 } | 121 } |
77 } | 122 } |
78 | 123 |
79 // ---------------------------------------------------------------------------- | 124 // ---------------------------------------------------------------------------- |
80 | 125 |
81 // Both Runtime_GeneratorNext and Runtime_GeneratorThrow are supported by | 126 // None of the three resume operations (Runtime_GeneratorNext, |
82 // neither Crankshaft nor TurboFan, disable optimization of wrappers here. | 127 // Runtime_GeneratorReturn, Runtime_GeneratorThrow) is supported by |
128 // Crankshaft or TurboFan. Disable optimization of wrappers here. | |
83 %NeverOptimizeFunction(GeneratorObjectNext); | 129 %NeverOptimizeFunction(GeneratorObjectNext); |
130 %NeverOptimizeFunction(GeneratorObjectReturn); | |
84 %NeverOptimizeFunction(GeneratorObjectThrow); | 131 %NeverOptimizeFunction(GeneratorObjectThrow); |
85 | 132 |
86 // Set up non-enumerable functions on the generator prototype object. | 133 // Set up non-enumerable functions on the generator prototype object. |
87 var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype; | 134 var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype; |
88 utils.InstallFunctions(GeneratorObjectPrototype, | 135 utils.InstallFunctions(GeneratorObjectPrototype, |
89 DONT_ENUM, | 136 DONT_ENUM, |
90 ["next", GeneratorObjectNext, | 137 ["next", GeneratorObjectNext, |
138 "return", GeneratorObjectReturn, | |
91 "throw", GeneratorObjectThrow]); | 139 "throw", GeneratorObjectThrow]); |
92 | 140 |
93 %AddNamedProperty(GeneratorObjectPrototype, "constructor", | 141 %AddNamedProperty(GeneratorObjectPrototype, "constructor", |
94 GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY); | 142 GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY); |
95 %AddNamedProperty(GeneratorObjectPrototype, | 143 %AddNamedProperty(GeneratorObjectPrototype, |
96 toStringTagSymbol, "Generator", DONT_ENUM | READ_ONLY); | 144 toStringTagSymbol, "Generator", DONT_ENUM | READ_ONLY); |
97 %InternalSetPrototype(GeneratorFunctionPrototype, GlobalFunction.prototype); | 145 %InternalSetPrototype(GeneratorFunctionPrototype, GlobalFunction.prototype); |
98 %AddNamedProperty(GeneratorFunctionPrototype, | 146 %AddNamedProperty(GeneratorFunctionPrototype, |
99 toStringTagSymbol, "GeneratorFunction", DONT_ENUM | READ_ONLY); | 147 toStringTagSymbol, "GeneratorFunction", DONT_ENUM | READ_ONLY); |
100 %AddNamedProperty(GeneratorFunctionPrototype, "constructor", | 148 %AddNamedProperty(GeneratorFunctionPrototype, "constructor", |
101 GeneratorFunction, DONT_ENUM | READ_ONLY); | 149 GeneratorFunction, DONT_ENUM | READ_ONLY); |
102 %InternalSetPrototype(GeneratorFunction, GlobalFunction); | 150 %InternalSetPrototype(GeneratorFunction, GlobalFunction); |
103 | 151 |
104 }) | 152 }) |
OLD | NEW |