summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/language/expressions/yield
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test262/language/expressions/yield')
-rw-r--r--js/src/tests/test262/language/expressions/yield/arguments-object-attributes.js43
-rw-r--r--js/src/tests/test262/language/expressions/yield/browser.js0
-rw-r--r--js/src/tests/test262/language/expressions/yield/captured-free-vars.js38
-rw-r--r--js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js47
-rw-r--r--js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-strict-strict.js48
-rw-r--r--js/src/tests/test262/language/expressions/yield/formal-parameters.js43
-rw-r--r--js/src/tests/test262/language/expressions/yield/from-catch.js29
-rw-r--r--js/src/tests/test262/language/expressions/yield/from-try.js29
-rw-r--r--js/src/tests/test262/language/expressions/yield/from-with.js42
-rw-r--r--js/src/tests/test262/language/expressions/yield/in-iteration-stmt.js24
-rw-r--r--js/src/tests/test262/language/expressions/yield/in-rltn-expr.js50
-rw-r--r--js/src/tests/test262/language/expressions/yield/invalid-left-hand-side.js29
-rw-r--r--js/src/tests/test262/language/expressions/yield/iter-value-specified.js31
-rw-r--r--js/src/tests/test262/language/expressions/yield/iter-value-unspecified.js26
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-iter.js41
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-omitted.js128
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-primitive.js118
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-regexp.js45
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-template-middle.js40
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-unresolvable.js33
-rw-r--r--js/src/tests/test262/language/expressions/yield/rhs-yield.js28
-rw-r--r--js/src/tests/test262/language/expressions/yield/shell.js0
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-array.js33
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-in-iteration-stmt.js24
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-in-rltn-expr.js50
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-iterable.js42
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-return-is-null.js57
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-err.js45
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-non-obj.js44
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-get-err.js45
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-err.js52
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-non-obj.js53
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-get-err.js53
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-invoke.js54
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-err.js55
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-no-value.js62
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-err.js58
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-final.js64
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-no-rtrn.js78
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-err.js69
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-no-value.js93
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-err.js72
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-final.js73
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-err.js57
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-non-obj.js60
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-get-err.js67
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-invoke.js59
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-err.js68
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-no-value.js78
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-err.js71
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-final.js56
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-err.js54
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-non-obj.js59
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-get-err.js57
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-invoke.js56
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-no-rtrn.js82
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-err.js73
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-non-obj.js70
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-get-err.js75
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-invoke.js91
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-rhs-unresolvable.js33
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-string.js33
-rw-r--r--js/src/tests/test262/language/expressions/yield/star-throw-is-null.js73
-rw-r--r--js/src/tests/test262/language/expressions/yield/then-return.js24
-rw-r--r--js/src/tests/test262/language/expressions/yield/within-for.js34
65 files changed, 3418 insertions, 0 deletions
diff --git a/js/src/tests/test262/language/expressions/yield/arguments-object-attributes.js b/js/src/tests/test262/language/expressions/yield/arguments-object-attributes.js
new file mode 100644
index 0000000000..d6db638781
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/arguments-object-attributes.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ Attributes of the `arguments` object are valid yield expression operands.
+features: [generators]
+---*/
+
+function* g() {
+ yield arguments[0];
+ yield arguments[1];
+ yield arguments[2];
+ yield arguments[3];
+}
+var iter = g(23, 45, 33);
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 23, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 45, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 33, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Fourth result `value` (unspecified parameter)'
+);
+assert.sameValue(
+ result.done, false, 'Fourth result `done` flag (unspecified parameter)'
+);
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/browser.js b/js/src/tests/test262/language/expressions/yield/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/browser.js
diff --git a/js/src/tests/test262/language/expressions/yield/captured-free-vars.js b/js/src/tests/test262/language/expressions/yield/captured-free-vars.js
new file mode 100644
index 0000000000..569cfba77c
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/captured-free-vars.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ Free variables captured within the GeneratorFunction closure are valid
+ yield expression operands.
+features: [generators]
+---*/
+
+var a = 1;
+var b = 2;
+var c = 3;
+function* g() {
+ yield a;
+ yield b;
+ yield c;
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 2, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 3, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js b/js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js
new file mode 100644
index 0000000000..b79ec78a6b
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-non-strict.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ Formal parameters are valid yield expression operands.
+flags: [noStrict]
+features: [generators]
+---*/
+
+function* g(a, b, c, d) {
+ arguments[0] = 32;
+ arguments[1] = 54;
+ arguments[2] = 333;
+ yield a;
+ yield b;
+ yield c;
+ yield d;
+}
+var iter = g(23, 45, 33);
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 32, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 54, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 333, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Fourth result `value` (unspecified parameter)'
+);
+assert.sameValue(
+ result.done, false, 'Fourth result `done` flag (unspecified parameter)'
+);
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-strict-strict.js b/js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-strict-strict.js
new file mode 100644
index 0000000000..aa5c3a1b1e
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/formal-parameters-after-reassignment-strict-strict.js
@@ -0,0 +1,48 @@
+'use strict';
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ Formal parameters are valid yield expression operands.
+flags: [onlyStrict]
+features: [generators]
+---*/
+
+function* g(a, b, c, d) {
+ arguments[0] = 32;
+ arguments[1] = 54;
+ arguments[2] = 333;
+ yield a;
+ yield b;
+ yield c;
+ yield d;
+}
+var iter = g(23, 45, 33);
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 23, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 45, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 33, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Fourth result `value` (unspecified parameter)'
+);
+assert.sameValue(
+ result.done, false, 'Fourth result `done` flag (unspecified parameter)'
+);
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/formal-parameters.js b/js/src/tests/test262/language/expressions/yield/formal-parameters.js
new file mode 100644
index 0000000000..83467fc2b9
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/formal-parameters.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ Formal parameters are valid yield expression operands.
+features: [generators]
+---*/
+
+function* g(a, b, c, d) {
+ yield a;
+ yield b;
+ yield c;
+ yield d;
+}
+var iter = g(23, 45, 33);
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 23, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 45, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 33, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Fourth result `value` (unspecified parameter)'
+);
+assert.sameValue(
+ result.done, false, 'Fourth result `done` flag (unspecified parameter)'
+);
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/from-catch.js b/js/src/tests/test262/language/expressions/yield/from-catch.js
new file mode 100644
index 0000000000..a90a9ae34e
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/from-catch.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ The behavior of `yield` expressions should not be affected when they appear
+ within the `catch` block of `try` statements.
+features: [generators]
+---*/
+
+function* g() {
+ try {
+ throw new Error();
+ } catch (err) {
+ yield 1;
+ }
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done`flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/from-try.js b/js/src/tests/test262/language/expressions/yield/from-try.js
new file mode 100644
index 0000000000..732ff70b78
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/from-try.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ The behavior of `yield` expressions should not be affected when they appear
+ within the `try` block of `try` statements.
+features: [generators]
+---*/
+
+function* g() {
+ try {
+ yield 1;
+ } catch (err) {
+ throw err;
+ }
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done`flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/from-with.js b/js/src/tests/test262/language/expressions/yield/from-with.js
new file mode 100644
index 0000000000..6d30c8ecaf
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/from-with.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ The operand to a `yield` expression should honor the semantics of the
+ `with` statement.
+flags: [noStrict]
+features: [generators]
+---*/
+
+function* g() {
+ var x = 1;
+
+ yield x;
+
+ with ({ x: 2 }) {
+ yield x;
+ }
+
+ yield x;
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 2, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/in-iteration-stmt.js b/js/src/tests/test262/language/expressions/yield/in-iteration-stmt.js
new file mode 100644
index 0000000000..f85781f867
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/in-iteration-stmt.js
@@ -0,0 +1,24 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: >
+ YieldExpression operand may not include the `in` keyword in contexts where it
+ is disallowed
+info: |
+ Syntax
+
+ yield [no LineTerminator here] AssignmentExpression[?In, +Yield]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [generators]
+---*/
+
+$DONOTEVALUATE();
+
+function* g() {
+ for (yield '' in {}; ; ) ;
+}
diff --git a/js/src/tests/test262/language/expressions/yield/in-rltn-expr.js b/js/src/tests/test262/language/expressions/yield/in-rltn-expr.js
new file mode 100644
index 0000000000..1d1e69ceb5
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/in-rltn-expr.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: >
+ YieldExpression contextually recognizes the `in` keyword as part of a
+ RelationalExpression
+info: |
+ Syntax
+
+ yield [no LineTerminator here] AssignmentExpression[?In, +Yield]
+features: [generators]
+---*/
+
+var obj = Object.create(null);
+var iter, iterResult, value;
+function* g() {
+ value = yield 'hit' in obj;
+ value = yield 'miss' in obj;
+}
+obj.hit = true;
+
+iter = g();
+
+iterResult = iter.next('first');
+
+assert.sameValue(iterResult.done, false, '`done` property (first iteration)');
+assert.sameValue(iterResult.value, true, '`value` property (first iteration)');
+assert.sameValue(
+ value, undefined, 'generator paused prior to evaluating AssignmentExpression'
+);
+
+iterResult = iter.next('second');
+
+assert.sameValue(iterResult.done, false, '`done` property (second iteration)');
+assert.sameValue(
+ iterResult.value, false, '`value` property (second iteration)'
+);
+assert.sameValue(value, 'second', 'value of first AssignmentExpression');
+
+iterResult = iter.next('third');
+
+assert.sameValue(iterResult.done, true, '`done` property (third iteration)');
+assert.sameValue(
+ iterResult.value, undefined, '`value` property (third iteration)'
+);
+assert.sameValue(value, 'third', 'value of second AssignmentExpression');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/invalid-left-hand-side.js b/js/src/tests/test262/language/expressions/yield/invalid-left-hand-side.js
new file mode 100644
index 0000000000..656e27d75f
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/invalid-left-hand-side.js
@@ -0,0 +1,29 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: A YieldExpression is not a valid LeftHandSideExpression
+info: |
+ AssignmentExpression[In, Yield] :
+ ConditionalExpression[?In, ?Yield]
+ [+Yield]YieldExpression[?In]
+ ArrowFunction[?In, ?Yield]
+ LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
+ LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
+
+ LeftHandSideExpression[Yield] :
+ NewExpression[?Yield]
+ CallExpression[?Yield]
+features: [generators]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+function* g() {
+ yield = 1;
+}
diff --git a/js/src/tests/test262/language/expressions/yield/iter-value-specified.js b/js/src/tests/test262/language/expressions/yield/iter-value-specified.js
new file mode 100644
index 0000000000..cd5355f6d0
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/iter-value-specified.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ When the `next` method of a generator-produced iterable is invoked without
+ an argument, the corresponding `yield` expression should be evaluated as
+ `undefined`.
+features: [generators]
+---*/
+
+function* g() { actual = yield; }
+var expected = {};
+var iter = g();
+var actual, result;
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+assert.sameValue(
+ actual, undefined, 'Value of `yield` expression (prior to continuation)'
+);
+
+result = iter.next(expected);
+assert.sameValue(result.value, undefined, 'Second result `value`');
+assert.sameValue(result.done, true, 'Second result `done` flag');
+assert.sameValue(
+ actual, expected, 'Value of `yield` expression (following continuation)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/iter-value-unspecified.js b/js/src/tests/test262/language/expressions/yield/iter-value-unspecified.js
new file mode 100644
index 0000000000..97a0c7522d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/iter-value-unspecified.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ When the `next` method of a generator-produced iterable is invoked without
+ an argument, the corresponding `yield` expression should be evaluated as
+ `undefined`.
+features: [generators]
+---*/
+
+function* g() { actual = yield; }
+var iter = g();
+var actual, result;
+
+result = iter.next();
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, false);
+assert.sameValue(actual, undefined);
+
+result = iter.next();
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(actual, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-iter.js b/js/src/tests/test262/language/expressions/yield/rhs-iter.js
new file mode 100644
index 0000000000..c837ba837a
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-iter.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Iteration protocol is not initiated for non-delegating YieldExpression
+info: |
+ YieldExpression:yieldAssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Return ? GeneratorYield(CreateIterResultObject(value, false)).
+features: [generators, Symbol.iterator]
+---*/
+
+var callCount = 0;
+var iterSpy = Object.defineProperty({}, Symbol.iterator, {
+ get: function() {
+ callCount += 1;
+ }
+});
+function* g() {
+ yield iterSpy;
+}
+var iter = g();
+var result;
+
+result = iter.next();
+
+assert.sameValue(result.value, iterSpy);
+assert.sameValue(result.done, false);
+assert.sameValue(callCount, 0);
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(callCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-omitted.js b/js/src/tests/test262/language/expressions/yield/rhs-omitted.js
new file mode 100644
index 0000000000..23c3f710ff
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-omitted.js
@@ -0,0 +1,128 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `yield` is a valid expression within generator function bodies.
+es6id: 14.4
+features: [generators]
+---*/
+
+var iter, result;
+function* g1() { (yield) }
+function* g2() { [yield] }
+function* g3() { {yield} }
+function* g4() { yield, yield; }
+function* g5() { (yield) ? yield : yield; }
+
+iter = g1();
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Within grouping operator: result `value`'
+);
+assert.sameValue(
+ result.done, false, 'Within grouping operator: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following grouping operator: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following grouping operator: result `done` flag'
+);
+
+iter = g2();
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Within array literal: result `value`'
+);
+assert.sameValue(
+ result.done, false, 'Within array literal: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following array literal: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following array literal: result `done` flag'
+);
+
+iter = g3();
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Within object literal: result `value`'
+);
+assert.sameValue(
+ result.done, false, 'Within object literal: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following object literal: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following object literal: result `done` flag'
+);
+
+iter = g4();
+result = iter.next();
+assert.sameValue(
+ result.value,
+ undefined,
+ 'First expression in comma expression: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'First expression in comma expression: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value,
+ undefined,
+ 'Second expression in comma expression: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Second expression in comma expression: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following comma expression: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following comma expression: result `done` flag'
+);
+
+iter = g5();
+result = iter.next();
+assert.sameValue(
+ result.value,
+ undefined,
+ 'Conditional expression in conditional operator: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Conditional expression in conditional operator: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value,
+ undefined,
+ 'Branch in conditional operator: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Branch in conditional operator: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following conditional operator: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following conditional operator: result `done` flag'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-primitive.js b/js/src/tests/test262/language/expressions/yield/rhs-primitive.js
new file mode 100644
index 0000000000..bde90dfbd8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-primitive.js
@@ -0,0 +1,118 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `yield` is a valid expression within generator function bodies.
+es6id: 14.4
+features: [generators]
+---*/
+
+var result, iter;
+function* g1() { (yield 1) }
+function* g2() { [yield 1] }
+function* g3() { {yield 1} }
+function* g4() { yield 1, yield 2; }
+function* g5() { (yield 1) ? yield 2 : yield 3; }
+
+iter = g1();
+result = iter.next();
+assert.sameValue(result.value, 1, 'Within grouping operator: result `value`');
+assert.sameValue(
+ result.done, false, 'Within grouping operator: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following grouping operator: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following grouping operator: result `done` flag'
+);
+
+iter = g2();
+result = iter.next();
+assert.sameValue(result.value, 1, 'Within array literal: result `value`');
+assert.sameValue(
+ result.done, false, 'Within array literal: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following array literal: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following array literal: result `done` flag'
+);
+
+iter = g3();
+result = iter.next();
+assert.sameValue(result.value, 1, 'Within object literal: result `value`');
+assert.sameValue(
+ result.done, false, 'Within object literal: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following object literal: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following object literal: result `done` flag'
+);
+
+iter = g4();
+result = iter.next();
+assert.sameValue(
+ result.value, 1, 'First expression in comma expression: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'First expression in comma expression: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, 2, 'Second expression in comma expression: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Second expression in comma expression: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following comma expression: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following comma expression: result `done` flag'
+);
+
+iter = g5();
+result = iter.next();
+assert.sameValue(
+ result.value,
+ 1,
+ 'Conditional expression in conditional operator: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Conditional expression in conditional operator: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value,
+ 3,
+ 'Branch in conditional operator: result `value`'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Branch in conditional operator: result `done` flag'
+);
+result = iter.next();
+assert.sameValue(
+ result.value, undefined, 'Following conditional operator: result `value`'
+);
+assert.sameValue(
+ result.done, true, 'Following conditional operator: result `done` flag'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-regexp.js b/js/src/tests/test262/language/expressions/yield/rhs-regexp.js
new file mode 100644
index 0000000000..96ee0985ed
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-regexp.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: >
+ YieldExpression accepts a regular expression literal as its right-hand side
+info: |
+ The syntactic context immediately following yield requires use of the
+ InputElementRegExpOrTemplateTail lexical goal.
+features: [generators]
+---*/
+
+var complete = false;
+var sent = {};
+var iter, iterResult, received;
+// Unused variables declared to improve error messages in incorrect parsing
+// scenarios.
+var abc, i;
+function* g() {
+ received = yield/abc/i;
+ complete = true;
+}
+
+iter = g();
+
+assert.sameValue(complete, false, 'generator initially paused');
+assert.sameValue(received, undefined, 'first statement no executed');
+
+iterResult = iter.next();
+
+assert.sameValue(complete, false, 'generator paused following expression');
+assert.sameValue(received, undefined, 'first statement not executed');
+
+assert.sameValue(iterResult.done, false, 'iteration not complete');
+assert.sameValue(iterResult.value.test('ABC'), true, 'first iterated value');
+
+iterResult = iter.next(sent);
+
+assert.sameValue(received, sent, 'YieldExpression value');
+assert.sameValue(complete, true, 'generator correctly re-started');
+assert.sameValue(iterResult.done, true, 'iteration complete');
+assert.sameValue(iterResult.value, undefined, 'second iterated value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-template-middle.js b/js/src/tests/test262/language/expressions/yield/rhs-template-middle.js
new file mode 100644
index 0000000000..051e6dbab0
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-template-middle.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: YieldExpression may be followed by a TemplateMiddle construct
+info: |
+ The syntactic context immediately following yield requires use of the
+ InputElementRegExpOrTemplateTail lexical goal.
+features: [generators]
+---*/
+
+var complete = false;
+var iter, iterResult, str;
+function* g() {
+ str = `1${ yield }3${ 4 }5`;
+ complete = true;
+}
+
+iter = g();
+
+assert.sameValue(complete, false, 'generator initially paused');
+assert.sameValue(str, undefined, 'first statement not executed');
+
+iterResult = iter.next();
+
+assert.sameValue(complete, false, 'generator paused following expression');
+assert.sameValue(str, undefined, 'first statement not executed');
+
+assert.sameValue(iterResult.done, false, 'iteration not complete');
+assert.sameValue(iterResult.value, undefined, 'first iterated value');
+
+iterResult = iter.next(2);
+
+assert.sameValue(str, '12345', 'YieldExpression value');
+assert.sameValue(complete, true, 'generator correctly re-started');
+assert.sameValue(iterResult.done, true, 'iteration complete');
+assert.sameValue(iterResult.value, undefined, 'second iterated value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-unresolvable.js b/js/src/tests/test262/language/expressions/yield/rhs-unresolvable.js
new file mode 100644
index 0000000000..b20f397850
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-unresolvable.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: GetValue invoked on Reference value
+info: |
+ YieldExpression : yield AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+features: [generators]
+---*/
+
+var err;
+function* g() {
+ try {
+ yield test262unresolvable;
+ } catch (_err) {
+ err = _err;
+ }
+}
+var iter = g();
+var result;
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(typeof err, 'object');
+assert.sameValue(err.constructor, ReferenceError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/rhs-yield.js b/js/src/tests/test262/language/expressions/yield/rhs-yield.js
new file mode 100644
index 0000000000..1962517b83
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/rhs-yield.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ Yield expressions are valid yield expression operands.
+features: [generators]
+---*/
+
+function* g() {
+ yield yield 1;
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next(3);
+assert.sameValue(result.value, 3, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done`flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/shell.js b/js/src/tests/test262/language/expressions/yield/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/shell.js
diff --git a/js/src/tests/test262/language/expressions/yield/star-array.js b/js/src/tests/test262/language/expressions/yield/star-array.js
new file mode 100644
index 0000000000..8e85b126e1
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-array.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ When an array is the operand of a `yield *` expression, the generator
+ should produce an iterator that visits each element in order.
+features: [generators]
+---*/
+
+function* g() {
+ yield* [1, 2, 3];
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 2, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 3, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-in-iteration-stmt.js b/js/src/tests/test262/language/expressions/yield/star-in-iteration-stmt.js
new file mode 100644
index 0000000000..4511806e2f
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-in-iteration-stmt.js
@@ -0,0 +1,24 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: >
+ YieldExpression operand may not include the `in` keyword in contexts where it
+ is disallowed
+info: |
+ Syntax
+
+ yield [no LineTerminator here] * AssignmentExpression[?In, +Yield]
+negative:
+ phase: parse
+ type: SyntaxError
+features: [generators]
+---*/
+
+$DONOTEVALUATE();
+
+function* g() {
+ for (yield * '' in {}; ; ) ;
+}
diff --git a/js/src/tests/test262/language/expressions/yield/star-in-rltn-expr.js b/js/src/tests/test262/language/expressions/yield/star-in-rltn-expr.js
new file mode 100644
index 0000000000..3aa00be2b2
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-in-rltn-expr.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions
+es6id: 14.4
+description: >
+ YieldExpression contextually recognizes the `in` keyword as part of a
+ RelationalExpression
+info: |
+ Syntax
+
+ yield [no LineTerminator here] AssignmentExpression[?In, +Yield]
+features: [generators, Symbol.iterator]
+---*/
+
+var obj = Object.create({ hit: true });
+var iter, iterResult, value;
+Boolean.prototype[Symbol.iterator] = function* () { yield this.valueOf(); };
+function* g() {
+ value = yield * 'hit' in obj;
+ value = yield * 'miss' in obj;
+}
+
+iter = g();
+
+iterResult = iter.next('first');
+
+assert.sameValue(iterResult.done, false, '`done` property (first iteration)');
+assert.sameValue(iterResult.value, true, '`value` property (first iteration)');
+assert.sameValue(
+ value, undefined, 'generator paused prior to evaluating AssignmentExpression'
+);
+
+iterResult = iter.next('second');
+
+assert.sameValue(iterResult.done, false, '`done` property (second iteration)');
+assert.sameValue(
+ iterResult.value, false, '`value` property (second iteration)'
+);
+assert.sameValue(value, undefined, 'value of first AssignmentExpression');
+
+iterResult = iter.next('third');
+
+assert.sameValue(iterResult.done, true, '`done` property (third iteration)');
+assert.sameValue(
+ iterResult.value, undefined, '`value` property (third iteration)'
+);
+assert.sameValue(value, undefined, 'value of second AssignmentExpression');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-iterable.js b/js/src/tests/test262/language/expressions/yield/star-iterable.js
new file mode 100644
index 0000000000..4c00f343ca
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-iterable.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ When an iterator is the operand of a `yield *` expression, the generator
+ should produce an iterator that visits each iterated item.
+features: [generators, Symbol.iterator]
+---*/
+
+var results = [{ value: 1 }, { value: 8 }, { value: 34, done: true }];
+var idx = 0;
+var iterator = {};
+var iterable = {
+ next: function() {
+ var result = results[idx];
+ idx += 1;
+ return result;
+ }
+};
+iterator[Symbol.iterator] = function() {
+ return iterable;
+};
+function* g() {
+ yield* iterator;
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, undefined, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 8, 'Third result `value`');
+assert.sameValue(result.done, undefined, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-return-is-null.js b/js/src/tests/test262/language/expressions/yield/star-return-is-null.js
new file mode 100644
index 0000000000..3b703ee5f8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-return-is-null.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: >
+ If iterator's "return" method is `null`,
+ received completion is forwarded to the runtime.
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ [...]
+ 7. Repeat,
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, then
+ [...]
+ 2. Return Completion(received).
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+features: [generators, Symbol.iterator]
+---*/
+
+var returnGets = 0;
+var iterable = {
+ next: function() {
+ return {value: 1, done: false};
+ },
+ get return() {
+ returnGets += 1;
+ return null;
+ },
+};
+
+iterable[Symbol.iterator] = function() {
+ return iterable;
+};
+
+function* generator() {
+ yield* iterable;
+}
+
+var iterator = generator();
+iterator.next();
+
+var result = iterator.return(2);
+assert.sameValue(result.value, 2);
+assert.sameValue(result.done, true);
+
+assert.sameValue(returnGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-err.js
new file mode 100644
index 0000000000..74a20e2a24
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-err.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when invoking the @@iterator method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+
+ 7.4.1 GetIterator
+
+ 1. If method was not passed, then
+ a. Let method be ? GetMethod(obj, @@iterator).
+ 2. Let iterator be ? Call(method, obj).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ throw thrown;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+assert.sameValue(caught, undefined, 'method is not invoked eagerly');
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined, 'iteration value');
+assert.sameValue(result.done, true, 'iteration status');
+assert.sameValue(caught, thrown, 'error value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-non-obj.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-non-obj.js
new file mode 100644
index 0000000000..65fa89f754
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-call-non-obj.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: TypeError thrown when @@iterator method returns a non-object value
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+
+ 7.4.1 GetIterator
+
+ 1. If method was not passed, then
+ a. Let method be ? GetMethod(obj, @@iterator).
+ 2. Let iterator be ? Call(method, obj).
+ 3. If Type(iterator) is not Object, throw a TypeError exception.
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return 7;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(typeof caught, 'object');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-get-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-get-err.js
new file mode 100644
index 0000000000..b9ededfdd7
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-get-get-err.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when accessing the @@iterator property
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+
+ 7.4.1 GetIterator
+
+ 1. If method was not passed, then
+ a. Let method be ? GetMethod(obj, @@iterator).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var poisonedIter = Object.defineProperty({}, Symbol.iterator, {
+ get: function() {
+ throw thrown;
+ }
+});
+function* g() {
+ try {
+ yield * poisonedIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+assert.sameValue(caught, undefined, 'property is not accessed eagerly');
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined, 'iteration value');
+assert.sameValue(result.done, true, 'iteration status');
+assert.sameValue(caught, thrown, 'error value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-err.js
new file mode 100644
index 0000000000..bfacb141ef
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-err.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when invoking iterator `next` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+
+ 7.4.2 IteratorNext
+
+ 1. If value was not passed, then
+ [...]
+ 2. Else,
+ a. Let result be ? Invoke(iterator, "next", « value »).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw thrown;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-non-obj.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-non-obj.js
new file mode 100644
index 0000000000..8d0e27e212
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-call-non-obj.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ TypeError thrown when iterator `next` method returns a non-object value
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+
+ 7.4.2 IteratorNext
+
+ 1. If value was not passed, then
+ [...]
+ 2. Else,
+ a. Let result be ? Invoke(iterator, "next", « value »).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return 8;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(typeof caught, 'object');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-get-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-get-err.js
new file mode 100644
index 0000000000..3da74f2671
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-get-err.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when accessing iterator `next` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+
+ 7.4.2 IteratorNext
+
+ 1. If value was not passed, then
+ [...]
+ 2. Else,
+ a. Let result be ? Invoke(iterator, "next", « value »).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedNext = Object.defineProperty({}, 'next', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return poisonedNext;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-invoke.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-invoke.js
new file mode 100644
index 0000000000..50fc345659
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-next-invoke.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Invocation of iterator `next` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+
+ 7.4.2 IteratorNext
+
+ 1. If value was not passed, then
+ [...]
+ 2. Else,
+ a. Let result be ? Invoke(iterator, "next", « value »).
+ [...]
+features: [generators, Symbol.iterator]
+---*/
+
+var args, thisValue;
+var callCount = 0;
+var spyIterator = {
+ next: function() {
+ callCount += 1;
+ args = arguments;
+ thisValue = this;
+ return { done: true };
+ }
+};
+var spyIterable = {};
+spyIterable[Symbol.iterator] = function() {
+ return spyIterator;
+};
+function* g() {
+ yield * spyIterable;
+}
+var iter = g();
+
+iter.next(9876);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], undefined);
+assert.sameValue(thisValue, spyIterator);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-err.js
new file mode 100644
index 0000000000..8888b974f3
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-err.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing `done` property of iteration result
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+ ii. Let done be ? IteratorComplete(innerResult).
+
+ 7.4.3 IteratorComplete
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ToBoolean(? Get(iterResult, "done")).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedDone = Object.defineProperty({}, 'done', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedDone;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+result = iter.next();
+
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-no-value.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-no-value.js
new file mode 100644
index 0000000000..2450ad2884
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-done-no-value.js
@@ -0,0 +1,62 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ `value` property is not accessed when iteration is incomplete
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+ ii. Let done be ? IteratorComplete(innerResult).
+ iii. If done is true, then
+ 1. Return ? IteratorValue(innerResult).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+var callCount = 0;
+var spyValue = Object.defineProperty({ done: false }, 'value', {
+ get: function() {
+ callCount += 1;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return spyValue;
+ }
+ };
+};
+var delegationComplete = false;
+function* g() {
+ yield * badIter;
+ delegationComplete = true;
+}
+var iter = g();
+
+iter.next();
+assert.sameValue(callCount, 0, 'access count (first iteration)');
+assert.sameValue(
+ delegationComplete, false, 'delegation ongoing (first iteration)'
+);
+
+iter.next();
+assert.sameValue(callCount, 0, 'access count (second iteration)');
+assert.sameValue(
+ delegationComplete, false, 'delegation ongoing (second iteration)'
+);
+
+spyValue.done = true;
+iter.next();
+assert.sameValue(callCount, 1, 'access count (final iteration)');
+assert.sameValue(delegationComplete, true, 'delegation complete');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-err.js
new file mode 100644
index 0000000000..efe0206098
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-err.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing `value` property of iteration
+ result
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+ ii. Let done be ? IteratorComplete(innerResult).
+ iii. If done is true, then
+ 1. Return ? IteratorValue(innerResult).
+
+ 7.4.4 IteratorValue
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ? Get(iterResult, "value").
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedValue = Object.defineProperty({ done: true }, 'value', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedValue;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+result = iter.next();
+
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-final.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-final.js
new file mode 100644
index 0000000000..3068878530
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-nrml-res-value-final.js
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Value received from invocation of generator's `next` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ i. Let innerResult be ? IteratorNext(iterator, received.[[Value]]).
+ ii. Let done be ? IteratorComplete(innerResult).
+ iii. If done is true, then
+ 1. Return ? IteratorValue(innerResult).
+
+ 7.4.4 IteratorValue
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ? Get(iterResult, "value").
+features: [generators, Symbol.iterator]
+---*/
+
+var quickIter = {};
+var exprValue, nextReceived, done, iter;
+quickIter[Symbol.iterator] = function() {
+ return {
+ next: function(x) {
+ nextReceived = x;
+ return {
+ done: done,
+ value: 3333
+ };
+ }
+ };
+};
+function* g() {
+ exprValue = yield * quickIter;
+}
+
+done = true;
+iter = g();
+iter.next(4444);
+
+assert.sameValue(
+ nextReceived, undefined, 'received value (previously-exhausted iterator)'
+);
+assert.sameValue(exprValue, 3333, 'expression value (previously-exhausted iterator)');
+
+done = false;
+exprValue = null;
+iter = g();
+iter.next(2222);
+done = true;
+iter.next(5555);
+
+assert.sameValue(nextReceived, 5555, 'received value');
+assert.sameValue(exprValue, 3333, 'expression value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-no-rtrn.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-no-rtrn.js
new file mode 100644
index 0000000000..8c2dd1bba9
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-no-rtrn.js
@@ -0,0 +1,78 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ "Return" completion returned when `return` method is not defined
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+var throwCount = 0;
+var returnCount = 0;
+var hitNextStatement = false;
+var hitCatch = false;
+var hitFinally = false;
+var spyResult = {
+ next: function() {
+ return { done: false };
+ }
+};
+Object.defineProperty(spyResult, 'throw', {
+ get: function() {
+ throwCount += 1;
+ }
+});
+Object.defineProperty(spyResult, 'return', {
+ get: function() {
+ returnCount += 1;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return spyResult;
+};
+function* g() {
+ try {
+ yield * badIter;
+ hitNextStatement = true;
+ } catch (_) {
+ hitCatch = true;
+ } finally {
+ hitFinally = true;
+ }
+}
+var iter = g();
+
+iter.next();
+iter.return();
+
+assert.sameValue(throwCount, 0, '`throw` property access');
+assert.sameValue(returnCount, 1, '`return` property access');
+assert.sameValue(
+ hitFinally, true, 'Generator execution was resumed'
+);
+assert.sameValue(
+ hitNextStatement, false, 'Abrupt completion interrupted control flow'
+);
+assert.sameValue(
+ hitCatch, false, 'Abrupt completion not interpreted as "throw"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-err.js
new file mode 100644
index 0000000000..52d4b145e1
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-err.js
@@ -0,0 +1,69 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing `done` property of iteration result
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+ v. If Type(innerReturnResult) is not Object, throw a TypeError
+ exception.
+ vi. Let done be ? IteratorComplete(innerReturnResult).
+
+ 7.4.3 IteratorComplete
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ToBoolean(? Get(iterResult, "done")).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedDone = Object.defineProperty({}, 'done', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ return poisonedDone;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.return();
+
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-no-value.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-no-value.js
new file mode 100644
index 0000000000..b34b87dfd8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-done-no-value.js
@@ -0,0 +1,93 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ `value` property is not accessed when iteration is incomplete
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+ v. If Type(innerReturnResult) is not Object, throw a TypeError
+ exception.
+ vi. Let done be ? IteratorComplete(innerReturnResult).
+ vii. If done is true, then
+ 1. Let value be ? IteratorValue(innerReturnResult).
+ 2. Return Completion{[[Type]]: return, [[Value]]: value,
+ [[Target]]: empty}.
+ viii. Let received be GeneratorYield(innerReturnResult).
+
+ 7.4.3 IteratorComplete
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ToBoolean(? Get(iterResult, "done")).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+var callCount = 0;
+var spyValue = Object.defineProperty({ done: false }, 'value', {
+ get: function() {
+ callCount += 1;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ return spyValue;
+ }
+ };
+};
+var normalCompletion = false;
+var errorCompletion = false;
+var delegationComplete = false;
+function* g() {
+ try {
+ yield * badIter;
+ normalCompletion = true;
+ } catch (_) {
+ errorCompletion = true;
+ } finally {
+ delegationComplete = true;
+ }
+}
+var iter = g();
+
+iter.next();
+assert.sameValue(callCount, 0, 'access count (first iteration)');
+assert.sameValue(
+ delegationComplete, false, 'delegation ongoing (first iteration)'
+);
+
+iter.return();
+assert.sameValue(callCount, 0, 'access count (second iteration)');
+assert.sameValue(
+ delegationComplete, false, 'delegation ongoing (second iteration)'
+);
+
+spyValue.done = true;
+iter.return();
+assert.sameValue(callCount, 1, 'access count (final iteration)');
+assert.sameValue(delegationComplete, true, 'delegation complete');
+assert.sameValue(normalCompletion, false, 'completion was abrupt');
+assert.sameValue(errorCompletion, false, 'completion was not of type "throw"');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-err.js
new file mode 100644
index 0000000000..269dfe7cad
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-err.js
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing `value` property of iteration
+ result
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+ v. If Type(innerReturnResult) is not Object, throw a TypeError
+ exception.
+ vi. Let done be ? IteratorComplete(innerReturnResult).
+ vii. If done is true, then
+ 1. Let value be ? IteratorValue(innerReturnResult).
+
+ 7.4.4 IteratorValue
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ? Get(iterResult, "value").
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedValue = Object.defineProperty({ done: true }, 'value', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ return poisonedValue;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.return();
+
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-final.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-final.js
new file mode 100644
index 0000000000..878450d948
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-res-value-final.js
@@ -0,0 +1,73 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Value received from invocation of generator's `return` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+ v. If Type(innerReturnResult) is not Object, throw a TypeError
+ exception.
+ vi. Let done be ? IteratorComplete(innerReturnResult).
+ vii. If done is true, then
+ 1. Let value be ? IteratorValue(innerReturnResult).
+ 2. Return Completion{[[Type]]: return, [[Value]]: value,
+ [[Target]]: empty}.
+ viii. Let received be GeneratorYield(innerReturnResult).
+
+features: [generators, Symbol.iterator]
+---*/
+
+var quickIter = {};
+var normalCompletion = false;
+var errorCompletion = false;
+var delegationComplete = false;
+var iter, returnReceived;
+quickIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function(x) {
+ returnReceived = x;
+ return { done: true, value: 3333 };
+ }
+ };
+};
+function* g() {
+ try {
+ yield * quickIter;
+ normalCompletion = true;
+ } catch (e) {
+ errorCompletion = true;
+ } finally {
+ delegationComplete = true;
+ }
+}
+
+iter = g();
+
+iter.next();
+iter.return(2222);
+assert.sameValue(returnReceived, 2222);
+assert.sameValue(delegationComplete, true, 'delegation complete');
+assert.sameValue(normalCompletion, false, 'completion was abrupt');
+assert.sameValue(errorCompletion, false, 'completion was not of type "throw"');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-err.js
new file mode 100644
index 0000000000..9f16505ebf
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-err.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when invoking iterator `return` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ throw thrown;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+iter.next();
+result = iter.return();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-non-obj.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-non-obj.js
new file mode 100644
index 0000000000..53f2a56680
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-call-non-obj.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ TypeError thrown when iterator `return` method returns a non-object value
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+ v. If Type(innerReturnResult) is not Object, throw a TypeError
+ exception.
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ return 23;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+iter.next();
+result = iter.return();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(typeof caught, 'object');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-get-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-get-err.js
new file mode 100644
index 0000000000..0f5450df23
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-get-err.js
@@ -0,0 +1,67 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when accessing iterator `return` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var callCount = 0;
+var poisonedReturn = {
+ next: function() {
+ return { done: false };
+ }
+};
+Object.defineProperty(poisonedReturn, 'throw', {
+ get: function() {
+ callCount += 1;
+ }
+});
+Object.defineProperty(poisonedReturn, 'return', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return poisonedReturn;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+iter.next();
+
+assert.sameValue(caught, undefined, '`return` property not accessed eagerly');
+
+result = iter.return();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(caught, thrown);
+assert.sameValue(callCount, 0, 'iterator `throw` property is not accessed');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-invoke.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-invoke.js
new file mode 100644
index 0000000000..88d9a4786c
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-rtrn-rtrn-invoke.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Invocation of iterator `return` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ [...]
+ c. Else,
+ i. Assert: received.[[Type]] is return.
+ ii. Let return be ? GetMethod(iterator, "return").
+ iii. If return is undefined, return Completion(received).
+ iv. Let innerReturnResult be ? Call(return, iterator, «
+ received.[[Value]] »).
+ [...]
+features: [generators, Symbol.iterator]
+---*/
+
+var args, thisValue;
+var callCount = 0;
+var spyIterator = {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ callCount += 1;
+ args = arguments;
+ thisValue = this;
+ return { done: true };
+ }
+};
+var spyIterable = {};
+spyIterable[Symbol.iterator] = function() {
+ return spyIterator;
+};
+function* g() {
+ yield * spyIterable;
+}
+var iter = g();
+
+iter.next(8888);
+iter.return(7777);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], 7777);
+assert.sameValue(thisValue, spyIterator);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-err.js
new file mode 100644
index 0000000000..f1352e5789
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-err.js
@@ -0,0 +1,68 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing `done` property of iteration result
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+ 2. NOTE: Exceptions from the inner iterator throw method are
+ propagated. Normal completions from an inner throw method are
+ processed similarly to an inner next.
+ 3. If Type(innerResult) is not Object, throw a TypeError exception.
+ 4. Let done be ? IteratorComplete(innerResult).
+
+ 7.4.3 IteratorComplete
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ToBoolean(? Get(iterResult, "done")).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedDone = Object.defineProperty({}, 'done', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ throw: function() {
+ return poisonedDone;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-no-value.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-no-value.js
new file mode 100644
index 0000000000..ef844d38a8
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-done-no-value.js
@@ -0,0 +1,78 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: >
+ `value` property is not accessed when iteration is complete
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+ 2. NOTE: Exceptions from the inner iterator throw method are
+ propagated. Normal completions from an inner throw method are
+ processed similarly to an inner next.
+ 3. If Type(innerResult) is not Object, throw a TypeError exception.
+ 4. Let done be ? IteratorComplete(innerResult).
+ 5. If done is true, then
+ a. Return ? IteratorValue(innerResult).
+
+ 7.4.3 IteratorComplete
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ToBoolean(? Get(iterResult, "done")).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+var callCount = 0;
+var spyValue = Object.defineProperty({ done: false }, 'value', {
+ get: function() {
+ callCount += 1;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ throw: function() {
+ return spyValue;
+ }
+ };
+};
+var delegationComplete = false;
+function* g() {
+ yield * badIter;
+ delegationComplete = true;
+}
+var iter = g();
+
+iter.next();
+assert.sameValue(callCount, 0, 'access count (first iteration)');
+assert.sameValue(
+ delegationComplete, false, 'delegation ongoing (first iteration)'
+);
+
+iter.throw();
+assert.sameValue(callCount, 0, 'access count (second iteration)');
+assert.sameValue(
+ delegationComplete, false, 'delegation ongoing (second iteration)'
+);
+
+spyValue.done = true;
+iter.throw();
+assert.sameValue(callCount, 1, 'access count (final iteration)');
+assert.sameValue(delegationComplete, true, 'delegation complete');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-err.js
new file mode 100644
index 0000000000..5ee80aed9a
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-err.js
@@ -0,0 +1,71 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing `value` property of iteration
+ result
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+ 2. NOTE: Exceptions from the inner iterator throw method are
+ propagated. Normal completions from an inner throw method are
+ processed similarly to an inner next.
+ 3. If Type(innerResult) is not Object, throw a TypeError exception.
+ 4. Let done be ? IteratorComplete(innerResult).
+ 5. If done is true, then
+ a. Return ? IteratorValue(innerResult).
+
+ 7.4.4 IteratorValue
+
+ 1. Assert: Type(iterResult) is Object.
+ 2. Return ? Get(iterResult, "value").
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedValue = Object.defineProperty({ done: true }, 'value', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ throw: function() {
+ return poisonedValue;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-final.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-final.js
new file mode 100644
index 0000000000..7101f1bcfa
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-res-value-final.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: Value received from invocation of generator's `throw` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+ 2. NOTE: Exceptions from the inner iterator throw method are
+ propagated. Normal completions from an inner throw method are
+ processed similarly to an inner next.
+ 3. If Type(innerResult) is not Object, throw a TypeError exception.
+ 4. Let done be ? IteratorComplete(innerResult).
+ 5. If done is true, then
+ [...]
+ 6. Let received be GeneratorYield(innerResult).
+features: [generators, Symbol.iterator]
+---*/
+
+var quickIter = {};
+var iter, exprValue, throwReceived;
+quickIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ throw: function(x) {
+ throwReceived = x;
+ return { done: true, value: 3333 };
+ }
+ };
+};
+function* g() {
+ exprValue = yield * quickIter;
+}
+
+iter = g();
+
+iter.next();
+iter.throw(2222);
+assert.sameValue(throwReceived, 2222);
+assert.sameValue(exprValue, 3333);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-err.js
new file mode 100644
index 0000000000..5f588eefa6
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-err.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when invoking iterator `throw` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ throw: function() {
+ throw thrown;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+iter.next();
+result = iter.throw();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-non-obj.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-non-obj.js
new file mode 100644
index 0000000000..bbb7245e78
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-call-non-obj.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ TypeError thrown when iterator `throw` method returns a non-object value
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+ 2. NOTE: Exceptions from the inner iterator throw method are
+ propagated. Normal completions from an inner throw method are
+ processed similarly to an inner next.
+ 3. If Type(innerResult) is not Object, throw a TypeError exception.
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ throw: function() {
+ return 23;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+iter.next();
+result = iter.throw();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(typeof caught, 'object');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-get-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-get-err.js
new file mode 100644
index 0000000000..23d11ba8dc
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-get-err.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Abrupt completion returned when accessing iterator `throw` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var poisonedThrow = {
+ next: function() {
+ return { done: false };
+ }
+};
+Object.defineProperty(poisonedThrow, 'throw', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return poisonedThrow;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var result, caught;
+
+iter.next();
+
+assert.sameValue(caught, undefined, '`throw` property not accesed eagerly');
+
+result = iter.throw();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-invoke.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-invoke.js
new file mode 100644
index 0000000000..5db1533f5f
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-thrw-invoke.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: Invocation of iterator `throw` method
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ 1. Let innerResult be ? Call(throw, iterator, « received.[[Value]]
+ »).
+ [...]
+features: [generators, Symbol.iterator]
+---*/
+
+var args, thisValue;
+var callCount = 0;
+var spyIterator = {
+ next: function() {
+ return { done: false };
+ },
+ throw: function() {
+ callCount += 1;
+ args = arguments;
+ thisValue = this;
+ return { done: true };
+ }
+};
+var spyIterable = {};
+spyIterable[Symbol.iterator] = function() {
+ return spyIterator;
+};
+function* g() {
+ yield * spyIterable;
+}
+var iter = g();
+
+iter.next(8888);
+iter.throw(7777);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], 7777);
+assert.sameValue(thisValue, spyIterator);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-no-rtrn.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-no-rtrn.js
new file mode 100644
index 0000000000..a32cee1265
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-no-rtrn.js
@@ -0,0 +1,82 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned after protocol violation (and a `return` method
+ is not defined)
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ [...]
+ iii. Else,
+ 1. NOTE: If iterator does not have a throw method, this throw is
+ going to terminate the yield* loop. But first we need to give
+ iterator a chance to clean up.
+ 2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
+ [[Value]]: empty, [[Target]]: empty}).
+ 3. NOTE: The next step throws a TypeError to indicate that there
+ was a yield* protocol violation: iterator does not have a throw
+ method.
+ 4. Throw a TypeError exception.
+
+ 7.4.6 IteratorClose
+
+ 1. Assert: Type(iterator) is Object.
+ 2. Assert: completion is a Completion Record.
+ 3. Let return be ? GetMethod(iterator, "return").
+ 4. If return is undefined, return Completion(completion).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+var throwCount = 0;
+var returnCount = 0;
+var spyResult = {
+ next: function() {
+ return { done: false };
+ }
+};
+Object.defineProperty(spyResult, 'throw', {
+ get: function() {
+ throwCount += 1;
+ }
+});
+Object.defineProperty(spyResult, 'return', {
+ get: function() {
+ returnCount += 1;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return spyResult;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(throwCount, 1, '`throw` property access');
+assert.sameValue(returnCount, 1, '`return` property access');
+assert.sameValue(typeof caught, 'object');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-err.js
new file mode 100644
index 0000000000..8f6062bd4d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-err.js
@@ -0,0 +1,73 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when invoking iterator `return` method following
+ protocol violation
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ [...]
+ iii. Else,
+ 1. NOTE: If iterator does not have a throw method, this throw is
+ going to terminate the yield* loop. But first we need to give
+ iterator a chance to clean up.
+ 2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
+ [[Value]]: empty, [[Target]]: empty}).
+
+ 7.4.6 IteratorClose
+
+ 1. Assert: Type(iterator) is Object.
+ 2. Assert: completion is a Completion Record.
+ 3. Let return be ? GetMethod(iterator, "return").
+ 4. If return is undefined, return Completion(completion).
+ 5. Let innerResult be Call(return, iterator, « »).
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+ 8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ // Using a primitive completion value ensures that the check for the type
+ // of the completion value (and resulting TypeError) occurs *after* the
+ // check for the type of the completion itself (which is the behavior
+ // under test).
+ throw 87;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(caught, 87);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-non-obj.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-non-obj.js
new file mode 100644
index 0000000000..8a8ac0314e
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-call-non-obj.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Non-object value returned by iterator `return` method following protocol
+ violation
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ [...]
+ iii. Else,
+ 1. NOTE: If iterator does not have a throw method, this throw is
+ going to terminate the yield* loop. But first we need to give
+ iterator a chance to clean up.
+ 2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
+ [[Value]]: empty, [[Target]]: empty}).
+
+ 7.4.6 IteratorClose
+
+ 1. Assert: Type(iterator) is Object.
+ 2. Assert: completion is a Completion Record.
+ 3. Let return be ? GetMethod(iterator, "return").
+ 4. If return is undefined, return Completion(completion).
+ 5. Let innerResult be Call(return, iterator, « »).
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+ 8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+badIter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ return 87;
+ }
+ };
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(typeof caught, 'object');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-get-err.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-get-err.js
new file mode 100644
index 0000000000..be98f16ef9
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-get-err.js
@@ -0,0 +1,75 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned when accessing iterator `return` property after
+ protocol violation
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ [...]
+ iii. Else,
+ 1. NOTE: If iterator does not have a throw method, this throw is
+ going to terminate the yield* loop. But first we need to give
+ iterator a chance to clean up.
+ 2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
+ [[Value]]: empty, [[Target]]: empty}).
+
+ 7.4.6 IteratorClose
+
+ 1. Assert: Type(iterator) is Object.
+ 2. Assert: completion is a Completion Record.
+ 3. Let return be ? GetMethod(iterator, "return").
+features: [generators, Symbol.iterator]
+---*/
+
+var thrown = new Test262Error();
+var badIter = {};
+var callCount = 0;
+var poisonedReturn = {
+ next: function() {
+ return { done: false };
+ }
+};
+Object.defineProperty(poisonedReturn, 'throw', {
+ get: function() {
+ callCount += 1;
+ }
+});
+Object.defineProperty(poisonedReturn, 'return', {
+ get: function() {
+ throw thrown;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return poisonedReturn;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(callCount, 1);
+assert.sameValue(caught, thrown);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-invoke.js b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-invoke.js
new file mode 100644
index 0000000000..f6bcff0a05
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-iter-thrw-violation-rtrn-invoke.js
@@ -0,0 +1,91 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: >
+ Abrupt completion returned after protocol violation (and a `return` method
+ is defined)
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+ 3. Let iterator be ? GetIterator(value).
+ 4. Let received be NormalCompletion(undefined).
+ 5. Repeat
+ a. If received.[[Type]] is normal, then
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ [...]
+ iii. Else,
+ 1. NOTE: If iterator does not have a throw method, this throw is
+ going to terminate the yield* loop. But first we need to give
+ iterator a chance to clean up.
+ 2. Perform ? IteratorClose(iterator, Completion{[[Type]]: normal,
+ [[Value]]: empty, [[Target]]: empty}).
+ 3. NOTE: The next step throws a TypeError to indicate that there
+ was a yield* protocol violation: iterator does not have a throw
+ method.
+ 4. Throw a TypeError exception.
+
+ 7.4.6 IteratorClose
+
+ 1. Assert: Type(iterator) is Object.
+ 2. Assert: completion is a Completion Record.
+ 3. Let return be ? GetMethod(iterator, "return").
+ 4. If return is undefined, return Completion(completion).
+ 5. Let innerResult be Call(return, iterator, « »).
+ 6. If completion.[[Type]] is throw, return Completion(completion).
+ 7. If innerResult.[[Type]] is throw, return Completion(innerResult).
+ 8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
+ 9. Return Completion(completion).
+features: [generators, Symbol.iterator]
+---*/
+
+var badIter = {};
+var throwCount = 0;
+var thisValue, args;
+var poisonedReturn = {
+ next: function() {
+ return { done: false };
+ },
+ return: function() {
+ thisValue = this;
+ args = arguments;
+ return 'this value has no effect on the protocol';
+ }
+};
+Object.defineProperty(poisonedReturn, 'throw', {
+ get: function() {
+ throwCount += 1;
+ }
+});
+badIter[Symbol.iterator] = function() {
+ return poisonedReturn;
+};
+function* g() {
+ try {
+ yield * badIter;
+ } catch (err) {
+ caught = err;
+ }
+}
+var iter = g();
+var caught;
+
+iter.next();
+iter.throw();
+
+assert.sameValue(throwCount, 1);
+assert.sameValue(thisValue, poisonedReturn, '"this" value');
+assert.sameValue(
+ typeof args, 'object', 'method invoked, arguments object provided'
+);
+assert.sameValue(args.length, 0);
+assert.sameValue(typeof caught, 'object', 'object value thrown');
+assert.sameValue(caught.constructor, TypeError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-rhs-unresolvable.js b/js/src/tests/test262/language/expressions/yield/star-rhs-unresolvable.js
new file mode 100644
index 0000000000..a5687a94c4
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-rhs-unresolvable.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+es6id: 14.4.14
+description: GetValue invoked on Reference value
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ 1. Let exprRef be the result of evaluating AssignmentExpression.
+ 2. Let value be ? GetValue(exprRef).
+features: [generators]
+---*/
+
+var err;
+function* g() {
+ try {
+ yield * test262unresolvable;
+ } catch (_err) {
+ err = _err;
+ }
+}
+var iter = g();
+var result;
+
+result = iter.next();
+
+assert.sameValue(result.value, undefined);
+assert.sameValue(result.done, true);
+assert.sameValue(typeof err, 'object');
+assert.sameValue(err.constructor, ReferenceError);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-string.js b/js/src/tests/test262/language/expressions/yield/star-string.js
new file mode 100644
index 0000000000..b2fc8c536d
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-string.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ When a string is the operand of a `yield *` expression, the generator
+ should produce an iterator that visits each character in order.
+features: [generators]
+---*/
+
+function* g() {
+ yield* 'abc';
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 'a', 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 'b', 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 'c', 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/star-throw-is-null.js b/js/src/tests/test262/language/expressions/yield/star-throw-is-null.js
new file mode 100644
index 0000000000..90c5c5de41
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/star-throw-is-null.js
@@ -0,0 +1,73 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: >
+ If iterator's "throw" method is `null`,
+ IteratorClose is called before rising TypeError.
+info: |
+ YieldExpression : yield * AssignmentExpression
+
+ [...]
+ 7. Repeat,
+ [...]
+ b. Else if received.[[Type]] is throw, then
+ i. Let throw be ? GetMethod(iterator, "throw").
+ ii. If throw is not undefined, then
+ [...]
+ iii. Else,
+ [...]
+ 4. Else, perform ? IteratorClose(iteratorRecord, closeCompletion).
+ [...]
+ 6. Throw a TypeError exception.
+
+ GetMethod ( V, P )
+
+ [...]
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+
+ IteratorClose ( iteratorRecord, completion )
+
+ [...]
+ 4. Let innerResult be GetMethod(iterator, "return").
+ 5. If innerResult.[[Type]] is normal, then
+ a. Let return be innerResult.[[Value]].
+ b. If return is undefined, return Completion(completion).
+features: [generators, Symbol.iterator]
+---*/
+
+var throwGets = 0;
+var returnGets = 0;
+var iterable = {
+ next: function() {
+ return {value: 1, done: false};
+ },
+ get throw() {
+ throwGets += 1;
+ return null;
+ },
+ get return() {
+ returnGets += 1;
+ },
+};
+
+iterable[Symbol.iterator] = function() {
+ return iterable;
+};
+
+function* generator() {
+ yield* iterable;
+}
+
+var iterator = generator();
+iterator.next();
+
+assert.throws(TypeError, function() {
+ iterator.throw();
+});
+
+assert.sameValue(throwGets, 1);
+assert.sameValue(returnGets, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/then-return.js b/js/src/tests/test262/language/expressions/yield/then-return.js
new file mode 100644
index 0000000000..5ec10fac84
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/then-return.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ When a generator body contains a yield statement followed by a return
+ statement, it should produce an iterator that visits the yieled value and
+ completes on the returned value.
+features: [generators]
+---*/
+
+function* g() { yield 1; return 2; }
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 2, 'Second result `value`');
+assert.sameValue(result.done, true, 'Second result `done` flag');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/expressions/yield/within-for.js b/js/src/tests/test262/language/expressions/yield/within-for.js
new file mode 100644
index 0000000000..ddc98c63cd
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/yield/within-for.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2013 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 25.2
+description: >
+ `yield` expressions should suspend `for` loop iteration.
+features: [generators]
+---*/
+
+function* g() {
+ for (var idx = 0; idx < 3; idx++) {
+ yield idx;
+ }
+}
+var iter = g();
+var result;
+
+result = iter.next();
+assert.sameValue(result.value, 0, 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 1, 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, 2, 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iter.next();
+assert.sameValue(result.value, undefined, 'Final result `value`');
+assert.sameValue(result.done, true, 'Final result `done` flag');
+
+reportCompare(0, 0);