Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Side by Side Diff: src/js/generator.js

Issue 1606273002: Implement [Generator].prototype.return. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 })
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698