summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/language/statements/for-in
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test262/language/statements/for-in')
-rw-r--r--js/src/tests/test262/language/statements/for-in/12.6.4-1.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/12.6.4-2.js36
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A1.js31
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A14_T2.js28
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A15.js24
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A2.js30
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A3.1.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A3.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A4.1.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A4.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A5.1.js45
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A5.js45
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A6.1.js44
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A6.js44
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T1.js55
-rw-r--r--js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js45
-rw-r--r--js/src/tests/test262/language/statements/for-in/browser.js0
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-decl-abrupt-empty.js43
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-decl-itr.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-decl-skip-itr.js27
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-decl-zero-itr.js29
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-expr-abrupt-empty.js43
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-expr-itr.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-expr-skip-itr.js27
-rw-r--r--js/src/tests/test262/language/statements/for-in/cptn-expr-zero-itr.js29
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-async-fun.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-async-gen.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-cls.js15
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-const.js15
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-fun.js15
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-gen.js16
-rw-r--r--js/src/tests/test262/language/statements/for-in/decl-let.js15
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-init-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js66
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js69
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-simple-strict-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-yield-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-element.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-elision.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-rest.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-elision-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-init.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/array-rest-yield-ident-invalid-strict.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/browser.js0
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-expr.js36
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-simple-strict-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-id-simple-strict-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js66
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js69
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-invalid.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js34
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/obj-rest-not-last-element-invalid.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/dstr/shell.js0
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-const-bound-names-dup.js18
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-const-bound-names-fordecl-tdz.js14
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-const-bound-names-in-stmt.js20
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-const-bound-names-let.js18
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-const-fresh-binding-per-iteration.js17
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-decl-expr.js27
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-expr-expr.js28
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-let-bound-names-dup.js18
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-let-bound-names-fordecl-tdz.js14
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-let-bound-names-in-stmt.js20
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-let-bound-names-let.js18
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-let-destructuring.js33
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-let-fresh-binding-per-iteration.js30
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-cover-non-asnmt-trgt.js25
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-cover.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-ary.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-obj.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-let.js40
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-member.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-lhs-non-asnmt-trgt.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-var-bound-names-dup.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-var-bound-names-in-stmt.js20
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-var-bound-names-let.js20
-rw-r--r--js/src/tests/test262/language/statements/for-in/head-var-expr.js27
-rw-r--r--js/src/tests/test262/language/statements/for-in/identifier-let-allowed-as-lefthandside-expression-not-strict.js14
-rw-r--r--js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-const.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-let.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-lhs.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-var.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/let-array-with-newline.js22
-rw-r--r--js/src/tests/test262/language/statements/for-in/let-block-with-newline.js18
-rw-r--r--js/src/tests/test262/language/statements/for-in/let-identifier-with-newline.js18
-rw-r--r--js/src/tests/test262/language/statements/for-in/order-after-define-property.js53
-rw-r--r--js/src/tests/test262/language/statements/for-in/order-enumerable-shadowed.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/order-property-added.js27
-rw-r--r--js/src/tests/test262/language/statements/for-in/order-property-on-prototype.js30
-rw-r--r--js/src/tests/test262/language/statements/for-in/order-simple-object.js35
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-body-lex-boundary.js52
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-body-lex-close.js42
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-body-lex-open.js50
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-body-var-none.js50
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-head-lex-close.js46
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-head-lex-open.js40
-rw-r--r--js/src/tests/test262/language/statements/for-in/scope-head-var-none.js47
-rw-r--r--js/src/tests/test262/language/statements/for-in/shell.js0
-rw-r--r--js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-init-strict.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-strict.js21
-rw-r--r--js/src/tests/test262/language/statements/for-in/var-arguments-strict-init-strict.js19
-rw-r--r--js/src/tests/test262/language/statements/for-in/var-arguments-strict-strict.js17
-rw-r--r--js/src/tests/test262/language/statements/for-in/var-eval-strict-init-strict.js17
-rw-r--r--js/src/tests/test262/language/statements/for-in/var-eval-strict-strict.js17
118 files changed, 3526 insertions, 0 deletions
diff --git a/js/src/tests/test262/language/statements/for-in/12.6.4-1.js b/js/src/tests/test262/language/statements/for-in/12.6.4-1.js
new file mode 100644
index 0000000000..ef470c7b36
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/12.6.4-1.js
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.6.4-1
+description: >
+ The for-in Statement - a property name must not be visited more
+ than once in any enumeration.
+---*/
+
+ var obj = { prop1: "abc", prop2: "bbc", prop3: "cnn" };
+
+ var countProp1 = 0;
+ var countProp2 = 0;
+ var countProp3 = 0;
+
+ for (var p in obj) {
+ if (obj.hasOwnProperty(p)) {
+ if (p === "prop1") {
+ countProp1++;
+ }
+ if (p === "prop2") {
+ countProp2++;
+ }
+ if (p === "prop3") {
+ countProp3++;
+ }
+ }
+ }
+
+assert.sameValue(countProp1, 1, 'countProp1');
+assert.sameValue(countProp2, 1, 'countProp2');
+assert.sameValue(countProp3, 1, 'countProp3');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/12.6.4-2.js b/js/src/tests/test262/language/statements/for-in/12.6.4-2.js
new file mode 100644
index 0000000000..1a021881f8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/12.6.4-2.js
@@ -0,0 +1,36 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.6.4-2
+description: >
+ The for-in Statement - the values of [[Enumerable]] attributes are
+ not considered when determining if a property of a prototype
+ object is shadowed by a previous object on the prototype chain
+---*/
+
+ var proto = {
+ prop: "enumerableValue"
+ };
+
+ var ConstructFun = function () { };
+ ConstructFun.prototype = proto;
+
+ var child = new ConstructFun();
+
+ Object.defineProperty(child, "prop", {
+ value: "nonEnumerableValue",
+ enumerable: false
+ });
+
+ var accessedProp = false;
+
+ for (var p in child) {
+ if (p === "prop") {
+ accessedProp = true;
+ }
+ }
+
+assert.sameValue(accessedProp, false, 'accessedProp');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A1.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A1.js
new file mode 100644
index 0000000000..4d80be149d
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A1.js
@@ -0,0 +1,31 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: "\"for(key in undefined)\" Statement is allowed"
+es5id: 12.6.4_A1
+description: Checking if execution of "for(key in undefined)" passes
+---*/
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+try {
+ for(__key in undefined){
+ var key=__key;
+ };
+} catch (e) {
+ throw new Test262Error('#1: "for(key in undefined){}" does not lead to throwing exception');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (key!==undefined) {
+ throw new Test262Error('#2: key === undefined. Actual: key === '+key);
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A14_T2.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A14_T2.js
new file mode 100644
index 0000000000..526ce6f3c8
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A14_T2.js
@@ -0,0 +1,28 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: FunctionExpession within a "for-in" Expression is allowed
+es5id: 12.6.4_A14_T2
+description: "Using \"function __func(){return {a:1};}()\" as Expession"
+---*/
+
+var x;
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#
+for(x in function __func(){return {a:1};}()){
+ var __reached = x;
+};
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (__reached !== "a") {
+ throw new Test262Error('#2: function expession inside of for-in expression allowed');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A15.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A15.js
new file mode 100644
index 0000000000..f82438c5e9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A15.js
@@ -0,0 +1,24 @@
+// |reftest| error:SyntaxError
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Block within a "for-in" Expression is not allowed
+es5id: 12.6.4_A15
+description: Using block within "for-in" Expression
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+var __arr=[1,2,3];
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#
+for(x in {__arr;}){
+ break ;
+};
+//
+//////////////////////////////////////////////////////////////////////////////
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A2.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A2.js
new file mode 100644
index 0000000000..4b51f20771
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A2.js
@@ -0,0 +1,30 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: "\"for(key in null)\" Expression is allowed"
+es5id: 12.6.4_A2
+description: Checking if execution of "for(key in null)" passes
+---*/
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#
+try {
+ for(__key in null){
+ var key=__key;
+ };
+} catch (e) {
+ throw new Test262Error('#1: "for(__key in null){}" does not lead to throwing exception');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (key!==undefined) {
+ throw new Test262Error('#2: key === undefined. Actual: key ==='+key);
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A3.1.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A3.1.js
new file mode 100644
index 0000000000..1311d1a2c2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A3.1.js
@@ -0,0 +1,35 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A3.1
+description: >
+ Using an array as an Expression is appropriate. Here Expression is
+ an array of numbers
+---*/
+
+var __str, __evaluated, arr;
+__str="";
+
+__evaluated = eval("for(var ind in (arr=[2,1,4,3]))__str+=arr[ind]");
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if (__evaluated !== __str) {
+ throw new Test262Error('#1: __evaluated === __str. Actual: __evaluated ==='+ __evaluated );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (!( (__str.indexOf("2")!==-1)&&(__str.indexOf("1")!==-1)&&(__str.indexOf("4")!==-1)&&(__str.indexOf("3")!==-1) )) {
+ throw new Test262Error('#2: (__str.indexOf("2")!==-1)&&(__str.indexOf("1")!==-1)&&(__str.indexOf("4")!==-1)&&(__str.indexOf("3")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A3.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A3.js
new file mode 100644
index 0000000000..b66aa73187
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A3.js
@@ -0,0 +1,35 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A3
+description: >
+ Using an array as an Expression is appropriate. Here Expression is
+ an array of numbers. Eval is used
+---*/
+
+var __str, __evaluated, arr, ind;
+__str="";
+
+__evaluated = eval("for(ind in (arr=[2,1,4,3]))__str+=arr[ind]");
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if (__evaluated !== __str) {
+ throw new Test262Error('#1: __evaluated === __str. Actual: __evaluated ==='+ __evaluated );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (!( (__str.indexOf("2")!==-1)&&(__str.indexOf("1")!==-1)&&(__str.indexOf("4")!==-1)&&(__str.indexOf("3")!==-1) )) {
+ throw new Test262Error('#2: (__str.indexOf("2")!==-1)&&(__str.indexOf("1")!==-1)&&(__str.indexOf("4")!==-1)&&(__str.indexOf("3")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A4.1.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A4.1.js
new file mode 100644
index 0000000000..bc5292630a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A4.1.js
@@ -0,0 +1,33 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A4.1
+description: Using Object as an Expression is appropriate. Eval is used
+---*/
+
+var __str, __evaluated, hash;
+__str="";
+
+__evaluated = eval("for(var ind in (hash={2:'b',1:'a',4:'d',3:'c'}))__str+=hash[ind]");
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if ( !( (__evaluated.indexOf("a")!==-1)& (__evaluated.indexOf("b")!==-1)& (__evaluated.indexOf("c")!==-1)&(__evaluated.indexOf("d")!==-1) ) ) {
+ throw new Test262Error('#1: (__evaluated.indexOf("a")!==-1)& (__evaluated.indexOf("b")!==-1)& (__evaluated.indexOf("c")!==-1)&(__evaluated.indexOf("d")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (__str !== __evaluated) {
+ throw new Test262Error('#2: __str === __evaluated. Actual: __str ==='+ __str );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A4.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A4.js
new file mode 100644
index 0000000000..b2e2c3e1c5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A4.js
@@ -0,0 +1,33 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A4
+description: Using Object as an Expression is appropriate. Eval is used
+---*/
+
+var __str, __evaluated, hash, ind;
+__str="";
+
+__evaluated = eval("for(ind in (hash={2:'b',1:'a',4:'d',3:'c'}))__str+=hash[ind]");
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if ( !( (__evaluated.indexOf("a")!==-1)& (__evaluated.indexOf("b")!==-1)& (__evaluated.indexOf("c")!==-1)&(__evaluated.indexOf("d")!==-1) ) ) {
+ throw new Test262Error('#1: (__evaluated.indexOf("a")!==-1)& (__evaluated.indexOf("b")!==-1)& (__evaluated.indexOf("c")!==-1)&(__evaluated.indexOf("d")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (__str !== __evaluated) {
+ throw new Test262Error('#2: __str === __evaluated. Actual: __str ==='+ __str );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A5.1.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A5.1.js
new file mode 100644
index 0000000000..51877da9a0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A5.1.js
@@ -0,0 +1,45 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A5.1
+description: >
+ Using hierarchical Object as an Expression is appropriate. The
+ depth is two
+---*/
+
+var __hash__map, __arr;
+
+__hash__map={a:{aa:1,ab:2,ac:3,ad:4},b:{ba:1,bb:2,bc:3,bd:4},c:{ca:1,cb:2,cc:3,cd:4},d:{da:1,db:2,dc:3,dd:4}};
+
+__arr = "";
+
+for(var __key in __hash__map){
+ for (var __ind in __hash__map[__key]){
+ __arr+=("" + __ind + __hash__map[__key][__ind]);
+ }
+}
+
+if(!(
+(__arr.indexOf("aa1")!==-1)&
+(__arr.indexOf("ab2")!==-1)&
+(__arr.indexOf("ac3")!==-1)&
+(__arr.indexOf("ad4")!==-1)&
+(__arr.indexOf("ba1")!==-1)&
+(__arr.indexOf("bb2")!==-1)&
+(__arr.indexOf("bc3")!==-1)&
+(__arr.indexOf("bd4")!==-1)&
+(__arr.indexOf("ca1")!==-1)&
+(__arr.indexOf("cb2")!==-1)&
+(__arr.indexOf("cc3")!==-1)&
+(__arr.indexOf("cd4")!==-1)&
+(__arr.indexOf("da1")!==-1)&
+(__arr.indexOf("db2")!==-1)&
+(__arr.indexOf("dc3")!==-1)&
+(__arr.indexOf("dd4")!==-1)
+)) throw new Test262Error('#1: The nested for-in Statement applied to hierarchial object works properly as described in the Standard');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A5.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A5.js
new file mode 100644
index 0000000000..d018b9185b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A5.js
@@ -0,0 +1,45 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A5
+description: >
+ Using hierarchical Object as an Expression is appropriate. The
+ depth is two
+---*/
+
+var __hash__map, __arr, __key, __ind;
+
+__hash__map={a:{aa:1,ab:2,ac:3,ad:4},b:{ba:1,bb:2,bc:3,bd:4},c:{ca:1,cb:2,cc:3,cd:4},d:{da:1,db:2,dc:3,dd:4}};
+
+__arr = "";
+
+for(__key in __hash__map){
+ for (__ind in __hash__map[__key]){
+ __arr+=("" + __ind + __hash__map[__key][__ind]);
+ }
+}
+
+if(!(
+(__arr.indexOf("aa1")!==-1)&
+(__arr.indexOf("ab2")!==-1)&
+(__arr.indexOf("ac3")!==-1)&
+(__arr.indexOf("ad4")!==-1)&
+(__arr.indexOf("ba1")!==-1)&
+(__arr.indexOf("bb2")!==-1)&
+(__arr.indexOf("bc3")!==-1)&
+(__arr.indexOf("bd4")!==-1)&
+(__arr.indexOf("ca1")!==-1)&
+(__arr.indexOf("cb2")!==-1)&
+(__arr.indexOf("cc3")!==-1)&
+(__arr.indexOf("cd4")!==-1)&
+(__arr.indexOf("da1")!==-1)&
+(__arr.indexOf("db2")!==-1)&
+(__arr.indexOf("dc3")!==-1)&
+(__arr.indexOf("dd4")!==-1)
+)) throw new Test262Error('#1: The nested for-in Statement applied to hierarchial object works properly as described in the Standard');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A6.1.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A6.1.js
new file mode 100644
index 0000000000..b32c085afa
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A6.1.js
@@ -0,0 +1,44 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A6.1
+description: >
+ Using Object with custom prototype as an Expression is
+ appropriate. The prototype is "{feat:2,hint:"protohint"}"
+---*/
+
+var __accum;
+
+function FACTORY(){this.prop=1;this.hint="hinted"};
+
+FACTORY.prototype = {feat:2,hint:"protohint"};
+
+var __instance = new FACTORY;
+
+__accum="";
+
+for (var key in __instance){
+ __accum+=(key + __instance[key]);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if (!((__accum.indexOf("prop1")!==-1)&&(__accum.indexOf("feat2")!==-1)&&(__accum.indexOf("hinthinted")!==-1))) {
+ throw new Test262Error('#1: (__accum.indexOf("prop1")!==-1)&&(__accum.indexOf("feat2")!==-1)&&(__accum.indexOf("hinthinted")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (__accum.indexOf("hintprotohint")!==-1) {
+ throw new Test262Error('#2: __accum.indexOf("hintprotohint") === -1. Actual: __accum.indexOf("hintprotohint") ==='+ __accum.indexOf("hintprotohint") );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A6.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A6.js
new file mode 100644
index 0000000000..3eacd7cc9a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A6.js
@@ -0,0 +1,44 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ The production IterationStatement: "for (var VariableDeclarationNoIn in
+ Expression) Statement"
+es5id: 12.6.4_A6
+description: >
+ Using Object with custom prototype as an Expression is
+ appropriate. The prototype is "{feat:2,hint:"protohint"}"
+---*/
+
+var __accum, key;
+
+function FACTORY(){this.prop=1;this.hint="hinted"};
+
+FACTORY.prototype = {feat:2,hint:"protohint"};
+
+var __instance = new FACTORY;
+
+__accum="";
+
+for (key in __instance){
+ __accum+=(key + __instance[key]);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if (!((__accum.indexOf("prop1")!==-1)&&(__accum.indexOf("feat2")!==-1)&&(__accum.indexOf("hinthinted")!==-1))) {
+ throw new Test262Error('#1: (__accum.indexOf("prop1")!==-1)&&(__accum.indexOf("feat2")!==-1)&&(__accum.indexOf("hinthinted")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (__accum.indexOf("hintprotohint")!==-1) {
+ throw new Test262Error('#2: __accum.indexOf("hintprotohint") === -1. Actual: __accum.indexOf("hintprotohint") ==='+ __accum.indexOf("hintprotohint") );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T1.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T1.js
new file mode 100644
index 0000000000..42ffcf4c32
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T1.js
@@ -0,0 +1,55 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ Properties of the object being enumerated may be deleted during
+ enumeration
+es5id: 12.6.4_A7_T1
+description: >
+ Checking "for (LeftHandSideExpression in Expression) Statement"
+ case
+---*/
+
+var __obj, __accum, __key;
+
+__obj={aa:1,ba:2,ca:3};
+
+__accum="";
+
+for (__key in __obj){
+
+ erasator_T_1000(__obj,"b");
+
+ __accum+=(__key+__obj[__key]);
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#1
+if (!((__accum.indexOf("aa1")!==-1)&&(__accum.indexOf("ca3")!==-1))) {
+ throw new Test262Error('#1: (__accum.indexOf("aa1")!==-1)&&(__accum.indexOf("ca3")!==-1)');
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+//CHECK#2
+if (__accum.indexOf("ba2")!==-1) {
+ throw new Test262Error('#2: __accum.indexOf("ba2") === -1. Actual: __accum.indexOf("ba2") ==='+ __accum.indexOf("ba2") );
+}
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+// erasator is the hash map terminator
+function erasator_T_1000(hash_map, charactr){
+ for (var key in hash_map){
+ if (key.indexOf(charactr)===0) {
+ delete hash_map[key];
+ };
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js b/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js
new file mode 100644
index 0000000000..ae7800a414
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/S12.6.4_A7_T2.js
@@ -0,0 +1,45 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+ Properties of the object being enumerated may be deleted during
+ enumeration
+es5id: 12.6.4_A7_T2
+description: >
+ Checking "for (var VariableDeclarationNoIn in Expression)
+ Statement" case
+---*/
+
+var __obj, __accum;
+
+__obj = Object.create(null);
+__obj.aa = 1;
+__obj.ba = 2;
+__obj.ca = 3;
+
+__accum="";
+
+for (var __key in __obj){
+
+ erasator_T_1000(__obj,"b");
+
+ __accum+=(__key+__obj[__key]);
+
+}
+
+assert(
+ __accum === "aa1ca3" || __accum === "ca3aa1",
+ "Unexpected value: '" + __accum + "'"
+);
+
+// erasator is the hash map terminator
+function erasator_T_1000(hash_map, charactr){
+ for (var key in hash_map){
+ if (key.indexOf(charactr)===0) {
+ delete hash_map[key];
+ };
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/browser.js b/js/src/tests/test262/language/statements/for-in/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/browser.js
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-decl-abrupt-empty.js b/js/src/tests/test262/language/statements/for-in/cptn-decl-abrupt-empty.js
new file mode 100644
index 0000000000..1b8b4ae24b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-decl-abrupt-empty.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has a declaration and iteration is cancelled
+info: |
+ IterationStatement : for ( var ForBinding in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 2. Let V = undefined.
+ [...]
+ 5. Repeat
+ a. Let nextResult be IteratorStep(iterator).
+ b. ReturnIfAbrupt(nextResult).
+ c. If nextResult is false, return NormalCompletion(V).
+ [...]
+ k. Let result be the result of evaluating stmt.
+ [...]
+ m. If LoopContinues(result, labelSet) is false, return
+ IteratorClose(iterator, UpdateEmpty(result, V)).
+---*/
+
+assert.sameValue(eval('1; for (var a in { x: 0 }) { break; }'), undefined);
+assert.sameValue(eval('2; for (var b in { x: 0 }) { 3; break; }'), 3);
+
+assert.sameValue(
+ eval('4; outer: do { for (var a in { x: 0 }) { continue outer; } } while (false)'),
+ undefined
+);
+assert.sameValue(
+ eval('5; outer: do { for (var b in { x: 0 }) { 6; continue outer; } } while (false)'),
+ 6
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-decl-itr.js b/js/src/tests/test262/language/statements/for-in/cptn-decl-itr.js
new file mode 100644
index 0000000000..c598e39f15
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-decl-itr.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.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has a declaration and iteration occurs
+info: |
+ IterationStatement : for ( var ForBinding in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 2. Let V = undefined.
+ [...]
+ 5. Repeat
+ a. Let nextResult be IteratorStep(iterator).
+ b. ReturnIfAbrupt(nextResult).
+ c. If nextResult is false, return NormalCompletion(V).
+ [...]
+ k. Let result be the result of evaluating stmt.
+ [...]
+ n. If result.[[value]] is not empty, let V be result.[[value]].
+---*/
+
+assert.sameValue(eval('1; for (var a in { x: 0 }) { }'), undefined);
+assert.sameValue(eval('2; for (var b in { x: 0 }) { 3; }'), 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-decl-skip-itr.js b/js/src/tests/test262/language/statements/for-in/cptn-decl-skip-itr.js
new file mode 100644
index 0000000000..7ee1ac90c2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-decl-skip-itr.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has a declaration and iteration is skipped
+info: |
+ IterationStatement : for ( var ForBinding in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+
+ 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation
+
+ [...]
+ 7. If iterationKind is enumerate, then
+ a. If exprValue.[[value]] is null or undefined, then
+ i. Return Completion{[[type]]: break, [[value]]: empty, [[target]]:
+ empty}.
+---*/
+
+assert.sameValue(eval('1; for (var a in undefined) { }'), undefined);
+assert.sameValue(eval('2; for (var b in undefined) { 3; }'), undefined);
+assert.sameValue(eval('4; for (var c in null) { }'), undefined);
+assert.sameValue(eval('5; for (var d in null) { 6; }'), undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-decl-zero-itr.js b/js/src/tests/test262/language/statements/for-in/cptn-decl-zero-itr.js
new file mode 100644
index 0000000000..f4cb2efc4a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-decl-zero-itr.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has a declaration and no iteration occurs
+info: |
+ IterationStatement : for ( var ForBinding in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult,
+ varBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 2. Let V = undefined.
+ [...]
+ 5. Repeat
+ a. Let nextResult be IteratorStep(iterator).
+ b. ReturnIfAbrupt(nextResult).
+ c. If nextResult is false, return NormalCompletion(V).
+---*/
+
+assert.sameValue(eval('1; for (var a in {}) { }'), undefined);
+assert.sameValue(eval('2; for (var b in {}) { 3; }'), undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-expr-abrupt-empty.js b/js/src/tests/test262/language/statements/for-in/cptn-expr-abrupt-empty.js
new file mode 100644
index 0000000000..1e186b2b4c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-expr-abrupt-empty.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has no declaration and iteration is cancelled
+info: |
+ IterationStatement : for ( LeftHandSideExpression in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 2. Let V = undefined.
+ [...]
+ 5. Repeat
+ a. Let nextResult be IteratorStep(iterator).
+ b. ReturnIfAbrupt(nextResult).
+ c. If nextResult is false, return NormalCompletion(V).
+ [...]
+ k. Let result be the result of evaluating stmt.
+ [...]
+ m. If LoopContinues(result, labelSet) is false, return
+ IteratorClose(iterator, UpdateEmpty(result, V)).
+---*/
+
+assert.sameValue(eval('var a; 1; for (a in { x: 0 }) { break; }'), undefined);
+assert.sameValue(eval('var b; 2; for (b in { x: 0 }) { 3; break; }'), 3);
+
+assert.sameValue(
+ eval('var a; 4; outer: do { for (a in { x: 0 }) { continue outer; } } while (false)'),
+ undefined
+);
+assert.sameValue(
+ eval('var b; 5; outer: do { for (b in { x: 0 }) { 6; continue outer; } } while (false)'),
+ 6
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-expr-itr.js b/js/src/tests/test262/language/statements/for-in/cptn-expr-itr.js
new file mode 100644
index 0000000000..9e4242dc03
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-expr-itr.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.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has no declaration and iteration occurs
+info: |
+ IterationStatement : for ( LeftHandSideExpression in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 2. Let V = undefined.
+ [...]
+ 5. Repeat
+ a. Let nextResult be IteratorStep(iterator).
+ b. ReturnIfAbrupt(nextResult).
+ c. If nextResult is false, return NormalCompletion(V).
+ [...]
+ k. Let result be the result of evaluating stmt.
+ [...]
+ n. If result.[[value]] is not empty, let V be result.[[value]].
+---*/
+
+assert.sameValue(eval('var a; 1; for (a in { x: 0 }) { }'), undefined);
+assert.sameValue(eval('var b; 2; for (b in { x: 0 }) { 3; }'), 3);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-expr-skip-itr.js b/js/src/tests/test262/language/statements/for-in/cptn-expr-skip-itr.js
new file mode 100644
index 0000000000..f473542dec
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-expr-skip-itr.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has no declaration and iteration is skipped
+info: |
+ IterationStatement : for ( LeftHandSideExpression in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+
+ 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation
+
+ [...]
+ 7. If iterationKind is enumerate, then
+ a. If exprValue.[[value]] is null or undefined, then
+ i. Return Completion{[[type]]: break, [[value]]: empty, [[target]]:
+ empty}.
+---*/
+
+assert.sameValue(eval('var a; 1; for (a in undefined) { }'), undefined);
+assert.sameValue(eval('var b; 2; for (b in undefined) { 3; }'), undefined);
+assert.sameValue(eval('var c; 4; for (c in null) { }'), undefined);
+assert.sameValue(eval('var d; 5; for (d in null) { 6; }'), undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/cptn-expr-zero-itr.js b/js/src/tests/test262/language/statements/for-in/cptn-expr-zero-itr.js
new file mode 100644
index 0000000000..a68f14494f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/cptn-expr-zero-itr.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.7.5.11
+description: >
+ Completion value when head has no declaration and no iteration occurs
+info: |
+ IterationStatement : for ( LeftHandSideExpression in Expression ) Statement
+
+ 1. Let keyResult be ForIn/OfHeadEvaluation( « », Expression, enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 2. Let V = undefined.
+ [...]
+ 5. Repeat
+ a. Let nextResult be IteratorStep(iterator).
+ b. ReturnIfAbrupt(nextResult).
+ c. If nextResult is false, return NormalCompletion(V).
+---*/
+
+assert.sameValue(eval('var a; 1; for (a in {}) { }'), undefined);
+assert.sameValue(eval('var b; 2; for (b in {}) { 3; }'), undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/decl-async-fun.js b/js/src/tests/test262/language/statements/for-in/decl-async-fun.js
new file mode 100644
index 0000000000..daf6f9ac7f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-async-fun.js
@@ -0,0 +1,21 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-in-and-for-of-statements
+description: >
+ AsyncFunctionDeclaration is not allowed in statement position
+info: |
+ ExpressionStatement[Yield, Await] :
+ [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
+ Expression[+In, ?Yield, ?Await] ;
+negative:
+ phase: parse
+ type: SyntaxError
+features: [async-functions]
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) async function f() {}
diff --git a/js/src/tests/test262/language/statements/for-in/decl-async-gen.js b/js/src/tests/test262/language/statements/for-in/decl-async-gen.js
new file mode 100644
index 0000000000..fb494e4384
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-async-gen.js
@@ -0,0 +1,21 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-in-and-for-of-statements
+description: >
+ AsyncGeneratorDeclaration is not allowed in statement position
+info: |
+ ExpressionStatement[Yield, Await] :
+ [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
+ Expression[+In, ?Yield, ?Await] ;
+negative:
+ phase: parse
+ type: SyntaxError
+features: [async-iteration]
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) async function* g() {}
diff --git a/js/src/tests/test262/language/statements/for-in/decl-cls.js b/js/src/tests/test262/language/statements/for-in/decl-cls.js
new file mode 100644
index 0000000000..71c5e75d11
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-cls.js
@@ -0,0 +1,15 @@
+// |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.
+/*---
+description: Class declaration not allowed in statement position
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) class C {}
diff --git a/js/src/tests/test262/language/statements/for-in/decl-const.js b/js/src/tests/test262/language/statements/for-in/decl-const.js
new file mode 100644
index 0000000000..44290e6877
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-const.js
@@ -0,0 +1,15 @@
+// |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.
+/*---
+description: Lexical declaration (const) not allowed in statement position
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) const y = null;
diff --git a/js/src/tests/test262/language/statements/for-in/decl-fun.js b/js/src/tests/test262/language/statements/for-in/decl-fun.js
new file mode 100644
index 0000000000..bbf0df9899
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-fun.js
@@ -0,0 +1,15 @@
+// |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.
+/*---
+description: Function declaration not allowed in statement position
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) function f() {}
diff --git a/js/src/tests/test262/language/statements/for-in/decl-gen.js b/js/src/tests/test262/language/statements/for-in/decl-gen.js
new file mode 100644
index 0000000000..a50259ad05
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-gen.js
@@ -0,0 +1,16 @@
+// |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.
+/*---
+description: Generator declaration not allowed in statement position
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+features: [generators]
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) function* g() {}
diff --git a/js/src/tests/test262/language/statements/for-in/decl-let.js b/js/src/tests/test262/language/statements/for-in/decl-let.js
new file mode 100644
index 0000000000..db3fe3b034
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/decl-let.js
@@ -0,0 +1,15 @@
+// |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.
+/*---
+description: Lexical declaration (let) not allowed in statement position
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) let y;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-init-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-init-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..d58f1a9e2b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-init-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-init-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of an AssignmentElement outside of a generator function body, it behaves as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([ x = yield ] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-invalid.js
new file mode 100644
index 0000000000..17f34e04c0
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([[(x, y)]] in [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..4f3e87dab4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-array-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-array-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of a nested destructuring assignment outside of strict mode, it behaves as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([[x[yield]]] in [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..f07643b8f2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-memberexpr-optchain-prop-ref-init.js
@@ -0,0 +1,66 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-memberexpr-optchain-prop-ref-init.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [optional-chaining, destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+
+ Syntax
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ OptionalExpression:
+ MemberExpression OptionalChain
+ CallExpression OptionalChain
+ OptionalExpression OptionalChain
+
+ OptionalChain:
+ ?. [ Expression ]
+ ?. IdentifierName
+ ?. Arguments
+ ?. TemplateLiteral
+ OptionalChain [ Expression ]
+ OptionalChain .IdentifierName
+ OptionalChain Arguments
+ OptionalChain TemplateLiteral
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
+
+ Static Semantics: IsValidSimpleAssignmentTarget
+
+ LeftHandSideExpression : OptionalExpression
+ 1. Return false.
+
+---*/
+$DONOTEVALUATE();
+var x = {};
+
+for ([x?.y = 42] in [[23]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-invalid.js
new file mode 100644
index 0000000000..d12f86f553
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([{ get x() {} }] in [[{}]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..709a3fa9f5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-nested-obj-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-nested-obj-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment outside of a generator function body, it behaves as a IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([{ x = yield }] in [[{}]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..1b05d6fd99
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-put-obj-literal-optchain-prop-ref-init.js
@@ -0,0 +1,69 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-put-obj-literal-optchain-prop-ref-init.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [optional-chaining, destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+
+ Syntax
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ OptionalExpression:
+ MemberExpression OptionalChain
+ CallExpression OptionalChain
+ OptionalExpression OptionalChain
+
+ OptionalChain:
+ ?. [ Expression ]
+ ?. IdentifierName
+ ?. Arguments
+ ?. TemplateLiteral
+ OptionalChain [ Expression ]
+ OptionalChain .IdentifierName
+ OptionalChain Arguments
+ OptionalChain TemplateLiteral
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
+
+ Static Semantics: IsValidSimpleAssignmentTarget
+
+ LeftHandSideExpression : OptionalExpression
+ 1. Return false.
+
+---*/
+$DONOTEVALUATE();
+
+for ([{
+ set y(val) {
+ throw new Test262Error('The property should not be accessed.');
+ }
+}?.y = 42] in [[23]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-simple-strict-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-simple-strict-strict.js
new file mode 100644
index 0000000000..f5a4747f93
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-simple-strict-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-target-simple-strict.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is false. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([arguments] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-yield-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-yield-invalid-strict.js
new file mode 100644
index 0000000000..d0e58a5b06
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-elem-target-yield-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-elem-target-yield-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentElement and outside of a generator function body, it behaves as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([ x[yield] ] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-element.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-element.js
new file mode 100644
index 0000000000..cc0e130b32
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-element.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-before-element.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: An AssignmentElement may not follow an AssignmentRestElement in an AssignmentElementList. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...x, y] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-elision.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-elision.js
new file mode 100644
index 0000000000..5679bae445
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-elision.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-before-elision.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: An elision may not follow an AssignmentRestElement in an AssignmentElementList. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...x,] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-rest.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-rest.js
new file mode 100644
index 0000000000..d4f66dfce2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-before-rest.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-before-rest.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: An AssignmentRestElement may not follow another AssignmentRestElement in an AssignmentElementList. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...x, ...y] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-elision-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-elision-invalid.js
new file mode 100644
index 0000000000..a8ecd55db9
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-elision-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-elision-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: ArrayAssignmentPattern may not include elisions following an AssignmentRestElement in a AssignmentElementList. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...x,] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-init.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-init.js
new file mode 100644
index 0000000000..b36cfaa08b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-init.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-init.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: The AssignmentRestElement does not support an initializer. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+var x;
+
+for ([...x = 1] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-invalid.js
new file mode 100644
index 0000000000..a15928fdad
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...[(x, y)]] in [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..471ffd5816
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-array-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-array-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of a nested destructuring assignment and outside of a generator function body, it should behave as an IdentifierExpression. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...[x[yield]]] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-invalid.js
new file mode 100644
index 0000000000..6e9f02e7f5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...{ get x() {} }] in [[[]]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..9bef5247c3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-nested-obj-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-nested-obj-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and outside of a generator function body, it should behave as an IdentifierExpression. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ([...{ x = yield }] in [[{}]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/array-rest-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..8eb174f956
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/array-rest-yield-ident-invalid-strict.js
@@ -0,0 +1,35 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/array-rest-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentRestElement and outside of a generator function body, it should behave as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+var x = {};
+
+for ([...x[yield]] in [[]]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/browser.js b/js/src/tests/test262/language/statements/for-in/dstr/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/browser.js
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-expr.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-expr.js
new file mode 100644
index 0000000000..e25d88f3e4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-expr.js
@@ -0,0 +1,36 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-yield-expr.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: yield is not a valid IdentifierReference in an AssignmentProperty within generator function bodies. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [generators, destructuring-binding]
+flags: [generated, noStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+(function*() {
+
+for ({ yield } in [{}]) ;
+
+});
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..ad47dfa927
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-identifier-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-identifier-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: yield is not a valid IdentifierReference in an AssignmentProperty within strict mode code. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ yield } in [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-simple-strict-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-simple-strict-strict.js
new file mode 100644
index 0000000000..df621510c3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-simple-strict-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-simple-strict.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if IsValidSimpleAssignmentTarget of IdentifierReference is false. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ eval = 0 } in [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..f58aecb243
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-init-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-init-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of an AssignmentProperty and outside of a generator function body, it should behave as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x = yield } in [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-id-simple-strict-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-simple-strict-strict.js
new file mode 100644
index 0000000000..96b86c86d1
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-id-simple-strict-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-id-simple-strict.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if IsValidSimpleAssignmentTarget of IdentifierReference is false. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ eval } in [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..4047197760
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-init-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-init-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of an AssignmentElement and outside of a generator function body, it should behave as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x: x = yield } in [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..91c8913af4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.js
@@ -0,0 +1,66 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-memberexpr-optchain-prop-ref-init.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (MemberExpression OptionalChain .IdentifierName Initializer) (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [optional-chaining, destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+
+ Syntax
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ OptionalExpression:
+ MemberExpression OptionalChain
+ CallExpression OptionalChain
+ OptionalExpression OptionalChain
+
+ OptionalChain:
+ ?. [ Expression ]
+ ?. IdentifierName
+ ?. Arguments
+ ?. TemplateLiteral
+ OptionalChain [ Expression ]
+ OptionalChain .IdentifierName
+ OptionalChain Arguments
+ OptionalChain TemplateLiteral
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
+
+ Static Semantics: IsValidSimpleAssignmentTarget
+
+ LeftHandSideExpression : OptionalExpression
+ 1. Return false.
+
+---*/
+$DONOTEVALUATE();
+var y = {};
+
+for ({ x: y?.z = 42 } in [{ x: 23 }]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js
new file mode 100644
index 0000000000..ba16f696e3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.js
@@ -0,0 +1,69 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-obj-literal-optchain-prop-ref-init.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression of an DestructuringAssignmentTarget is neither an ObjectLiteral nor an ArrayLiteral and AssignmentTargetType(LeftHandSideExpression) is not simple Using Object (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [optional-chaining, destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+
+ Syntax
+
+ AssignmentElement : DestructuringAssignmentTarget Initializer_opt
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ Static Semantics: Early Errors
+
+ OptionalExpression:
+ MemberExpression OptionalChain
+ CallExpression OptionalChain
+ OptionalExpression OptionalChain
+
+ OptionalChain:
+ ?. [ Expression ]
+ ?. IdentifierName
+ ?. Arguments
+ ?. TemplateLiteral
+ OptionalChain [ Expression ]
+ OptionalChain .IdentifierName
+ OptionalChain Arguments
+ OptionalChain TemplateLiteral
+
+ DestructuringAssignmentTarget : LeftHandSideExpression
+
+ - It is a Syntax Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget(LeftHandSideExpression) is not true.
+
+ Static Semantics: IsValidSimpleAssignmentTarget
+
+ LeftHandSideExpression : OptionalExpression
+ 1. Return false.
+
+---*/
+$DONOTEVALUATE();
+
+for ({ x: {
+ set y(val) {
+ throw new Test262Error('The property should not be accessed.');
+ }
+}?.y = 42} in [{x: 42}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..c900a5c99e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-elem-target-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-elem-target-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the DestructuringAssignmentTarget of an AssignmentElement and outside of a generator function body, it should behave as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x: x[yield] } in [{}]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-invalid.js
new file mode 100644
index 0000000000..d7a6a95084
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x: [(x, y)] } in [{ x: [] }]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..30d93ebabb
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-array-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-array-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and outside of a generator function body, it should behave as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x: [x = yield] } in [{ x: [] }]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-invalid.js
new file mode 100644
index 0000000000..bdb012fc97
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-invalid.js
@@ -0,0 +1,33 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral and if the lexical token sequence matched by LeftHandSideExpression cannot be parsed with no tokens left over using AssignmentPattern as the goal symbol. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x: { get x() {} } } in [{ x: {} }]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js
new file mode 100644
index 0000000000..cb77a9348f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-prop-nested-obj-yield-ident-invalid-strict.js
@@ -0,0 +1,34 @@
+// |reftest| error:SyntaxError
+'use strict';
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-prop-nested-obj-yield-ident-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: When a `yield` token appears within the Initializer of a nested destructuring assignment and outside of a generator function body, it should behave as an IdentifierReference. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [destructuring-binding]
+flags: [generated, onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+
+for ({ x: { x = yield } } in [{ x: {} }]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/obj-rest-not-last-element-invalid.js b/js/src/tests/test262/language/statements/for-in/dstr/obj-rest-not-last-element-invalid.js
new file mode 100644
index 0000000000..dc532f4d5b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/obj-rest-not-last-element-invalid.js
@@ -0,0 +1,35 @@
+// |reftest| error:SyntaxError
+// This file was procedurally generated from the following sources:
+// - src/dstr-assignment/obj-rest-not-last-element-invalid.case
+// - src/dstr-assignment/syntax/for-in.template
+/*---
+description: Object rest element needs to be the last AssignmenProperty in ObjectAssignmentPattern. (For..in statement)
+esid: sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+features: [object-rest, destructuring-binding]
+flags: [generated]
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ IterationStatement :
+ for ( LeftHandSideExpression of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ? ForIn/OfHeadEvaluation(« »,
+ AssignmentExpression, iterate).
+ 2. Return ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement,
+ keyResult, assignment, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 4. If destructuring is true and if lhsKind is assignment, then
+ a. Assert: lhs is a LeftHandSideExpression.
+ b. Let assignmentPattern be the parse of the source text corresponding to
+ lhs using AssignmentPattern as the goal symbol.
+ [...]
+---*/
+$DONOTEVALUATE();
+var rest, b;
+
+for ({...rest, b} in [{}
+]) ;
diff --git a/js/src/tests/test262/language/statements/for-in/dstr/shell.js b/js/src/tests/test262/language/statements/for-in/dstr/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/dstr/shell.js
diff --git a/js/src/tests/test262/language/statements/for-in/head-const-bound-names-dup.js b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-dup.js
new file mode 100644
index 0000000000..df52e66409
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-dup.js
@@ -0,0 +1,18 @@
+// |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.
+/*---
+description: The head's declaration may not contain duplicate entries
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ It is a Syntax Error if the BoundNames of ForDeclaration contains any
+ duplicate entries.
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+---*/
+
+$DONOTEVALUATE();
+
+for (const [x, x] in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-const-bound-names-fordecl-tdz.js b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-fordecl-tdz.js
new file mode 100644
index 0000000000..c3b281209c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-fordecl-tdz.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.12_S2
+description: >
+ ForIn/Of: Bound names of ForDeclaration are in TDZ (for-of)
+---*/
+
+assert.throws(ReferenceError, function() {
+ let x = 1;
+ for (const x in { x }) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-const-bound-names-in-stmt.js b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-in-stmt.js
new file mode 100644
index 0000000000..27c09224a2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-in-stmt.js
@@ -0,0 +1,20 @@
+// |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.
+/*---
+description: The body may not re-declare variables declared in the head
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ It is a Syntax Error if any element of the BoundNames of ForDeclaration
+ also occurs in the VarDeclaredNames of Statement.
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+---*/
+
+$DONOTEVALUATE();
+
+for (const x in {}) {
+ var x;
+}
diff --git a/js/src/tests/test262/language/statements/for-in/head-const-bound-names-let.js b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-let.js
new file mode 100644
index 0000000000..deca364ed5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-const-bound-names-let.js
@@ -0,0 +1,18 @@
+// |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.
+/*---
+description: The declaration may not contain a binding for `let`
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+flags: [noStrict]
+---*/
+
+$DONOTEVALUATE();
+
+for (const let in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-const-fresh-binding-per-iteration.js b/js/src/tests/test262/language/statements/for-in/head-const-fresh-binding-per-iteration.js
new file mode 100644
index 0000000000..460f398e4b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-const-fresh-binding-per-iteration.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2011 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.13
+description: >
+ const ForDeclaration: creates a fresh binding per iteration
+---*/
+
+let s = '';
+for (const x of [1, 2, 3]) {
+ s += x;
+}
+assert.sameValue(s, '123', "The value of `s` is `'123'`");
+
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-decl-expr.js b/js/src/tests/test262/language/statements/for-in/head-decl-expr.js
new file mode 100644
index 0000000000..7208b10a5a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-decl-expr.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Expression is allowed in head
+info: |
+ IterationStatement : for ( ForDeclaration in Expression ) Statement
+
+ 1. Let keyResult be the result of performing
+ ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression,
+ enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+es6id: 13.7.5.11
+---*/
+
+var iterCount = 0;
+
+for (let x in null, { key: 0 }) {
+ assert.sameValue(x, 'key');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-expr-expr.js b/js/src/tests/test262/language/statements/for-in/head-expr-expr.js
new file mode 100644
index 0000000000..9ad88f1836
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-expr-expr.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Expression is allowed in head
+info: |
+ IterationStatement : for ( ForDeclaration in Expression ) Statement
+
+ 1. Let keyResult be the result of performing
+ ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression,
+ enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+es6id: 13.7.5.11
+---*/
+
+var iterCount = 0;
+var x;
+
+for (x in null, { key: 0 }) {
+ assert.sameValue(x, 'key');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-let-bound-names-dup.js b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-dup.js
new file mode 100644
index 0000000000..f3ac4d4ef4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-dup.js
@@ -0,0 +1,18 @@
+// |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.
+/*---
+description: The head's declaration may not contain duplicate entries
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ It is a Syntax Error if the BoundNames of ForDeclaration contains any
+ duplicate entries.
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+---*/
+
+$DONOTEVALUATE();
+
+for (let [x, x] in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-let-bound-names-fordecl-tdz.js b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-fordecl-tdz.js
new file mode 100644
index 0000000000..2693e9e318
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-fordecl-tdz.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 13.6.4.12_S2
+description: >
+ ForIn/Of: Bound names of ForDeclaration are in TDZ (for-of)
+---*/
+
+assert.throws(ReferenceError, function() {
+ let x = 1;
+ for (let x in { x }) {}
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-let-bound-names-in-stmt.js b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-in-stmt.js
new file mode 100644
index 0000000000..2264f8e31a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-in-stmt.js
@@ -0,0 +1,20 @@
+// |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.
+/*---
+description: The body may not re-declare variables declared in the head
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ It is a Syntax Error if any element of the BoundNames of ForDeclaration
+ also occurs in the VarDeclaredNames of Statement.
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+---*/
+
+$DONOTEVALUATE();
+
+for (let x in {}) {
+ var x;
+}
diff --git a/js/src/tests/test262/language/statements/for-in/head-let-bound-names-let.js b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-let.js
new file mode 100644
index 0000000000..42bf0f6523
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-let-bound-names-let.js
@@ -0,0 +1,18 @@
+// |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.
+/*---
+description: The declaration may not contain a binding for `let`
+negative:
+ phase: parse
+ type: SyntaxError
+info: |
+ It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
+flags: [noStrict]
+esid: sec-for-in-and-for-of-statements
+es6id: 13.7.5
+---*/
+
+$DONOTEVALUATE();
+
+for (let let in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-let-destructuring.js b/js/src/tests/test262/language/statements/for-in/head-let-destructuring.js
new file mode 100644
index 0000000000..c9465b8b7a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-let-destructuring.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-iteration-statements
+es6id: 13.7
+description: >
+ The token sequence `let [`is interpreted as the beginning of a destructuring
+ binding pattern
+info: |
+ Syntax
+
+ IterationStatement[Yield, Return]:
+
+ for ( [lookahead ∉ { let [ } ] LeftHandSideExpression[?Yield] in
+ Expression[+In, ?Yield] ) Statement[?Yield, ?Return]
+
+ for ( ForDeclaration[?Yield] in Expression[+In, ?Yield] )
+ Statement[?Yield, ?Return]
+---*/
+
+var obj = Object.create(null);
+var value;
+
+obj.key = 1;
+
+for ( let[x] in obj ) {
+ value = x;
+}
+
+assert.sameValue(typeof x, 'undefined', 'binding is block-scoped');
+assert.sameValue(value, 'k');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-let-fresh-binding-per-iteration.js b/js/src/tests/test262/language/statements/for-in/head-let-fresh-binding-per-iteration.js
new file mode 100644
index 0000000000..b1aea266fe
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-let-fresh-binding-per-iteration.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2011 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
+es6id: 13.7.5.13
+description: >
+ let ForDeclaration: creates a fresh binding per iteration
+---*/
+
+var fns = {};
+var obj = Object.create(null);
+obj.a = 1;
+obj.b = 1;
+obj.c = 1;
+
+for (let x in obj) {
+ // Store function objects as properties of an object so that their return
+ // value may be verified regardless of the for-in statement's enumeration
+ // order.
+ fns[x] = function() { return x; };
+}
+
+assert.sameValue(typeof fns.a, 'function', 'property definition: "a"');
+assert.sameValue(fns.a(), 'a');
+assert.sameValue(typeof fns.b, 'function', 'property definition: "b"');
+assert.sameValue(fns.b(), 'b');
+assert.sameValue(typeof fns.c, 'function', 'property definition: "c"');
+assert.sameValue(fns.c(), 'c');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-cover-non-asnmt-trgt.js b/js/src/tests/test262/language/statements/for-in/head-lhs-cover-non-asnmt-trgt.js
new file mode 100644
index 0000000000..21c5c9124e
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-cover-non-asnmt-trgt.js
@@ -0,0 +1,25 @@
+// |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.
+
+/*---
+description: Head's LeftHandSideExpression must be a simple assignment target
+info: |
+ It is a Syntax Error if IsValidSimpleAssignmentTarget of
+ LeftHandSideExpression is false.
+
+ It is a Syntax Error if the LeftHandSideExpression is
+ CoverParenthesizedExpressionAndArrowParameterList : ( Expression ) and
+ Expression derives a production that would produce a Syntax Error according
+ to these rules if that production is substituted for
+ LeftHandSideExpression. This rule is recursively applied.
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for ((this) in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-cover.js b/js/src/tests/test262/language/statements/for-in/head-lhs-cover.js
new file mode 100644
index 0000000000..108a4775c6
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-cover.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Head's AssignmentExpression may be CoverParenthesizedExpressionAndArrowParameterList
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+---*/
+
+var iterCount = 0;
+var x;
+
+for ((x) in { attr: null }) {
+ assert.sameValue(x, 'attr');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-ary.js b/js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-ary.js
new file mode 100644
index 0000000000..0710c74012
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-ary.js
@@ -0,0 +1,21 @@
+// |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.
+
+/*---
+description: Invalid destructuring assignment pattern (array literal)
+info: |
+ It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral
+ or an ArrayLiteral and if the lexical token sequence matched by
+ LeftHandSideExpression cannot be parsed with no tokens left over using
+ AssignmentPattern as the goal symbol.
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for ([(x, y)] in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-obj.js b/js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-obj.js
new file mode 100644
index 0000000000..ca8a72be7c
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-invalid-asnmt-ptrn-obj.js
@@ -0,0 +1,21 @@
+// |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.
+
+/*---
+description: Invalid destructuring assignment pattern (object literal)
+info: |
+ It is a Syntax Error if LeftHandSideExpression is either an ObjectLiteral
+ or an ArrayLiteral and if the lexical token sequence matched by
+ LeftHandSideExpression cannot be parsed with no tokens left over using
+ AssignmentPattern as the goal symbol.
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for ({ m() {} } in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-let.js b/js/src/tests/test262/language/statements/for-in/head-lhs-let.js
new file mode 100644
index 0000000000..4e45b7c9a2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-let.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-iteration-statements
+es6id: 13.7
+description: >
+ The `let` token is interpreted as an Identifier when it is not followed by a
+ `[` token
+info: |
+ Syntax
+
+ IterationStatement[Yield, Return]:
+
+ for ( [lookahead ∉ { let [ } ] LeftHandSideExpression[?Yield] in
+ Expression[+In, ?Yield] ) Statement[?Yield, ?Return]
+
+ for ( ForDeclaration[?Yield] in Expression[+In, ?Yield] )
+ Statement[?Yield, ?Return]
+flags: [noStrict]
+---*/
+
+var obj = Object.create(null);
+var let, value;
+
+obj.key = 1;
+
+for ( let in obj ) ;
+
+assert.sameValue(let, 'key', 'IdentifierReference');
+
+Object.defineProperty(Array.prototype, '1', {
+ set: function(param) {
+ value = param;
+ }
+});
+for ( [let][1] in obj ) ;
+
+assert.sameValue(value, 'key', 'MemberExpression');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-member.js b/js/src/tests/test262/language/statements/for-in/head-lhs-member.js
new file mode 100644
index 0000000000..1aabaa75b4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-member.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Head's AssignmentExpression may be a MemberExpression
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+---*/
+
+var iterCount = 0;
+var x = {};
+
+for (x.y in { attr: null }) {
+ assert.sameValue(x.y, 'attr');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-lhs-non-asnmt-trgt.js b/js/src/tests/test262/language/statements/for-in/head-lhs-non-asnmt-trgt.js
new file mode 100644
index 0000000000..4c195a0402
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-lhs-non-asnmt-trgt.js
@@ -0,0 +1,19 @@
+// |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.
+
+/*---
+description: Head's LeftHandSideExpression must be a simple assignment target
+info: |
+ It is a Syntax Error if IsValidSimpleAssignmentTarget of
+ LeftHandSideExpression is false.
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (this in {}) {}
diff --git a/js/src/tests/test262/language/statements/for-in/head-var-bound-names-dup.js b/js/src/tests/test262/language/statements/for-in/head-var-bound-names-dup.js
new file mode 100644
index 0000000000..83d4f820dd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-var-bound-names-dup.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The head's declaration may contain duplicate entries
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+---*/
+
+var iterCount = 0;
+
+for (var [x, x] in { ab: null }) {
+ assert.sameValue(x, 'b');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-var-bound-names-in-stmt.js b/js/src/tests/test262/language/statements/for-in/head-var-bound-names-in-stmt.js
new file mode 100644
index 0000000000..7dcffd8a1f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-var-bound-names-in-stmt.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: The body may re-declare variables declared in the head
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+---*/
+
+var iterCount = 0;
+
+for (var x in { attr: null }) {
+ var x;
+
+ assert.sameValue(x, 'attr');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-var-bound-names-let.js b/js/src/tests/test262/language/statements/for-in/head-var-bound-names-let.js
new file mode 100644
index 0000000000..9af850a2d5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-var-bound-names-let.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The head's bound names may include "let"
+esid: sec-for-in-and-for-of-statements-static-semantics-early-errors
+es6id: 13.7.5
+flags: [noStrict]
+---*/
+
+var iterCount = 0;
+
+for (var let in { attr: null }) {
+ assert.sameValue(let, 'attr');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/head-var-expr.js b/js/src/tests/test262/language/statements/for-in/head-var-expr.js
new file mode 100644
index 0000000000..b7ff66f987
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/head-var-expr.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Expression is allowed in head
+info: |
+ IterationStatement : for ( ForDeclaration in Expression ) Statement
+
+ 1. Let keyResult be the result of performing
+ ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression,
+ enumerate).
+ 2. ReturnIfAbrupt(keyResult).
+ 3. Return ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+es6id: 13.7.5.11
+---*/
+
+var iterCount = 0;
+
+for (var x in null, { key: 0 }) {
+ assert.sameValue(x, 'key');
+ iterCount += 1;
+}
+
+assert.sameValue(iterCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/identifier-let-allowed-as-lefthandside-expression-not-strict.js b/js/src/tests/test262/language/statements/for-in/identifier-let-allowed-as-lefthandside-expression-not-strict.js
new file mode 100644
index 0000000000..f0d109c679
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/identifier-let-allowed-as-lefthandside-expression-not-strict.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2011 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ identifier "let" allowed as lefthandside expression
+esid: sec-iteration-statements
+info: |
+ for ( [ lookahead ∉ { let [ } ] LeftHandSideExpression [?Yield, ?Await] in
+ Expression[+In, ?Yield, ? Await]) Statement[?Yield, ?Await, ?Return]
+flags: [noStrict]
+---*/
+for (let in {}) { }
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-const.js b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-const.js
new file mode 100644
index 0000000000..021a7f923b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-const.js
@@ -0,0 +1,19 @@
+// |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.
+/*---
+description: It is a Syntax Error if IsLabelledFunction(Statement) is true.
+negative:
+ phase: parse
+ type: SyntaxError
+esid: sec-semantics-static-semantics-early-errors
+es6id: 13.7.1.1
+info: |
+ Although Annex B describes an extension which permits labelled function
+ declarations outside of strict mode, this early error is applied regardless
+ of the language mode.
+---*/
+
+$DONOTEVALUATE();
+
+for (const x in {}) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-let.js b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-let.js
new file mode 100644
index 0000000000..557f634a92
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-let.js
@@ -0,0 +1,19 @@
+// |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.
+/*---
+description: It is a Syntax Error if IsLabelledFunction(Statement) is true.
+negative:
+ phase: parse
+ type: SyntaxError
+esid: sec-semantics-static-semantics-early-errors
+es6id: 13.7.1.1
+info: |
+ Although Annex B describes an extension which permits labelled function
+ declarations outside of strict mode, this early error is applied regardless
+ of the language mode.
+---*/
+
+$DONOTEVALUATE();
+
+for (let x in {}) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-lhs.js b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-lhs.js
new file mode 100644
index 0000000000..a95c2e3895
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-lhs.js
@@ -0,0 +1,19 @@
+// |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.
+/*---
+description: It is a Syntax Error if IsLabelledFunction(Statement) is true.
+negative:
+ phase: parse
+ type: SyntaxError
+esid: sec-semantics-static-semantics-early-errors
+es6id: 13.7.1.1
+info: |
+ Although Annex B describes an extension which permits labelled function
+ declarations outside of strict mode, this early error is applied regardless
+ of the language mode.
+---*/
+
+$DONOTEVALUATE();
+
+for (x in {}) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-var.js b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-var.js
new file mode 100644
index 0000000000..dc3c9c38e2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/labelled-fn-stmt-var.js
@@ -0,0 +1,19 @@
+// |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.
+/*---
+description: It is a Syntax Error if IsLabelledFunction(Statement) is true.
+negative:
+ phase: parse
+ type: SyntaxError
+esid: sec-semantics-static-semantics-early-errors
+es6id: 13.7.1.1
+info: |
+ Although Annex B describes an extension which permits labelled function
+ declarations outside of strict mode, this early error is applied regardless
+ of the language mode.
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in {}) label1: label2: function f() {}
diff --git a/js/src/tests/test262/language/statements/for-in/let-array-with-newline.js b/js/src/tests/test262/language/statements/for-in/let-array-with-newline.js
new file mode 100644
index 0000000000..3cef8a7963
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/let-array-with-newline.js
@@ -0,0 +1,22 @@
+// |reftest| error:SyntaxError
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-in-and-for-of-statements
+description: >
+ ExpressionStatement has a lookahead restriction for `let [`.
+info: |
+ ExpressionStatement[Yield, Await] :
+ [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
+ Expression[+In, ?Yield, ?Await] ;
+negative:
+ phase: parse
+ type: SyntaxError
+flags: [noStrict]
+---*/
+
+$DONOTEVALUATE();
+
+for (var x in null) let
+[a] = 0;
diff --git a/js/src/tests/test262/language/statements/for-in/let-block-with-newline.js b/js/src/tests/test262/language/statements/for-in/let-block-with-newline.js
new file mode 100644
index 0000000000..27a6bf9268
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/let-block-with-newline.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-in-and-for-of-statements
+description: >
+ ExpressionStatement doesn't have a lookahead restriction for `let {`.
+info: |
+ ExpressionStatement[Yield, Await] :
+ [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
+ Expression[+In, ?Yield, ?Await] ;
+flags: [noStrict]
+---*/
+
+for (var x in null) let // ASI
+{}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/let-identifier-with-newline.js b/js/src/tests/test262/language/statements/for-in/let-identifier-with-newline.js
new file mode 100644
index 0000000000..89c01ee5c2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/let-identifier-with-newline.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-in-and-for-of-statements
+description: >
+ ExpressionStatement doesn't have a lookahead restriction for `let <binding-identifier>`.
+info: |
+ ExpressionStatement[Yield, Await] :
+ [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
+ Expression[+In, ?Yield, ?Await] ;
+flags: [noStrict]
+---*/
+
+for (var x in null) let // ASI
+x = 1;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/order-after-define-property.js b/js/src/tests/test262/language/statements/for-in/order-after-define-property.js
new file mode 100644
index 0000000000..f4b53b95a5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/order-after-define-property.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-enumerate-object-properties
+description: >
+ Property names are returned in ascending chronological order of creation
+ that is unaffected by [[DefineOwnProperty]].
+info: |
+ EnumerateObjectProperties ( O )
+
+ EnumerateObjectProperties must obtain the own property keys of the target object
+ by calling its [[OwnPropertyKeys]] internal method. Property attributes of the
+ target object must be obtained by calling its [[GetOwnProperty]] internal method.
+
+ OrdinaryOwnPropertyKeys ( O )
+
+ [...]
+ 3. For each own property key P of O that is a String but is not an array index,
+ in ascending chronological order of property creation, do
+ a. Add P as the last element of keys.
+ [...]
+ 5. Return keys.
+includes: [compareArray.js]
+---*/
+
+var obj = {};
+obj.a = 1;
+obj.b = 2;
+Object.defineProperty(obj, "a", {value: 11});
+var objKeys = [];
+for (var objKey in obj) {
+ objKeys.push(objKey);
+}
+assert.compareArray(objKeys, ["a", "b"]);
+
+var arr = [];
+Object.defineProperty(arr, "a", {
+ get: function() {},
+ enumerable: true,
+ configurable: true,
+})
+arr.b = 2;
+Object.defineProperty(arr, "a", {
+ get: function() {},
+});
+var arrKeys = [];
+for (var arrKey in arr) {
+ arrKeys.push(arrKey);
+}
+assert.compareArray(arrKeys, ["a", "b"]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/order-enumerable-shadowed.js b/js/src/tests/test262/language/statements/for-in/order-enumerable-shadowed.js
new file mode 100644
index 0000000000..f1315a7ad4
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/order-enumerable-shadowed.js
@@ -0,0 +1,35 @@
+// Copyright 2019 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-enumerate-object-properties
+description: Enumerable properties the prototype which are shadowed by non-enumerable properties on the object are not enumerated
+features: [for-in-order]
+includes: [compareArray.js]
+---*/
+
+var proto = {
+ p2: 'p2',
+};
+
+var o = Object.create(proto, {
+ 'p1': {
+ value: 'p1',
+ enumerable: true,
+ },
+ 'p2': {
+ value: 'p1',
+ enumerable: false,
+ },
+});
+
+
+
+var keys = [];
+for (var key in o) {
+ keys.push(key);
+}
+
+assert.compareArray(keys, ['p1']);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/order-property-added.js b/js/src/tests/test262/language/statements/for-in/order-property-added.js
new file mode 100644
index 0000000000..54ab4b19f5
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/order-property-added.js
@@ -0,0 +1,27 @@
+// Copyright 2019 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-enumerate-object-properties
+description: Properties added to the object during iteration are not enumerated
+features: [for-in-order]
+includes: [compareArray.js]
+---*/
+
+var o = {
+ p1: 'p1',
+ p2: 'p2',
+ p3: 'p3',
+};
+
+var keys = [];
+for (var key in o) {
+ if (key === 'p1') {
+ o.p4 = 'p4';
+ }
+ keys.push(key);
+}
+
+assert.compareArray(keys, ['p1', 'p2', 'p3']);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/order-property-on-prototype.js b/js/src/tests/test262/language/statements/for-in/order-property-on-prototype.js
new file mode 100644
index 0000000000..c1f1e9de38
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/order-property-on-prototype.js
@@ -0,0 +1,30 @@
+// Copyright 2019 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-enumerate-object-properties
+description: Properties on the prototype are enumerated after properties on the object
+features: [for-in-order]
+includes: [compareArray.js]
+---*/
+
+var proto = {
+ p4: 'p4',
+};
+
+var o = {
+ p1: 'p1',
+ p2: 'p2',
+ p3: 'p3',
+};
+
+Object.setPrototypeOf(o, proto);
+
+var keys = [];
+for (var key in o) {
+ keys.push(key);
+}
+
+assert.compareArray(keys, ['p1', 'p2', 'p3', 'p4']);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/order-simple-object.js b/js/src/tests/test262/language/statements/for-in/order-simple-object.js
new file mode 100644
index 0000000000..6c066eeb32
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/order-simple-object.js
@@ -0,0 +1,35 @@
+// Copyright 2019 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-enumerate-object-properties
+description: Property enumeration order for simple objects
+features: [for-in-order]
+includes: [compareArray.js]
+---*/
+
+var o = {
+ p1: 'p1',
+ p2: 'p2',
+ p3: 'p3',
+};
+
+o.p4 = 'p4';
+
+o[2] = '2';
+o[0] = '0';
+o[1] = '1';
+
+delete o.p1;
+delete o.p3;
+o.p1 = 'p1';
+
+
+var keys = [];
+for (var key in o) {
+ keys.push(key);
+}
+
+assert.compareArray(keys, ['0', '1', '2', 'p2', 'p4', 'p1']);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-body-lex-boundary.js b/js/src/tests/test262/language/statements/for-in/scope-body-lex-boundary.js
new file mode 100644
index 0000000000..506fb0ff60
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-body-lex-boundary.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: >
+ Creation of new lexical environment for each evaluation of the statement
+ body
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 5. Repeat
+ [...]
+ i. Let result be the result of evaluating stmt.
+ j. Set the running execution context's LexicalEnvironment to oldEnv.
+ k. If LoopContinues(result, labelSet) is false, return ?
+ IteratorClose(iterator, UpdateEmpty(result, V)).
+ l. If result.[[Value]] is not empty, let V be result.[[Value]].
+features: [let]
+---*/
+
+let x = 'outside';
+var probeFirst, probeSecond;
+
+for (let x in { a: 0, b: 0 })
+ if (!probeFirst)
+ probeFirst = function() { return x; };
+ else
+ probeSecond = function() { return x; };
+
+
+// 13.7.5.15 EnumerateObjectProperties
+//
+// > [...] The mechanics and order of enumerating the properties is not
+// > specified [...]
+assert.notSameValue(probeFirst(), probeSecond());
+assert(
+ probeFirst() === 'a' || probeFirst() === 'b',
+ 'First binding is either "a" or "b"'
+);
+assert(
+ probeSecond() === 'a' || probeSecond() === 'b',
+ 'Second binding is either "a" or "b"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-body-lex-close.js b/js/src/tests/test262/language/statements/for-in/scope-body-lex-close.js
new file mode 100644
index 0000000000..b24988864a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-body-lex-close.js
@@ -0,0 +1,42 @@
+// 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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: >
+ Removal of lexical environment for the initial evaluation of the statement
+ body
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 5. Repeat
+ [...]
+ i. Let result be the result of evaluating stmt.
+ j. Set the running execution context's LexicalEnvironment to oldEnv.
+ k. If LoopContinues(result, labelSet) is false, return ?
+ IteratorClose(iterator, UpdateEmpty(result, V)).
+ l. If result.[[Value]] is not empty, let V be result.[[Value]].
+features: [let]
+---*/
+
+let x = 'outside';
+var probeDecl, probeBody;
+
+for (
+ let [x, _ = probeDecl = function() { return x; }]
+ in
+ { i: 0 }
+ )
+ probeBody = function() { return x; };
+
+assert.sameValue(probeDecl(), 'i', 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 'i', 'reference from statement body');
+assert.sameValue(x, 'outside');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-body-lex-open.js b/js/src/tests/test262/language/statements/for-in/scope-body-lex-open.js
new file mode 100644
index 0000000000..e33b87aa0f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-body-lex-open.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: >
+ Creation of new lexical environment for the initial evaluation of the
+ statement body
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 5. Repeat
+ [...]
+ d. If lhsKind is either assignment or varBinding, then
+ [...]
+ e. Else,
+ i. Assert: lhsKind is lexicalBinding.
+ ii. Assert: lhs is a ForDeclaration.
+ iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv).
+ iv. Perform BindingInstantiation for lhs passing iterationEnv as the
+ argument.
+ v. Set the running execution context's LexicalEnvironment to
+ iterationEnv.
+ [...]
+features: [let]
+---*/
+
+var probeBefore = function() { return x; };
+let x = 'outside';
+var probeExpr, probeDecl, probeBody;
+
+for (
+ let [x, _ = probeDecl = function() { return x; }]
+ in
+ { i: probeExpr = function() { typeof x; }}
+ )
+ probeBody = function() { return x; };
+
+assert.sameValue(probeBefore(), 'outside');
+assert.throws(ReferenceError, probeExpr);
+assert.sameValue(probeDecl(), 'i', 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 'i', 'reference from statement body');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-body-var-none.js b/js/src/tests/test262/language/statements/for-in/scope-body-var-none.js
new file mode 100644
index 0000000000..63b0cc6c6f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-body-var-none.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: No variable environment is created for the statement body
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ [...]
+ 2. Return ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult,
+ lexicalBinding, labelSet).
+
+ 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation
+
+ [...]
+ 5. Repeat
+ [...]
+ d. If lhsKind is either assignment or varBinding, then
+ [...]
+ e. Else,
+ i. Assert: lhsKind is lexicalBinding.
+ ii. Assert: lhs is a ForDeclaration.
+ iii. Let iterationEnv be NewDeclarativeEnvironment(oldEnv).
+ iv. Perform BindingInstantiation for lhs passing iterationEnv as the
+ argument.
+ v. Set the running execution context's LexicalEnvironment to
+ iterationEnv.
+ [...]
+features: [let]
+---*/
+
+var probeBefore = function() { return x; };
+var probeExpr, probeDecl, probeBody;
+var x = 1;
+
+for (
+ let [_ = probeDecl = function() { return x; }]
+ in
+ { '': probeExpr = function() { return x; }}
+ )
+ var x = 2, __ = probeBody = function() { return x; };
+
+
+assert.sameValue(probeBefore(), 2, 'reference preceding statement');
+assert.sameValue(probeExpr(), 2, 'reference from AssignmentExpression');
+assert.sameValue(probeDecl(), 2, 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 2, 'reference from statement body');
+assert.sameValue(x, 2, 'reference following statement');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-head-lex-close.js b/js/src/tests/test262/language/statements/for-in/scope-head-lex-close.js
new file mode 100644
index 0000000000..911644825f
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-head-lex-close.js
@@ -0,0 +1,46 @@
+// 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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: >
+ Removal of lexical environment to serve as a temporal dead zone for the
+ statement's AssignmentExpresson
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ?
+ ForIn/OfHeadEvaluation(BoundNames of ForDeclaration,
+ AssignmentExpression, iterate).
+ [...]
+
+ 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation
+
+ [...]
+ 2. If TDZnames is not an empty List, then
+ a. Assert: TDZnames has no duplicate entries.
+ b. Let TDZ be NewDeclarativeEnvironment(oldEnv).
+ c. Let TDZEnvRec be TDZ's EnvironmentRecord.
+ d. For each string name in TDZnames, do
+ i. Perform ! TDZEnvRec.CreateMutableBinding(name, false).
+ e. Set the running execution context's LexicalEnvironment to TDZ.
+ 3. Let exprRef be the result of evaluating expr.
+ 4. Set the running execution context's LexicalEnvironment to oldEnv.
+ [...]
+features: [let]
+---*/
+
+let x = 'outside';
+var probeDecl, probeExpr, probeBody;
+
+for (
+ let [x, _ = probeDecl = function() { return x; }]
+ in
+ { i: probeExpr = function() { typeof x; } }
+ )
+ probeBody = function() { return x; };
+
+assert.throws(ReferenceError, probeExpr);
+assert.sameValue(probeDecl(), 'i', 'reference from ForDeclaration');
+assert.sameValue(probeBody(), 'i', 'reference from statement body');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-head-lex-open.js b/js/src/tests/test262/language/statements/for-in/scope-head-lex-open.js
new file mode 100644
index 0000000000..fb51fb7cb3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-head-lex-open.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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: >
+ Creation of new lexical environment to serve as a temporal dead zone for
+ the statement's AssignmentExpresson
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ?
+ ForIn/OfHeadEvaluation(BoundNames of ForDeclaration,
+ AssignmentExpression, iterate).
+ [...]
+
+ 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation
+
+ [...]
+ 2. If TDZnames is not an empty List, then
+ a. Assert: TDZnames has no duplicate entries.
+ b. Let TDZ be NewDeclarativeEnvironment(oldEnv).
+ c. Let TDZEnvRec be TDZ's EnvironmentRecord.
+ d. For each string name in TDZnames, do
+ i. Perform ! TDZEnvRec.CreateMutableBinding(name, false).
+ e. Set the running execution context's LexicalEnvironment to TDZ.
+ 3. Let exprRef be the result of evaluating expr.
+ [...]
+features: [let]
+---*/
+
+let x = 'outside';
+var probeBefore = function() { return x; };
+var probeExpr;
+
+for (let x in { i: probeExpr = function() { typeof x; }}) ;
+
+assert.sameValue(probeBefore(), 'outside');
+assert.throws(ReferenceError, probeExpr);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/scope-head-var-none.js b/js/src/tests/test262/language/statements/for-in/scope-head-var-none.js
new file mode 100644
index 0000000000..d0536483b3
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/scope-head-var-none.js
@@ -0,0 +1,47 @@
+// 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-for-in-and-for-of-statements-runtime-semantics-labelledevaluation
+description: >
+ No variable environment is created for the statement "head"
+info: |
+ IterationStatement : for ( ForDeclaration of AssignmentExpression ) Statement
+
+ 1. Let keyResult be the result of performing ?
+ ForIn/OfHeadEvaluation(BoundNames of ForDeclaration,
+ AssignmentExpression, iterate).
+ [...]
+
+ 13.7.5.12 Runtime Semantics: ForIn/OfHeadEvaluation
+
+ [...]
+ 2. If TDZnames is not an empty List, then
+ a. Assert: TDZnames has no duplicate entries.
+ b. Let TDZ be NewDeclarativeEnvironment(oldEnv).
+ c. Let TDZEnvRec be TDZ's EnvironmentRecord.
+ d. For each string name in TDZnames, do
+ i. Perform ! TDZEnvRec.CreateMutableBinding(name, false).
+ e. Set the running execution context's LexicalEnvironment to TDZ.
+ 3. Let exprRef be the result of evaluating expr.
+ [...]
+flags: [noStrict]
+---*/
+
+var probeBefore = function() { return x; };
+var x = 1;
+var probeDecl, probeExpr, probeBody;
+
+for (
+ let [_ = probeDecl = function() { return x; }]
+ in
+ { '': (eval('var x = 2;'), probeExpr = function() { return x; }) }
+ )
+ probeBody = function() { return x; };
+
+assert.sameValue(probeBefore(), 2, 'reference preceding statement');
+assert.sameValue(probeDecl(), 2, 'reference from ForDeclaration');
+assert.sameValue(probeExpr(), 2, 'reference from AssignmentExpression');
+assert.sameValue(probeBody(), 2, 'reference from statement body');
+assert.sameValue(x, 2, 'reference following statement');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/language/statements/for-in/shell.js b/js/src/tests/test262/language/statements/for-in/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/shell.js
diff --git a/js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-init-strict.js b/js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-init-strict.js
new file mode 100644
index 0000000000..2fa07fc233
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-init-strict.js
@@ -0,0 +1,21 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2018 Mike Pennisi. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-statement
+description: >
+ 'for(var arguments = 42 in ...) {...}' throws SyntaxError in
+ strict mode within a function declaration
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+function f() {
+ for (var arguments = 42 in null) {}
+}
diff --git a/js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-strict.js b/js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-strict.js
new file mode 100644
index 0000000000..efdfe80745
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/var-arguments-fn-strict-strict.js
@@ -0,0 +1,21 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2018 Mike Pennisi. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-statement
+description: >
+ 'for(var arguments in ...) {...}' throws SyntaxError in strict mode within a
+ function declaration
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+function f() {
+ for (var arguments in null) {}
+}
diff --git a/js/src/tests/test262/language/statements/for-in/var-arguments-strict-init-strict.js b/js/src/tests/test262/language/statements/for-in/var-arguments-strict-init-strict.js
new file mode 100644
index 0000000000..ffe0728b9a
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/var-arguments-strict-init-strict.js
@@ -0,0 +1,19 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-statement
+description: >
+ 'for(var arguments = 42 in ...) {...}' throws SyntaxError in
+ strict mode
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var arguments = 42 in null) {}
diff --git a/js/src/tests/test262/language/statements/for-in/var-arguments-strict-strict.js b/js/src/tests/test262/language/statements/for-in/var-arguments-strict-strict.js
new file mode 100644
index 0000000000..64ca63ea83
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/var-arguments-strict-strict.js
@@ -0,0 +1,17 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-statement
+description: "'for(var arguments in ...) {...}' throws SyntaxError in strict mode"
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var arguments in null) {}
diff --git a/js/src/tests/test262/language/statements/for-in/var-eval-strict-init-strict.js b/js/src/tests/test262/language/statements/for-in/var-eval-strict-init-strict.js
new file mode 100644
index 0000000000..b841da936b
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/var-eval-strict-init-strict.js
@@ -0,0 +1,17 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-statement
+description: "'for(var eval = 42 in ...) {...}' throws SyntaxError in strict mode"
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var eval = 42 in null) {}
diff --git a/js/src/tests/test262/language/statements/for-in/var-eval-strict-strict.js b/js/src/tests/test262/language/statements/for-in/var-eval-strict-strict.js
new file mode 100644
index 0000000000..ed6753dcfd
--- /dev/null
+++ b/js/src/tests/test262/language/statements/for-in/var-eval-strict-strict.js
@@ -0,0 +1,17 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-for-statement
+description: "'for(var eval in ...) {...}' throws SyntaxError in strict mode"
+flags: [onlyStrict]
+negative:
+ phase: parse
+ type: SyntaxError
+---*/
+
+$DONOTEVALUATE();
+
+for (var eval in null) {}