Chromium Code Reviews| 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 |