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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: src/js/generator.js
diff --git a/src/js/generator.js b/src/js/generator.js
index 7f43656ebcf5c1fb4cfb5eca311e8381082f5c33..c88b15d2b46bb8a5a9d05679638b305def175a70 100644
--- a/src/js/generator.js
+++ b/src/js/generator.js
@@ -26,6 +26,23 @@ utils.Import(function(from) {
// Generator functions and objects are specified by ES6, sections 15.19.3 and
// 15.19.4.
+// Explanation of the use of %GeneratorClose:
+//
+// There are two situations in which resuming a generator must result in
+// closing it (in ES6 terms: setting [[GeneratorState]] to "completed").
+// - When the generator throws. We close it by calling %GeneratorClose in the
+// catch blocks below.
+// - When the generator returns a "done" iterator result.
+// * For GeneratorObjectNext and GeneratorObjectThrow this can only happen
+// when the generator hits a "final" yield (as introduced by the
+// parser). A final yield already takes care of closing the generator
+// itself, so we don't need to do it here.
+// * For GeneratorObjectReturn this can also happen if the triggered return is
+// not "caught" and terminates the generator. We handle this here by just
+// always calling %GeneratorClose when the received result is "done". This
+// may include cases where the generator has already been closed but doing
+// it twice is harmless.
+
function GeneratorObjectNext(value) {
if (!IS_GENERATOR(this)) {
throw MakeTypeError(kIncompatibleMethodReceiver,
@@ -44,7 +61,35 @@ function GeneratorObjectNext(value) {
}
} else if (continuation == 0) {
// Generator is already closed.
- return { value: void 0, done: true };
+ 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
+ } else {
+ // Generator is running.
+ throw MakeTypeError(kGeneratorRunning);
+ }
+}
+
+
+function GeneratorObjectReturn(value) {
+ if (!IS_GENERATOR(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ '[Generator].prototype.return', this);
+ }
+
+ var continuation = %GeneratorGetContinuation(this);
+ if (continuation > 0) {
+ // Generator is suspended.
+ DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
+ try {
+ let result = %_GeneratorReturn(this, value);
+ if (result.done) %GeneratorClose(this);
+ return result;
+ } catch (e) {
+ %GeneratorClose(this);
+ throw e;
+ }
+ } else if (continuation == 0) {
+ // Generator is already closed.
+ return { value: value, done: true };
Benedikt Meurer 2016/01/21 05:09:02 Use %_CreateIterResultObject, as explained above.
} else {
// Generator is running.
throw MakeTypeError(kGeneratorRunning);
@@ -78,9 +123,11 @@ function GeneratorObjectThrow(exn) {
// ----------------------------------------------------------------------------
-// Both Runtime_GeneratorNext and Runtime_GeneratorThrow are supported by
-// neither Crankshaft nor TurboFan, disable optimization of wrappers here.
+// None of the three resume operations (Runtime_GeneratorNext,
+// Runtime_GeneratorReturn, Runtime_GeneratorThrow) is supported by
+// Crankshaft or TurboFan. Disable optimization of wrappers here.
%NeverOptimizeFunction(GeneratorObjectNext);
+%NeverOptimizeFunction(GeneratorObjectReturn);
%NeverOptimizeFunction(GeneratorObjectThrow);
// Set up non-enumerable functions on the generator prototype object.
@@ -88,6 +135,7 @@ var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
utils.InstallFunctions(GeneratorObjectPrototype,
DONT_ENUM,
["next", GeneratorObjectNext,
+ "return", GeneratorObjectReturn,
"throw", GeneratorObjectThrow]);
%AddNamedProperty(GeneratorObjectPrototype, "constructor",

Powered by Google App Engine
This is Rietveld 408576698