Index: src/js/generator.js |
diff --git a/src/js/generator.js b/src/js/generator.js |
index 7f43656ebcf5c1fb4cfb5eca311e8381082f5c33..6aad8e1624e7abe9b9fa687d497b2e25e1ce87dc 100644 |
--- a/src/js/generator.js |
+++ b/src/js/generator.js |
@@ -37,14 +37,44 @@ function GeneratorObjectNext(value) { |
// Generator is suspended. |
DEBUG_PREPARE_STEP_IN_IF_STEPPING(this); |
try { |
- return %_GeneratorNext(this, value); |
+ let result = %_GeneratorNext(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: void 0, done: true }; |
+ return %_CreateIterResultObject(UNDEFINED, true); |
+ } 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 %_CreateIterResultObject(value, true); |
} else { |
// Generator is running. |
throw MakeTypeError(kGeneratorRunning); |
@@ -62,7 +92,9 @@ function GeneratorObjectThrow(exn) { |
if (continuation > 0) { |
// Generator is suspended. |
try { |
- return %_GeneratorThrow(this, exn); |
+ let result = %_GeneratorThrow(this, exn); |
+ if (result.done) %GeneratorClose(this); |
+ return result; |
} catch (e) { |
%GeneratorClose(this); |
throw e; |
@@ -78,9 +110,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 +122,7 @@ var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype; |
utils.InstallFunctions(GeneratorObjectPrototype, |
DONT_ENUM, |
["next", GeneratorObjectNext, |
+ "return", GeneratorObjectReturn, |
"throw", GeneratorObjectThrow]); |
%AddNamedProperty(GeneratorObjectPrototype, "constructor", |